• SpringBoot+Shiro+DB (二)


    之前我们完成了Spring+Shiro的最基本配置搭建,现在我们再增加上DB,毕竟没有哪个系统会将用户、角色、权限等信息硬编码到代码里。DB选用myslq。

    数据库准备

    脚本如下。依然是两个用户:admin和guest。admin拥有角色admin以及权限permission1、permission2;guest拥有角色guest以及权限permission1、permission2。

    create table test.shiro_user (
           id int auto_increment primary key,
           username varchar(50),
           password varchar(50)
    );
    
    create table test.shiro_role (
           id int auto_increment primary key,
           role varchar(50)
    );
    
    create table test.shiro_permission (
           id int auto_increment primary key,
           permission varchar(50)
    );
    
    create table test.shiro_user_r_role (
           userid int,
           roleid int
    );
    
    create table test.shiro_user_r_permission (
           userid int,
           permissionid int
    );
    
    insert into test.shiro_user(id, username, password) values (1, 'admin', 'admin');
    insert into test.shiro_user(id, username, password) values (2, 'guest', 'guest');
    
    insert into test.shiro_role(id, role) values (1, 'admin');
    insert into test.shiro_role(id, role) values (2, 'guest');
    
    insert into test.shiro_permission(id, permission) values (1, 'permission1');
    insert into test.shiro_permission(id, permission) values (2, 'permission2');
    insert into test.shiro_permission(id, permission) values (3, 'permission3');
    insert into test.shiro_permission(id, permission) values (4, 'permission4');
    
    insert into test.shiro_user_r_role(userid, roleid) values (1, 1);
    insert into test.shiro_user_r_role(userid, roleid) values (2, 2);
    
    insert into test.shiro_user_r_permission(userid, permissionid) values (1, 1);
    insert into test.shiro_user_r_permission(userid, permissionid) values (1, 2);
    insert into test.shiro_user_r_permission(userid, permissionid) values (2, 3);
    insert into test.shiro_user_r_permission(userid, permissionid) values (2, 4);

    pom依赖

    再之前的基础上又增加了spring-jdbc和mysql的数据库驱动,因为要连接数据库嘛

    <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
    </dependency>

    application.properties

    增加连接数据库的相关配置

    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://192.168.2.12:3306/test?characterEncoding=utf8
    spring.datasource.username=root
    spring.datasource.password=onceas

    Dao和Service

    dao和service就没什么好说的了,Controller不用动

    @Repository
    public class LoginDao {
    
        private final JdbcTemplate jdbcTemplate;
    
        @Autowired
        public LoginDao(JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
        }
    
        public List<User> getUserByUsername(String username) {
            String sql = "select id, username, password from shiro_user where username=?";
            return jdbcTemplate.query(sql, new Object[]{username}, new BeanPropertyRowMapper<User>(User.class));
        }
    
        public List<String> getRoleByUsername(String username) {
            String sql = "select role from shiro_role A " +
                    "join shiro_user_r_role B on A.id = B.roleid " +
                    "join shiro_user C on B.userid = C.id " +
                    "where C.username=?";
            return jdbcTemplate.queryForList(sql, new Object[]{username}, String.class);
        }
    
        public List<String> getPermissionByUsername(String username) {
            String sql = "select permission from shiro_permission A " +
                    "join shiro_user_r_permission B on A.id = B.permissionid " +
                    "join shiro_user C on B.userid = C.id " +
                    "where C.username=?";
            return jdbcTemplate.queryForList(sql, new Object[]{username}, String.class);
        }
    }
    @Service
    public class LoginService {
    
        private final LoginDao loginDao;
    
        @Autowired
        public LoginService(LoginDao loginDao) {
            this.loginDao = loginDao;
        }
    
        public List<User> getUserByUsername(String username) {
            return loginDao.getUserByUsername(username);
        }
    
        public List<String> getRoleByUsername(String username) {
            return loginDao.getRoleByUsername(username);
        }
    
        public List<String> getPermissionByUsername(String username) {
            return loginDao.getPermissionByUsername(username);
        }
    }

    修改Realm

    调整Realm,用户验证和授权改为从数据库中获取数据

    public class PropertiesRealm extends AuthorizingRealm {
    
        private final LoginService loginService;
    
        @Autowired
        public PropertiesRealm(LoginService loginService) {
            this.loginService = loginService;
        }
    
        // 用户认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            if (authenticationToken instanceof UsernamePasswordToken) {
                UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
                String username = token.getUsername();
                String password = new String(token.getPassword());
                List<User> users = loginService.getUserByUsername(username);
                if (users == null || users.size() != 1) {
                    throw new AuthenticationException("用户名或密码错误");
                }
                User user = users.get(0);
                if (!user.getPassword().equals(password)) {
                    throw new AuthenticationException("用户名或密码错误");
                }
                return new SimpleAuthenticationInfo(username, password, getName());
            } else if (authenticationToken instanceof RememberMeAuthenticationToken) {
                RememberMeAuthenticationToken token = (RememberMeAuthenticationToken) authenticationToken;
                // TODO: 2018/10/24
                return null;
            } else if (authenticationToken instanceof HostAuthenticationToken) {
                HostAuthenticationToken token = (HostAuthenticationToken) authenticationToken;
                // TODO: 2018/10/24
                return null;
            } else {
                throw new AuthenticationException("未知的AuthenticationToken类型");
            }
        }
    
        // 用户授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            String username = (String) principalCollection.getPrimaryPrincipal();
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            simpleAuthorizationInfo.addRoles(loginService.getRoleByUsername(username));
            simpleAuthorizationInfo.addStringPermissions(loginService.getPermissionByUsername(username));
            return simpleAuthorizationInfo;
        }
    }

    调整SpringApplication

    因为修改后的realm需要LoginService的支持,所以相应的调整SpringApplication,其他地方不变。

    @Bean
    public PropertiesRealm propertiesRealm(LoginService loginService) {
        return new PropertiesRealm(loginService);
    }
  • 相关阅读:
    iOS 多线程/GCD
    iOS推送通知的实现步骤
    Swift中文教程-学习
    设计模式——观察者模式
    SSM学习
    Servlet 学习
    java基础
    DOM中节点
    会议管理系统设计
    springboot与thymeleaf 整合
  • 原文地址:https://www.cnblogs.com/LOVE0612/p/9855110.html
Copyright © 2020-2023  润新知