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);
}

 

posted @ 2018-10-26 10:55  柚子苹果果  阅读(202)  评论(0编辑  收藏  举报