Spring Security:授权GrantedAuthority介绍
在之前的博客中,已经介绍了Spring Security的用户UserDetails、用户服务UserDetailsService和密码编码器PasswordEncoder,它们都是用于验证用户的身份,而GrantedAuthority则表示用户验证通过后被授予的权限(可能授予多种权限),本篇博客介绍GrantedAuthority接口及其实现类。Spring Security:用户UserDet
在之前的博客中,已经介绍了Spring Security
的用户UserDetails
、用户服务UserDetailsService
和密码编码器PasswordEncoder
,它们都是用于验证用户的身份,而GrantedAuthority
则表示用户验证通过后被授予的权限(可能授予多种权限),本篇博客介绍GrantedAuthority
接口及其实现类。
- Spring Security:用户UserDetails源码与Debug分析
- Spring Security:用户服务UserDetailsService源码分析
- Spring Security:密码编码器PasswordEncoder介绍与Debug分析
应用的依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kaven</groupId>
<artifactId>security</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
启动类:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
GrantedAuthority
GrantedAuthority
接口源码:
package org.springframework.security.core;
import java.io.Serializable;
import org.springframework.security.access.AccessDecisionManager;
/**
* 表示授予Authentication对象(需要进行验证或通过验证的用户封装)的权限
*/
public interface GrantedAuthority extends Serializable {
/**
* 获取权限
*/
String getAuthority();
}
GrantedAuthority
接口及其实现类,如下图所示:
SimpleGrantedAuthority
GrantedAuthority
的基本具体实现,存储授予Authentication
对象的权限的String
表示形式。
SimpleGrantedAuthority
类源码:
public final class SimpleGrantedAuthority implements GrantedAuthority {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
// 授予Authentication对象的权限
private final String role;
public SimpleGrantedAuthority(String role) {
Assert.hasText(role, "A granted authority textual representation is required");
this.role = role;
}
@Override
public String getAuthority() {
return role;
}
// 只会比较role属性是否equals
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof SimpleGrantedAuthority) {
return role.equals(((SimpleGrantedAuthority) obj).role);
}
return false;
}
@Override
public int hashCode() {
return this.role.hashCode();
}
@Override
public String toString() {
return this.role;
}
}
增加配置文件:
spring:
security:
user:
name: kaven
password: itkaven
roles:
- USER
- ADMIN
Debug
启动应用,Spring Security
在应用启动时会创建配置文件中定义的用户,首先会创建用户服务(InMemoryUserDetailsManager
)bean
。
通过用户服务创建用户,并且授予权限(通过创建SimpleGrantedAuthority
实例)。
可见,SimpleGrantedAuthority
是默认的授权实现(特殊场景除外),它只存储权限,是一种简易的授权实现。
JaasGrantedAuthority
JaasGrantedAuthority
类源码:
/**
* 除了分配的角色,还持有授权人(AuthorityGranter)的主体(Principal),用作授予此权限的理由
*/
public final class JaasGrantedAuthority implements GrantedAuthority {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private final String role;
// 授权人的主体
private final Principal principal;
public JaasGrantedAuthority(String role, Principal principal) {
Assert.notNull(role, "role cannot be null");
Assert.notNull(principal, "principal cannot be null");
this.role = role;
this.principal = principal;
}
public Principal getPrincipal() {
return principal;
}
@Override
public String getAuthority() {
return role;
}
@Override
public int hashCode() {
int result = this.principal.hashCode();
result = 31 * result + this.role.hashCode();
return result;
}
// 判断role属性和principal属性是否都equals
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof JaasGrantedAuthority) {
JaasGrantedAuthority jga = (JaasGrantedAuthority) obj;
return this.role.equals(jga.role) && this.principal.equals(jga.principal);
}
return false;
}
@Override
public String toString() {
return "Jaas Authority [" + role + "," + principal + "]";
}
}
AuthorityGranter
接口源码:
/**
* AuthorityGranter接口用于将给定的主体映射到角色名称集合
*/
public interface AuthorityGranter {
/**
* 根据主体映射到角色名称集合
*/
Set<String> grant(Principal principal);
}
JaasGrantedAuthority
是一种用于Java
验证和授权服务(Java Authentication and Authorization Service
,简称JAAS
)场景下的授权实现,感兴趣可自行了解JAAS
。
SwitchUserGrantedAuthority
SwitchUserGrantedAuthority
类源码:
/**
* SwitchUserFilter使用的自定义GrantedAuthority
* 存储原始用户的Authentication对象,以便从退出用户切换时使用。
*/
public final class SwitchUserGrantedAuthority implements GrantedAuthority {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private final String role;
// 存储原始用户的Authentication对象
private final Authentication source;
public SwitchUserGrantedAuthority(String role, Authentication source) {
Assert.notNull(role, "role cannot be null");
Assert.notNull(source, "source cannot be null");
this.role = role;
this.source = source;
}
/**
* 返回与成功的用户切换关联的原始用户
*/
public Authentication getSource() {
return source;
}
@Override
public String getAuthority() {
return role;
}
@Override
public int hashCode() {
int result = this.role.hashCode();
result = 31 * result + this.source.hashCode();
return result;
}
// 判断role属性和source属性是否都equals
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof SwitchUserGrantedAuthority) {
SwitchUserGrantedAuthority swa = (SwitchUserGrantedAuthority) obj;
return this.role.equals(swa.role) && this.source.equals(swa.source);
}
return false;
}
@Override
public String toString() {
return "Switch User Authority [" + role + "," + source + "]";
}
}
该授权实现类似于Linux
系统下用户之间的切换授权(使用su
命令的权限),如下所示在Linux
系统中添加kaven
用户,然后从root
用户切换到kaven
用户(root
用户有这个权限)。
root@48556522ad65:~# adduser kaven
Adding user `kaven' ...
Adding new group `kaven' (1000) ...
Adding new user `kaven' (1000) with group `kaven' ...
Creating home directory `/home/kaven' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for kaven
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] Y
root@48556522ad65:~# su kaven
kaven@48556522ad65:/root$
SwitchUserGrantedAuthority
是SwitchUserFilter
使用的自定义GrantedAuthority
,SwitchUserFilter
(用户切换处理过滤器)负责用户上下文切换,对于Spring Security
管理的web
应用程序,此过滤器类似于su
命令,此功能的一个常见例子是能够允许更高权限的用户(如ROLE_ADMIN
)切换到普通用户(如ROLE_USER
)。Spring Security
的过滤器以及如何将自定义的过滤器集成到Spring Security
中,博主以后会进行介绍,这里只是了解即可。
所以,SwitchUserGrantedAuthority
是一种用于用户切换场景下的授权实现,不仅存储了权限,还存储了原始用户的Authentication
对象,即source
属性,方便用户切换的退出。
kaven@48556522ad65:/root$ exit
exit
root@48556522ad65:~# exit
logout
Connection closing...Socket close.
Connection closed by foreign host.
Disconnected from remote host(predict) at 13:40:23.
Type `help' to learn how to use Xshell prompt.
[C:\~]$
Spring Security
的授权GrantedAuthority
介绍就到这里,如果博主有说错的地方或者大家有不同的见解,欢迎大家评论补充。
更多推荐
所有评论(0)