spring - Spring boot security中授权服务关闭时的授权错误处理不起作用
问题描述
在我的 Spring Boot Web 应用程序中,我点击了第三方服务进行授权,而我的应用程序只是一个内容提供者。父应用程序使用站点管理员进行身份验证。我的应用程序在标头中获取用户 ID,并调用第三方 api 以设置 UserDetails 与权限。
我的要求是在第三方授权服务关闭时处理场景。目前在这种情况下,我将 UserDetails 设置为没有角色,并且由于每个端点都受授权绑定,因此如果用于授权的第三方服务关闭,我会得到 403。
但是如果用户缺乏授权并且授权服务关闭,我想显示不同的消息。
如果我通过从UserDetailsServiceImpl -> loadUserByUserName()抛出自定义异常来处理授权服务,则RequestHeaderAuthenticationFilter遇到此异常并且请求被过滤掉。知道如何完成这项工作吗?
安全配置
public class WebSecurityCustomConfig extends WebSecurityConfigAdapter {
private UserDetailsService userDetails;
protected void configure(HttpSecurity http) {
http.csrf().disable().authorizeRequests().antMatchers("/*).permitAll()
.anyRequests()
.hasAnyAuthority("MODULEX","MODULEY");
http.addFilterBefore(requestHeaderAuthFilter(),
BasicAuthenticationFilter.class);
http.exceptionHandling().authenticationEntryPoint(customEntryPoint());
}
protect void configure(AuthenticationManagerBuilder builder) {
PreAuthenticaticatedAuthenticationProvider auth = new
PreAuthenticaticatedAuthenticationProvider ();
auth.setPreAuthenticatedUserDetailsService(new
UserDetailsByNameServiceWrapper<>(userDetails));
}
}
自定义 UserDetailsService
public class CustomUserDetailsService implements UserDetailsService {
private final AuthorizationService authService;
@Inject
public CustoUserDetailsService(AuthorizationService authService) {
this.authService = authService;
}
public UserDetails loadUserByUsername(String username) {
return new User(username, "",
authService.getAuthorities(username));
// authService is a third party jar and if their upstream service
//is down , it throws a runtime exception
}
}
如果我按如下方式处理他们的错误,那么我最终会得到 403,但如果服务关闭,我想要 503,如果用户对他正在访问的端点没有正确的权限,我想要 403。
当前处理认证服务异常
public UserDetails loadUserByUsername(String username) {
try{
return new User(username, "",
authService.getAuthorities(username));
}
catch(AuthServiceException e) {
return new User(username, "",
Collections.emptyList());
}
}
解决方案
实现AuthenticationEntryPoint
和覆盖commence()
方法如下。
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
然后在你的WebSecurityCustomConfig
类中创建一个方法来初始化RestAuthenticationEntryPoint
类,如下所示。
public AuthenticationEntryPoint authenticationEntryPoint() {
RestAuthenticationEntryPoint ep = new RestAuthenticationEntryPoint();
return ep;
}
然后将您的以下行更改http.exceptionHandling().authenticationEntryPoint(customEntryPoint());
为
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint());
推荐阅读
- javascript - 使用 redux connect 的连接组件的子组件在一次 prop 更改后不会重新渲染
- python - django 在 UpdateView 中提交多个表单
- android - 几次点击后音频文件停止在列表视图上播放?
- xslt - XSL - 用另一个字符替换管道
- google-cloud-kms - 从错误的文件创建密钥,我该如何修改它/解决这个问题?
- r - 具有多个 lm 函数的循环
- rabbitmq - 使用管理 REST API 更改现有 RabbitMQ 队列的最大优先级
- azure-webjobs - Azure Batch Job 顺序执行不起作用
- ios - WKWebView 可水平滚动
- matlab - 提取matlab/八度符号表达式的特定部分?