Spring Security系列二 用户登录认证数据库实现

本文详细介绍了如何在SpringSecurity中使用数据库进行用户登录认证,包括认证架构解析、表结构设计及CustomUserDetailsService的修改,最后通过测试验证了数据库认证的正确性。

前言

在前面Spring Security系列一 权限控制基本功能实现中,我们已经实现了基本功能,这一章我们来把用户的登录认证修改成贴近实际的数据库获取。

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登录,权限校验结果还是跟前面一样,但后台的用户信息已经换成从数据库获取了。

已经博主授权,源码转载自 https://pan.quark.cn/s/053f1da40351 在计算机科学领域,MIPS(Microprocessor without Interlocked Pipeline Stages)被视作一种精简指令集计算机(RISC)的架构,其应用广泛存在于教学实践和嵌入式系统设计中。 本篇内容将深入阐释MIPS汇编语言中涉及数组处理的核心概念与实用操作技巧。 数组作为一种常见的数据结构,在编程中能够以有序化的形式储存及访问具有相同类型的数据元素集合。 在MIPS汇编语言环境下,数组通常借助内存地址与索引进行操作。 以下列举了运用MIPS汇编处理数组的关键要素:1. **数据存储**: - MIPS汇编架构采用32位地址系统,从而能够访问高达4GB的内存容量。 - 数组元素一般以连续方式存放在内存之中,且每个元素占据固定大小的字节空间。 例如,针对32位的整型数组,其每个元素将占用4字节的存储空间。 - 数组首元素的地址被称为基地址,而数组任一元素的地址可通过基地址加上元素索引乘以元素尺寸的方式计算得出。 2. **寄存器运用**: - MIPS汇编系统配备了32个通用寄存器,包括$zero, $t0, $s0等。 其中,$zero寄存器通常用于表示恒定的零值,$t0-$t9寄存器用于暂存临时数据,而$s0-$s7寄存器则用于保存子程序的静态变量或参数。 - 在数组处理过程中,基地址常被保存在$s0或$s1寄存器内,索引则存储在$t0或$t1寄存器中,运算结果通常保存在$v0或$v1寄存器。 3. **数组操作指令**: - **Load/Store指令**:这些指令用于在内存与寄存器之间进行数据传输,例如`lw`指令用于加载32位数据至寄存器,`sw`指令...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值