ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

springboot整合shiro简单使用(查询数据库)

2022-06-25 10:34:16  阅读:205  来源: 互联网

标签:java springboot 查询数据库 user org import com shiro name


shiro主要实现认证和授权的问题

认证确认用户身份,授权对用户访问资源的权限做控制

建表语句

CREATE TABLE `user` (
   id INT(11) PRIMARY KEY AUTO_INCREMENT  COMMENT '主键',
  `name` VARCHAR(255)  COMMENT '用户名',
  `password` VARCHAR(255)  COMMENT '密码'
)
INSERT INTO `user`(`name`,`password`) VALUES('test','123456')
CREATE TABLE `role` (
   id INT(11) PRIMARY KEY AUTO_INCREMENT NOT NULL  COMMENT '主键',
   role_name VARCHAR(255) DEFAULT NULL COMMENT '角色名称',
  user_id VARCHAR(255) DEFAULT NULL COMMENT '用户id'
)

INSERT INTO `role`(role_name,user_id) VALUES('admin','1')

CREATE TABLE permission (
   id INT(11) PRIMARY  KEY AUTO_INCREMENT NOT NULL  COMMENT '主键',
   permission VARCHAR(255) DEFAULT NULL COMMENT '权限',
  role_id VARCHAR(255) DEFAULT NULL COMMENT '角色id'
)
INSERT INTO permission(permission,role_id) VALUES
('create','1'),
('query','1')

  

 

 

 

 

 

 代码部分

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.java</groupId>
    <artifactId>shiro-service</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--springboot整合mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>
        <!--mysql驱动5.6.17-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.4</version>
        </dependency>
        <!--页面模板依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--热部署依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

  

server.port=8001

logging.level.com.java=debug
logging.level.web=debug
spring.devtools.add-properties=false

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#spring.datasource.url=jdbc:mysql://127.0.0.1:3306/spring_shiro?useUnicode=true&characterEncoding=utf-8&useSSL=false
#spring.datasource.username=root
#spring.datasource.password=root

mybatis.mapper-locations=classpath:mapping/*.xml
mybatis.configuration.map-underscore-to-camel-case=true 

spring.aop.proxy-target-class=true

  

 

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.java.mapper.PermissionMapper">

    <insert id="addBatchPermission" parameterType="java.util.List">
        INSERT INTO permission(permission,role_id) VALUES
        <foreach collection="list" item="item" separator=",">
            (#{item.permission},#{item.roleId})
        </foreach>
    </insert>



</mapper>

  

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.java.mapper.UserMapper">

    <resultMap id="userMap" type="com.java.bean.User">

        <result property="name" column="name"/>
        <result property="password" column="password"/>
        <collection property="roles" ofType="com.java.bean.Role">
            <result property="roleName" column="role_name"/>
            <collection property="permissions" ofType="com.java.bean.Permission">
                <result property="permission" column="permission"/>
            </collection>
        </collection>
    </resultMap>

      <select id="getListByBean" resultMap="userMap">
            SELECT  a.`name`,a.`password`,b.`role_name`,c.`permission`
         FROM  `user` a INNER JOIN  `role` b ON a.id=b.user_id INNER JOIN permission c ON b.id=c.role_id
      </select>

</mapper>

  

package com.java;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author yourheart
 * @Description
 * @create 2022-05-03 20:30
 */
@SpringBootApplication
public class ShiroApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShiroApplication.class,args);
    }
}

  

package com.java.bean;

import lombok.Data;

/**
 * @author yourheart
 * @Description
 * @create 2022-06-15 1:54
 */
@Data
public class Permission {


    private Integer id;

    private String permission;

    private Integer roleId;
}


package com.java.bean;

import lombok.Data;

/**
 * @author yourheart
 * @Description
 * @create 2021-09-17 23:54
 */
@Data
public class ResponseBean {
    /**
     * 状态码
     */
    private String code;
    /**
     * 返回值
     */
    private String msg;
    /**
     * 拓展字段
     */
    private Object extraInfo;
}


package com.java.bean;

import lombok.Data;

import java.util.List;

/**
 * @author yourheart
 * @Description
 * @create 2022-06-15 1:55
 */
@Data
public class Role {


    private Integer id;

    private String roleName;

   private Integer userId;

    private List<Permission> permissions;
}


package com.java.bean;

import lombok.Data;

import java.util.List;

/**
 * @author yourheart
 * @Description
 * @create 2022-06-15 1:53
 */
@Data
public class User {


    private Integer id;

    private String name;

    private Integer password;

    private List<Role> roles;
}

  

package com.java.mapper;

import com.java.bean.Permission;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @author yourheart
 * @Description
 * @create 2022-06-25 8:37
 */
@Mapper
public interface PermissionMapper {


    @Select("SELECT  permission FROM  permission  WHERE role_id=#{roleId}")
    List<Permission> findPermission(Integer roleId);

    int addBatchPermission(List<Permission> permissions);

}


package com.java.mapper;

import com.java.bean.Role;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @author yourheart
 * @Description
 * @create 2022-06-25 8:37
 */
@Mapper
public interface RoleMapper {

    @Select("SELECT  * FROM `role` r  WHERE user_id =#{id}")
    List<Role> findRoleById(Integer id);


    @Insert("INSERT INTO `role`(role_name,user_id) VALUES(#{roleName},#{userId})")
    int addRole(Role role);
}


package com.java.mapper;

import com.java.bean.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;
import java.util.Map;

/**
 * @author yourheart
 * @Description
 * @create 2022-06-25 8:10
 */
@Mapper
public interface UserMapper {

    @Select("SELECT  *  FROM  `user` WHERE `name`=#{name}")
    User findByName(@Param("name") String name);

    @Select("SELECT  COUNT(*)  FROM  `user` WHERE `name`=#{name} AND `password`=#{password}")
    int selectUserExists(User user);

    @Insert("INSERT INTO `user`(`name`,`password`) VALUES(#{name},#{password})")
    int addUser(User user);

    @Select("SELECT  *  FROM  `user` WHERE id=#{id}")
    User findById(Integer id);

    @Select("SELECT  a.`name`,a.`password`,b.`role_name`,c.`permission`  \n" +
            "FROM  `user` a INNER JOIN  `role` b ON a.id=b.user_id INNER JOIN permission c ON b.id=c.role_id")
    List<Map<String,Object>> getList();


    List<User> getListByBean();


}

  

package com.java.service;

import com.java.bean.ResponseBean;
import com.java.bean.User;

public interface UserService {

    /**
     * 通过用户名查询用户的权限
     * @param name
     * @return
     */
    User getUserByName(String name);


    /**
     * 添加用户时默认给query权限
     * @param user
     * @return
     */
    ResponseBean addUser(User user);
}


package com.java.service.impl;

import com.java.bean.Permission;
import com.java.bean.ResponseBean;
import com.java.bean.Role;
import com.java.bean.User;
import com.java.mapper.PermissionMapper;
import com.java.mapper.RoleMapper;
import com.java.mapper.UserMapper;
import com.java.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author yourheart
 * @Description
 * @create 2022-06-24 20:34
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;


    /**
     * 通过用户名查询用户的权限
     *
     * @param name
     * @return
     */
    @Override
    public User getUserByName(String name) {
        User user = userMapper.findByName(name);
        List<Role> roleByName = roleMapper.findRoleById(user.getId());

        roleByName.forEach(role -> {
            List<Permission> permissionList = permissionMapper.findPermission(role.getId());
            role.setPermissions(permissionList);
        });
        user.setRoles(roleByName);
        return user;
    }

    /**
     * 添加用户时默认给query权限
     *
     * @param user
     * @return
     */
    @Override
    public ResponseBean addUser(User user) {


        ResponseBean responseBean=new ResponseBean();

        int selectUserExists = userMapper.selectUserExists(user);
        if (selectUserExists==1){
            responseBean.setCode("-100");
            responseBean.setMsg("用户已经存在");
            return responseBean;
        }
        //入参需要用户名和密码
        int addUser = userMapper.addUser(user);

        //通过用户名查询返回用户的id,向角色表中存放用户的角色和用户的id
        User byName = userMapper.findByName(user.getName());
        Role role=new Role();
        role.setRoleName("common");
        role.setUserId(byName.getId());
        int addRole = roleMapper.addRole(role);

        //查询角色的id,向权限表存放角色的权限和角色id
        List<Role> roleById = roleMapper.findRoleById(byName.getId());

        roleById.forEach(r->{
            Integer rId = r.getId();
            List<Permission> permissions=new ArrayList<>();
            Permission permission=new Permission();
            permission.setPermission("query");
            permission.setRoleId(rId);
            permissions.add(permission);
            permissionMapper.addBatchPermission(permissions);
        });

        responseBean.setCode("100");
        responseBean.setMsg("用户添加成功");
        return responseBean;

    }
}

  shiro权限控制部分

package com.java.config;

import com.java.bean.Permission;
import com.java.bean.Role;
import com.java.bean.User;
import com.java.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;


/**
 * @author yourheart
 * @Description 实现AuthorizingRealm接口用户用户认证
 * @create 2022-06-15 1:56
 */
@Slf4j
public class MyShiroRealm extends AuthorizingRealm {


    @Autowired
    private UserService userService;

    /**
     * 角色权限和对应权限添加
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        String name = (String) principalCollection.getPrimaryPrincipal();
        log.info("【角色权限和对应权限添加】name:{}", name);
        //查询用户名称
        User user = userService.getUserByName(name);
        log.info("【角色权限和对应权限添加】user:{}", user);
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (Role role : user.getRoles()) {
            //添加角色
            simpleAuthorizationInfo.addRole(role.getRoleName());
            for (Permission permission : role.getPermissions()) {
                //添加权限
                simpleAuthorizationInfo.addStringPermission(permission.getPermission());
            }
        }
        return simpleAuthorizationInfo;
    }

    /**
     * 用户认证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //加这一步的目的是在Post请求的时候会先进认证,然后在到请求
        log.info("【用户认证】authenticationToken.getPrincipal():{}", authenticationToken.getPrincipal());
        if (authenticationToken.getPrincipal() == null) {
            return null;
        }
        //获取用户信息
        String name = authenticationToken.getPrincipal().toString();
        log.info("【用户认证】name:{}", name);
        User user = userService.getUserByName(name);
        log.info("【用户认证】user:{}", user);
        if (user == null) {
            //这里返回后会报出对应异常
            return null;
        } else {
            //这里验证authenticationToken和simpleAuthenticationInfo的信息
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword().toString(), getName());
            return simpleAuthenticationInfo;
        }
    }
}




package com.java.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author yourheart
 * @Description
 * @create 2022-06-15 1:58
 */
@Configuration
@Slf4j
public class ShiroConfiguration {

    /**
     * 将自己的验证方式加入容器
     *
     * @return
     */
    @Bean
    public MyShiroRealm myShiroRealm() {
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }

    /**
     * 权限管理,配置主要是Realm的管理认证
     *
     * @return
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    /**
     * Filter工厂,设置对应的过滤条件和跳转条件
     *
     * @param securityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> map = new HashMap<String, String>();
        //登出
        map.put("/logout", "logout");
        /**
         * Shiro内置过滤器,能够实现拦截器相关的拦截器
         *    经常使用的过滤器:
         *      anon:无需认证(登陆)能够访问
         *      authc:必须认证才能够访问
         *      user:若是使用rememberMe的功能能够直接访问
         *      perms:该资源必须获得资源权限才能够访问
         *      role:该资源必须获得角色权限才能够访问
         **/
        //对所有用户认证
        map.put("/**", "authc");

        map.put("/re", "anon");


        //登录
        shiroFilterFactoryBean.setLoginUrl("/login");
        //首页
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //错误页面,认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    /**
     * 加入注解的使用,不加入这个注解不生效
     *
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

  

package com.java.controller.front;

import com.java.bean.Role;
import com.java.bean.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


/**
 * @author yourheart
 * @Description
 * @create 2022-06-15 2:11
 */
@RestController
@Slf4j
public class TestController {

    @PostMapping("/login")
    public String login(@RequestBody User user) {
        if (StringUtils.isEmpty(user.getName()) || StringUtils.isEmpty(user.getPassword())) {
            return "请输入用户名和密码!";
        }
        //用户认证信息
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
                user.getName(),
                String.valueOf(user.getPassword())
        );
        try {
            //进行验证,这里可以捕获异常,然后返回对应信息
            subject.login(usernamePasswordToken);
        } catch (UnknownAccountException e) {
            log.error("用户名不存在!", e);
            return "用户名不存在!";
        } catch (AuthenticationException e) {
            log.error("账号或密码错误!", e);
            return "账号或密码错误!";
        } catch (AuthorizationException e) {
            log.error("没有权限!", e);
            return "没有权限";
        }
        return "login success";
    }


    /**
     * 用户登出
     * @return
     */
    @RequestMapping("/loginOut")
    public String loginOut(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return  "退出成功";
    }

    @RequiresPermissions("query")
    @RequestMapping(value = "/index")
    @ResponseBody
    public String index(){
        return "进入主页";
    }



    @RequiresPermissions("create")
    @GetMapping("/add")
    public String add() {
        return "add success!";
    }


    @RequestMapping(value = "/re")
    @ResponseBody
    public String re(){
        return "进入注册页面";
    }


    @RequestMapping(value = "/log")
    @ResponseBody
    public String log(){
        return "进入日志页面";
    }

}

  

 

 附上测试地址

http://127.0.0.1:8001/login

{
    "name":"qiuxie",
    "password":"123"
}

http://127.0.0.1:8001/index

http://127.0.0.1:8001/add

用户登出
http://127.0.0.1:8001/loginOut

  

 

标签:java,springboot,查询数据库,user,org,import,com,shiro,name
来源: https://www.cnblogs.com/q202105271618/p/16384041.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有