Spring Security(2)----用户登录认证数据库实现
2023-09-11 14:21:54 时间
Spring Security认证架构
在这之前,先来了解一下Spring Security
的认证架构,有篇不错的分析文章,具体可以看这里:https://my.oschina.net/u/865921/blog/159849。
总的来说,Spring Security
通过filter来控制web应用的安全,但filter自己不干事,分别委托给了认证管理器和决策管理器,认证管理器和决策管理器再分别委托给Provider和Voter,就这样一级级委托下来,委托的最底层就是需要我们根据实际情况实现的逻辑。可以看下图:
根据我们这次的目标,想用数据库来储存用户的认证数据,那么我们就需要一个操作数据库的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 页面,分别用admin
和selfly
登录,权限校验结果还是跟前面一样,但后台的用户信息已经换成从数据库获取了。
附件列表
相关文章
- 面试(4)-spring-Spring面试题和答案
- Spring : 征服数据库(一)
- 记spring boot线上项目内存优化
- 《深入实践Spring Boot》一3.6 小结
- Is Spring Integration 5.5.10 must be based on Java 9 to use or depend on spring integration? #3761
- spring @Value 设置默认值
- Spring boot+Spring security+JWT实现前后端分离登录认证及权限控制
- 比较分析 Spring AOP 和 AspectJ 之间的差别
- 一行配置搞定 Spring Boot项目的 log4j2 核弹漏洞!
- Spring Boot 2.x基础教程:使用国产数据库连接池Druid
- Spring Boot 2 实战:使用 Flyway 管理你数据库的版本变更
- mysql+spring+mybatis实现数据库读写分离[代码配置] .
- 从零开始学 Java - Spring 一主多从、多主多从 数据库配置
- spring框架漏洞整理(Spring WebFlow远程代码执行)
- spring事务详解(一)初探事务
- 【转】Spring@Autowired注解与自动装配
- Spring Cloud Alibaba 微服务组件 Skywalking 分布式任务链(十一)
- Spring 数据库连接整理
- mvn打包spring工程成jar时报Unable to locate Spring NamespaceHandler for XML schema namespace错误解决办法
- Scalable, Distributed Systems Using Akka, Spring Boot, DDD, and Java--转