Spring Security 之自定义UserDetails

  Spring Security(以下简称SS)中默认存在一个org.springframework.security.core.userdetails.UserDetails类,该类是SS内置的,提供了几个简单的属性,如userName,password,enabled等等,但这些属性不能完全适应我们现在的系统,所有一般需要自定义自己的UserDetails。自定义UserDetails需要继承SS内置的UserDetails,之所以继承内置的UserDetails,是因为在SS中可以通过SecurityContextHolder取得用户凭证和用户所有的信息,用户信息都存放在系统内置的UserDetails中,如果继承之后,即可进行向下转型,变成我们自己的定义的UserDetails了。

  参考代码如下,以下自定义的UserDetails中加入了用户拥有的设备,用户角色,用户权限等等,假设我需要在用户登录之后就加载这些用户关联的信息,那么加入UserDetails之后,在任何位置就能通过SecurityContextHolder取到了。

 1 /**
 2  *
 3  * @author bigbang 通过扩展UserDetails接口扩展自己的用户信息
 4  */
 5 public class MyUserDetails implements UserDetails {
 6
 7     private static final long serialVersionUID = 1L;
 8     private User user;
 9     private List<Privilege> privileges;
10     private Collection<GrantedAuthority> roles;
11     private List<Device> devices;
12
13     public MyUserDetails() {
14     }
15
16     public MyUserDetails(User user, List<Privilege> privileges, Collection<GrantedAuthority> roles, List<Device> devices) {
17         super();
18         this.user = user;
19         this.privileges = privileges;
20         this.roles = roles;
21         this.devices = devices;
22     }
23
24     public List<Privilege> getPrivileges() {
25         return privileges;
26     }
27
28     public List<Device> getDevices() {
29         return devices;
30     }
31
32     @Override
33     public Collection<? extends GrantedAuthority> getAuthorities() {
34         return this.roles;
35     }
36
37     @Override
38     public String getPassword() {
39         return user.getPassWord();
40     }
41
42     @Override
43     public String getUsername() {
44         return user.getUserName();
45     }
46
47     @Override
48     public boolean isAccountNonExpired() {
49         return true;
50     }
51
52     @Override
53     public boolean isAccountNonLocked() {
54         return true;
55     }
56
57     @Override
58     public boolean isCredentialsNonExpired() {
59         return true;
60     }
61
62     @Override
63     public boolean isEnabled() {
64         return true;
65     }
66
67     public User getUser() {
68         return user;
69     }
70
71     public void setUser(User user) {
72         this.user = user;
73     }
74
75     public Collection<GrantedAuthority> getRoles() {
76         return roles;
77     }
78
79     public void setRoles(Collection<GrantedAuthority> roles) {
80         this.roles = roles;
81     }
82
83     public void setPrivileges(List<Privilege> privileges) {
84         this.privileges = privileges;
85     }
86
87     public void setDevices(List<Device> devices) {
88         this.devices = devices;
89     }
90
91 }

  

  在定义之后,接着就是怎么使用了。因为使用了自己的凭证信息,所以必须在ss的配置文件中加入自定义的认证管理器(AuthenticationManager)与认证数据容器(AuthenticationProvider).

  第一步是在http标签添加认证管理器:

1 <http auto-config="true" use-expressions="true" authentication-manager-ref="myAuthenticationManager">
2 </http>

  第二步在认证管理器中添加认证容器:

  

1     <authentication-manager id="myAuthenticationManager">
2         <authentication-provider user-service-ref="accountSecurityService">
3             <password-encoder hash="bcrypt" base64="true"/>
4         </authentication-provider>
5     </authentication-manager>

  它其中指定了一个用户信息服务,那么对应关系即可以理解为: 用户信息服务——>认证数据提供者——>认证管理器,通过一层层包装用户数据。

  自定义用户信息服务才是我们真正使用自定义UserDetails的核心,它实现了UserDetailsService接口,它所需要实现的方法只有一个 loadUserByUserName(String userName),返回UserDetails对象。就是根据用户名查询出一个UserDetails。此时我们可以返回一个自定义的UserDetails。  

  

 1 public class AccountSecurityService implements UserDetailsService {
 2
 3     @Autowired
 4     private IUserService userService;
 5
 6     @Override
 7     public UserDetails loadUserByUsername(String userName)
 8             throws UsernameNotFoundException {
 9         MyUserDetails details = null;
10         com.bigbang.entity.User user = userService.getUserDetail(userName); //查询一次用户所有关联信息
11         if (user == null)
12             return null;
13         details = new MyUserDetails(user,null,null,null);
14         return details;
15     }
16
17 }

  此处仅仅是查询出了用户的基本信息,与用户相关联的角色与设备并没有设置进去,这样做的好处是防止用户如果登录多次就会多次查询,如果登录失败同样也会查询,造成不必要的查询。那么这部分信息,我们可以放到登录成功之后查询,这部分属于认证阶段,暂时不说。

  

时间: 2024-10-25 12:24:41

Spring Security 之自定义UserDetails的相关文章

在spring security手动 自定义 用户认证 SecurityContextHolder

1.Spring Security 目前支持认证一体化如下认证技术: HTTP BASIC authentication headers (一个基于IEFT  RFC 的标准) HTTP Digest authentication headers (一个基于IEFT  RFC 的标准) HTTP X.509 client certificate exchange  (一个基于IEFT RFC 的标准) LDAP (一个非常常见的跨平台认证需要做法,特别是在大环境) Form-based auth

Spring Security 4 自定义登录表单 注解和XML例子(带源码)

上一篇文章: Spring Security 4 Hello World 基于注解 和 XML 例子 下一篇:Spring Security 4 退出 示例 原文地址:http://websystique.com/spring-security/spring-security-4-custom-login-form-annotation-example/ [已翻译文章,点击分类里面的spring security 4查看.] [ 翻译by 明明如月 QQ 605283073] 本文演示Sprin

spring security使用自定义登录界面后,不能返回到之前的请求界面的问题

昨天因为集成spring security oauth2,所以对之前spring security的配置进行了一些修改,然后就导致登录后不能正确跳转回被拦截的页面,而是返回到localhost根目录. 开始以为是被oauth2拦截了导致出了问题,但是security的拦截器是优先起作用的,所以这不可能. 最后实在没法只有打断点调试找毛病(下图为spring security登录后重定向至拦截前访问的url的实现原理流程) 图片是在这里看到的https://blog.csdn.net/zy_coo

Spring security 3 非常全的文档 API 中文版

Spring Security 安全权限管理手册 序言 I. 基础篇 6.1. MD5加密 6.2. 盐值加密 6.3. 用户信息缓存 6.4. 获取当前用户信息 5.1. 数据库表结构 5.2. 初始化数据 5.3. 实现从数据库中读取资源信息 5.3.1. 需要何种数据格式 5.3.2. 替换原有功能的切入点 4.1. 实现自定义登陆页面 4.2. 修改配置文件 4.3. 登陆页面中的参数配置 4.4. 测试一下 3.1. 自定义表结构 3.2. 初始化数据 3.3. 获得自定义用户权限信息

Spring Security 4 Hello World 基于注解 和 XML 例子(带源码)

下一篇: Spring Security 4 自定义登录表单 注解和XML例子 原文:http://websystique.com/spring-security/spring-security-4-hello-world-annotation-xml-example/ [已翻译文章,点击分类里面的spring security 4进行查看] [翻译by 明明如月 QQ 605283073] 本教程演示Spring MVC web项目中Spring Security 4的用法.通过url对访问进

Spring Security在标准登录表单中添加一个额外的字段

概述 在本文中,我们将通过向标准登录表单添加额外字段来实现Spring Security的自定义身份验证方案. 我们将重点关注两种不同的方法,以展示框架的多功能性以及我们可以使用它的灵活方式. 我们的第一种方法是一个简单的解决方案,专注于重用现有的核心Spring Security实现. 我们的第二种方法是更加定制的解决方案,可能更适合高级用例. 2. Maven设置 我们将使用Spring Boot启动程序来引导我们的项目并引入所有必需的依赖项. 我们将使用的设置需要父声明,Web启动器和安全

Spring Security 4 退出 示例(带源码)

上一篇:Spring Security 4 自定义登录表单 注解和XML例子 下一篇:Spring Security 4 安全视图片段 使用标签(Spring Security 标签) 原文地址:http://websystique.com/spring-security/spring-security-4-logout-example/ [已翻译文章,点击分类里面的spring security 4 ] [ 翻译by 明明如月 QQ 605283073] 本文展示Spring Security

255.Spring Boot+Spring Security:使用md5加密

说明 (1)JDK版本:1.8 (2)Spring Boot 2.0.6 (3)Spring Security 5.0.9 (4)Spring Data JPA 2.0.11.RELEASE (5)hibernate5.2.17.Final (6)MySQLDriver 5.1.47 (7)MySQL 8.0.12 需求缘起 很多时候,我们自己已经有现成的一套系统在运行了,这时候要接入spring security的话,那么难免会碰到一个问题:就是自己设计的密码加密方式和spring secur

256.Spring Boot+Spring Security: MD5是加密算法吗?

说明 (1)JDK版本:1.8 (2)Spring Boot 2.0.6 (3)Spring Security 5.0.9 (4)Spring Data JPA 2.0.11.RELEASE (5)hibernate5.2.17.Final (6)MySQLDriver 5.1.47 (7)MySQL 8.0.12 前言 有网友在公众号留言:准确的说md5是摘要算法不是加密算法 针对这个问题,当时也没有仔细的思考,空下来的时候,对于这个问题整理了下思路. 一.加密算法 1.1 加密和解密 1.1