• Spring Security(2)----用户登录认证数据库实现


    Spring Security认证架构

    在这之前,先来了解一下Spring Security的认证架构,有篇不错的分析文章,具体可以看这里:https://my.oschina.net/u/865921/blog/159849。

    总的来说,Spring Security通过filter来控制web应用的安全,但filter自己不干事,分别委托给了认证管理器和决策管理器,认证管理器和决策管理器再分别委托给Provider和Voter,就这样一级级委托下来,委托的最底层就是需要我们根据实际情况实现的逻辑。可以看下图:

    spring security认证架构

    根据我们这次的目标,想用数据库来储存用户的认证数据,那么我们就需要一个操作数据库的Provider,这个Spring Security内部已经有了实现,就是DaoAuthenticationProvider,我们只需要实现它委托的UserDetailService即可,这个其实在前面一篇文章中已经有了实现,只不过没用数据库而已。对于Voter,选择内置的RoleVoter就够用了,它会根据我们的设置来决定是否允许某一个用户访问特定的Web资源。

    建表

    想要把数据存储在数据库,第一步当然是建表了,这里简单起见,只搞了用户和权限的基本信息:

    CREATE TABLE `USER` (
      `USER_ID` bigint(20) NOT NULL AUTO_INCREMENT,
      `LOGIN_NAME` varchar(32) NOT NULL,
      `PASSWORD` varchar(32) NOT NULL,
      `GMT_CREATE` datetime NOT NULL,
      PRIMARY KEY (`USER_ID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    CREATE TABLE `USER_AUTH` (
      `USER_AUTH_ID` bigint(20) NOT NULL AUTO_INCREMENT,
      `USER_ID` bigint(20) NOT NULL,
      `AUTH_CODE` varchar(32) NOT NULL,
      `GMT_CREATE` datetime NOT NULL,
      PRIMARY KEY (`USER_AUTH_ID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    insert into user(login_name,password,gmt_create) values ('admin','123456',now());
    insert into user(login_name,password,gmt_create) values ('selfly','123456',now());
    insert into user_auth(user_id,auth_code,gmt_create) values (1,'admin',NOW()); -- admin
    insert into user_auth(user_id,auth_code,gmt_create) values (2,'user',NOW()) -- user

    Spring Security中,貌似用户都是对应到角色(role)的,但是在实际的应用中一般都是对应到具体的权限码,这点无须纠结,把它理解为命名的方式不同而已即可,关于权限码的授权后面再作细讲。

    修改CustomUserDetailsService

    其实没多大改动,主要就是把写死的用户数据换成从数据库获取而已,具体代码:

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User user = jdbcDao.querySingleResult(Criteria.select(User.class).where("loginName", new Object[]{s}));
        if (user == null) {
            throw new UsernameNotFoundException("user not found");
        }
        List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
    
        List<UserAuth> userAuthList = jdbcDao.queryList(Criteria.select(UserAuth.class).where("userId", new Object[]{user.getUserId()}));
        if (userAuthList != null) {
    
            for (UserAuth userAuth : userAuthList) {
                authorities.add(new SimpleGrantedAuthority("ROLE_" + userAuth.getAuthCode()));
                LOG.info("loginName:{},authCode:{}", user.getLoginName(), userAuth.getAuthCode());
            }
    
        }
        return new org.springframework.security.core.userdetails.User(user.getLoginName(), user.getPassword(),
                authorities);
    }

    测试

    修改后,再访问 http://localhost:8080/login 页面,分别用adminselfly登录,权限校验结果还是跟前面一样,但后台的用户信息已经换成从数据库获取了。

    附件列表

  • 相关阅读:
    Linux常用命令-centos
    USACO 2006 Open, Problem. The Country Fair 动态规划
    USACO 2007 March Contest, Silver Problem 1. Cow Traffic
    USACO 2007 December Contest, Silver Problem 2. Building Roads Kruskal最小生成树算法
    USACO 2015 February Contest, Silver Problem 3. Superbull Prim最小生成树算法
    LG-P2804 神秘数字/LG-P1196 火柴排队 归并排序, 逆序对
    数据结构 并查集
    浴谷国庆集训 对拍
    1999 NOIP 回文数
    2010 NOIP 普及组 第3题 导弹拦截
  • 原文地址:https://www.cnblogs.com/grimm/p/13441692.html
Copyright © 2020-2023  润新知