✨ 通过编程方式授权方法
This commit is contained in:
parent
1940b29247
commit
c12807224e
|
@ -1083,8 +1083,43 @@ public class AuthTestController {
|
|||
|
||||
## 其余授权方式
|
||||
|
||||
### 前置条件
|
||||
|
||||
为了做一个较为通用看起来比较规范,写了一个配置类,可以在Spring配置文件中进行配置。
|
||||
|
||||
```java
|
||||
@Getter
|
||||
@Setter
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "security-path")
|
||||
@Schema(name = "SecurityPathsProperties对象", description = "路径忽略和认证")
|
||||
public class SecurityConfigProperties {
|
||||
|
||||
@Schema(name = "noAuthPaths", description = "不用认证的路径")
|
||||
public List<String> noAuthPaths;
|
||||
|
||||
@Schema(name = "securedPaths", description = "需要认证的路径")
|
||||
public List<String> securedPaths;
|
||||
|
||||
@Schema(name = "允许的角色或权限", description = "允许的角色或权限")
|
||||
public List<String> adminAuthorities;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
之后在配置文件中指定哪些可以放行的角色或权限。
|
||||
|
||||
```yaml
|
||||
security-path:
|
||||
# 配置放行的角色或权限
|
||||
admin-authorities:
|
||||
- "ADMIN"
|
||||
```
|
||||
|
||||
### 通过编程方式授权方法
|
||||
|
||||
#### 简单使用
|
||||
|
||||
如果需要对权限做出自定义的需求,将传入参数作为判断权限条件,这会很有用,比如某些参数不可以传入,或者参数做权限校验等。
|
||||
|
||||
首先创建一个Spring组件,包含自定义的授权逻辑:
|
||||
|
@ -1127,45 +1162,66 @@ public Result<String> lowerUser(String name) {
|
|||
}
|
||||
```
|
||||
|
||||
#### 进阶使用
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> 参考文档:[使用自定义的 `@Bean` 而不是对 `DefaultMethodSecurityExpressionHandler` 进行子类化](https://docs.spring.io/spring-security/reference/6.3/servlet/authorization/method-security.html#_use_a_custom_bean_instead_of_subclassing_defaultmethodsecurityexpressionhandler)
|
||||
|
||||
在上面可以大致了解到如何使用自定义的方式进行扩展,好处是可以简单易用。
|
||||
|
||||
可以对比下下面章节**【使用自定义授权管理器实现自定义权限校验】**实现哪个更符合你期望预期。
|
||||
|
||||
```java
|
||||
@Component("auth")
|
||||
@RequiredArgsConstructor
|
||||
public class AuthorizationLogic {
|
||||
|
||||
private final SecurityConfigProperties securityConfigProperties;
|
||||
|
||||
/**
|
||||
* 基本权限检查
|
||||
*/
|
||||
public boolean decide(String requiredAuthority) {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
if (authentication == null || !authentication.isAuthenticated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查用户是否有指定权限或是admin
|
||||
return hasAuthority(authentication, requiredAuthority) || isAdmin(authentication);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是管理员
|
||||
*/
|
||||
public boolean isAdmin() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
return authentication != null && isAdmin(authentication);
|
||||
}
|
||||
|
||||
private boolean isAdmin(Authentication authentication) {
|
||||
return securityConfigProperties.getAdminAuthorities().stream()
|
||||
.anyMatch(auth -> authentication.getAuthorities().stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.anyMatch(ga -> ga.equals(auth)));
|
||||
}
|
||||
|
||||
private boolean hasAuthority(Authentication authentication, String authority) {
|
||||
return authentication.getAuthorities().stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.anyMatch(auth -> auth.equals(authority));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 使用自定义授权管理器实现自定义权限校验
|
||||
|
||||
在实际开发中对于SpringSecurity提供的两个权限校验注解`@PreAuthorize`和`@PostAuthorize`,需要对这两个进行覆盖或者改造,需要实现两个`AuthorizationManager<T>`。
|
||||
|
||||
实现完成后需要显式的在配置中禁用原先的内容。
|
||||
|
||||
#### 前置条件
|
||||
|
||||
为了做一个较为通用看起来比较规范,写了一个配置类,可以在Spring配置文件中进行配置。
|
||||
|
||||
```java
|
||||
@Getter
|
||||
@Setter
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "security-path")
|
||||
@Schema(name = "SecurityPathsProperties对象", description = "路径忽略和认证")
|
||||
public class SecurityConfigProperties {
|
||||
|
||||
@Schema(name = "noAuthPaths", description = "不用认证的路径")
|
||||
public List<String> noAuthPaths;
|
||||
|
||||
@Schema(name = "securedPaths", description = "需要认证的路径")
|
||||
public List<String> securedPaths;
|
||||
|
||||
@Schema(name = "允许的角色或权限", description = "允许的角色或权限")
|
||||
public List<String> adminAuthorities;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
之后在配置文件中指定哪些可以放行的角色或权限。
|
||||
|
||||
```yaml
|
||||
security-path:
|
||||
# 配置放行的角色或权限
|
||||
admin-authorities:
|
||||
- "ADMIN"
|
||||
```
|
||||
|
||||
#### 1. 实现前置
|
||||
|
||||
**方式一:正则表达式**
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.spring.step3.controller.test;
|
|||
import com.spring.step3.domain.vo.result.Result;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
@ -17,8 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
@PreAuthorize("hasAuthority('USER')")
|
||||
public class SecurityProgrammaticallyController {
|
||||
|
||||
// @PreAuthorize("permitAll()")
|
||||
@PermitAll
|
||||
@PreAuthorize("permitAll()")
|
||||
@Operation(summary = "拥有 USER 的角色可以访问", description = "当前用户拥有 USER 角色可以访问这个接口")
|
||||
@GetMapping("upper-user")
|
||||
public Result<String> upperUser() {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.spring.step3.mapper;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
|
|
@ -1,14 +1,49 @@
|
|||
package com.spring.step3.security.annotation;
|
||||
|
||||
import com.spring.step3.security.config.properties.SecurityConfigProperties;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("auth")
|
||||
@RequiredArgsConstructor
|
||||
public class AuthorizationLogic {
|
||||
|
||||
public boolean decide(String name) {
|
||||
// 直接使用name的实现
|
||||
// System.out.println(name);
|
||||
return name.equalsIgnoreCase("user");
|
||||
private final SecurityConfigProperties securityConfigProperties;
|
||||
|
||||
/**
|
||||
* 基本权限检查
|
||||
*/
|
||||
public boolean decide(String requiredAuthority) {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
if (authentication == null || !authentication.isAuthenticated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查用户是否有指定权限或是admin
|
||||
boolean baseAuthority = authentication.getAuthorities().stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.anyMatch(auth -> auth.equals(requiredAuthority));
|
||||
|
||||
return baseAuthority || isAdmin(authentication);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是管理员
|
||||
*/
|
||||
public boolean isAdmin() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
return authentication != null && isAdmin(authentication);
|
||||
}
|
||||
|
||||
private boolean isAdmin(Authentication authentication) {
|
||||
return securityConfigProperties.getAdminAuthorities().stream()
|
||||
.anyMatch(auth -> authentication.getAuthorities().stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.anyMatch(ga -> ga.equals(auth)));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue