JJ *_*kar 5 spring spring-mvc spring-security spring-boot
我想生成HTTP响应主体,除了403 ForbiddenHTTP状态代码之外,还引用了一个错误消息,引用了诸如_"missing ...'CUSTOM_AUTHORITY'"_之类的内容.
我的应用程序是@PreAuthorize在Spring-MVC-REST中使用Spring-Security-Secured 方法的Spring Boot @Controller:
@Controller
@RequestMapping("/foo")
public FooController{
@PreAuthorize("hasAuthority('CUSTOM_AUTHORITY')")
public Object getSomething(){ ... }
}
Run Code Online (Sandbox Code Playgroud)
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(AccessDeniedException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public Object forbidden(AccessDeniedException exception){ ... }
}
Run Code Online (Sandbox Code Playgroud)
我想要的是暴露/注入Collection<ConfigAttribute>.在Spring Security的文档中引用它.
似乎没有一种简单的方法可以实现这一点。(AccessDecisionManager即AffirmativeBased) 抛出 ,AccessDeniedException但没有任何您想要的信息。因此,如果您想“公开/注入” Collection<ConfigAttribute>,您需要提供自己的AccessDecisionManager异常来抛出保存ConfigAttributes 的自定义异常。
最简单的方法是用AccessDecisionManager您自己的默认值包装默认值并对其进行委托方法调用:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
CustomMethodSecurityConfig extends GlobalMethodSecurityConfiguration
@Override
protected AccessDecisionManager accessDecisionManager() {
AccessDecisionManager default = super.accessDecisionManager();
MyCustomDecisionManager custom = new CustomDecisionManager(default);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以AccessDecisionManager按如下方式定义您的自定义:
public class MyCustomDecisionManager implements AccessDecisionManager {
private AccessDecisionManager default;
public MyCustomDecisionManager(AccessDecisionManager acm) {
this.default = acm;
}
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException{
try {
default.decide(authentication, object, configAttributes)
} catch(AccessDeniedException ex) {
throw new CustomAccessDeniedException(ex.getMessage(), configAttributes);
}
}
// other methods delegate to default
}
Run Code Online (Sandbox Code Playgroud)
现在,每当访问被拒绝时,您都会收到一个包含Collection<ConfigAttribute>.
您的自定义异常可能如下所示:
public class CustomAccessDeniedException extends AccessDeniedException {
private Collection<ConfigAttribute> attributes;
public CustomAccessDeniedException(String message, Collection<ConfigAttribute> attr) {
super(message);
this.attributes = attr;
}
public Collection<ConfigAttribute> getAttributes() {
return this.attributes;
}
}
Run Code Online (Sandbox Code Playgroud)
现在您的 @ExceptionHandler 可以处理您的CustomAccessDeniedException并可以访问ConfigAttributes。
但是...
我不确定这是否会向您提供您想要的错误消息。该ConfigAttribute接口只有一个方法:
String getAttribute();
Run Code Online (Sandbox Code Playgroud)
javadoc 指出:
如果 ConfigAttribute 无法以足够的精度表示为字符串,则应返回 null。
由于我们不能依赖接口方法,因此如何处理每个方法ConfigAttribute将在很大程度上取决于您正在处理的特定对象的类型。
例如,ConfigAttribute对应于@PreAuthorize("hasAuthority('CUSTOM_AUTHORITY')")is PreInvocationExpressionAttribute,要打印类似于您想要的内容,您可以执行以下操作:
PreInvocationExpressionAttribute attr = (PreInvocationExpressionAttribute)configAttribute;
String expressionString = attr.getAuthorizeExpression().getExpressionString();
System.out.println(expressionString); // "hasAuthority('CUSTOM_AUTHORITY')"
Run Code Online (Sandbox Code Playgroud)
这是主要的缺点。此外,您将获得所有s ConfigAttribute,而不一定是失败的。
| 归档时间: |
|
| 查看次数: |
241 次 |
| 最近记录: |