Pet*_*ete 17 java security spring spring-security spring-boot
如何在纯资源服务器上获取我的自定义ResponseEntityExceptionHandler或OAuth2ExceptionRenderer处理Spring安全性引发的异常?
我们实施了一个
@ControllerAdvice
@RestController
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
Run Code Online (Sandbox Code Playgroud)
因此,只要资源服务器上出现错误,我们就希望它能够回答
{
"message": "...",
"type": "...",
"status": 400
}
Run Code Online (Sandbox Code Playgroud)
资源服务器使用application.properties设置:
security.oauth2.resource.userInfoUri: http://localhost:9999/auth/user
Run Code Online (Sandbox Code Playgroud)
对我们的auth服务器进行身份验证和授权请求.
但是,任何弹簧安全性错误都将始终绕过我们的异常处理程
@ExceptionHandler(InvalidTokenException.class)
public ResponseEntity<Map<String, Object>> handleInvalidTokenException(InvalidTokenException e) {
return createErrorResponseAndLog(e, 401);
}
Run Code Online (Sandbox Code Playgroud)
并生产
{
"timestamp": "2016-12-14T10:40:34.122Z",
"status": 403,
"error": "Forbidden",
"message": "Access Denied",
"path": "/api/templates/585004226f793042a094d3a9/schema"
}
Run Code Online (Sandbox Code Playgroud)
要么
{
"error": "invalid_token",
"error_description": "5d7e4ab5-4a88-4571-b4a4-042bce0a076b"
}
Run Code Online (Sandbox Code Playgroud)
那么如何配置资源服务器的安全性异常处理呢?我找到的只是如何通过实现自定义来自定义Auth服务器的示例OAuth2ExceptionRenderer.但我无法找到将其连接到资源服务器的安全链的位置.
我们唯一的配置/设置是这样的:
@SpringBootApplication
@Configuration
@ComponentScan(basePackages = {"our.packages"})
@EnableAutoConfiguration
@EnableResourceServer
Run Code Online (Sandbox Code Playgroud)
Ala*_*Hay 30
如前面的注释中所述,安全框架在到达MVC层之前拒绝该请求,因此@ControllerAdvice这里不是一个选项.
Spring Security框架中有3个接口可能会引起关注:
您可以创建每个接口的实现,以自定义为各种事件发送的响应:成功登录,登录失败,尝试访问权限不足的受保护资源.
以下将在失败的登录尝试时返回JSON响应:
@Component
public class RestAuthenticationFailureHandler implements AuthenticationFailureHandler
{
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException ex) throws IOException, ServletException
{
response.setStatus(HttpStatus.FORBIDDEN.value());
Map<String, Object> data = new HashMap<>();
data.put("timestamp", new Date());
data.put("status",HttpStatus.FORBIDDEN.value());
data.put("message", "Access Denied");
data.put("path", request.getRequestURL().toString());
OutputStream out = response.getOutputStream();
com.fasterxml.jackson.databind.ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(out, data);
out.flush();
}
}
Run Code Online (Sandbox Code Playgroud)
您还需要使用安全框架注册您的实现.在Java配置中,如下所示:
@Configuration
@EnableWebSecurity
@ComponentScan("...")
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
@Override
public void configure(HttpSecurity http) throws Exception
{
http.addFilterBefore(corsFilter(), ChannelProcessingFilter.class).logout().deleteCookies("JESSIONID")
.logoutUrl("/api/logout").logoutSuccessHandler(logoutSuccessHandler()).and().formLogin().loginPage("/login")
.loginProcessingUrl("/api/login").failureHandler(authenticationFailureHandler())
.successHandler(authenticationSuccessHandler()).and().csrf().disable().exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint()).accessDeniedHandler(accessDeniedHandler());
}
/**
* @return Custom {@link AuthenticationFailureHandler} to send suitable response to REST clients in the event of a
* failed authentication attempt.
*/
@Bean
public AuthenticationFailureHandler authenticationFailureHandler()
{
return new RestAuthenticationFailureHandler();
}
/**
* @return Custom {@link AuthenticationSuccessHandler} to send suitable response to REST clients in the event of a
* successful authentication attempt.
*/
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler()
{
return new RestAuthenticationSuccessHandler();
}
/**
* @return Custom {@link AccessDeniedHandler} to send suitable response to REST clients in the event of an attempt to
* access resources to which the user has insufficient privileges.
*/
@Bean
public AccessDeniedHandler accessDeniedHandler()
{
return new RestAccessDeniedHandler();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您使用@EnableResourceServer,则可能会发现扩展方便,ResourceServerConfigurerAdapter而不是WebSecurityConfigurerAdapter在@Configuration课堂上。这样,您可以简单地AuthenticationEntryPoint通过重写configure(ResourceServerSecurityConfigurer resources)并resources.authenticationEntryPoint(customAuthEntryPoint())在方法内部使用来注册自定义。
像这样:
@Configuration
@EnableResourceServer
public class CommonSecurityConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.authenticationEntryPoint(customAuthEntryPoint());
}
@Bean
public AuthenticationEntryPoint customAuthEntryPoint(){
return new AuthFailureHandler();
}
}
Run Code Online (Sandbox Code Playgroud)
还有一个OAuth2AuthenticationEntryPoint可以扩展的优点(因为它不是最终的),并且在实现custom时可以部分重用AuthenticationEntryPoint。特别是,它添加了带有错误相关详细信息的“ WWW-Authenticate”标头。
| 归档时间: |
|
| 查看次数: |
19384 次 |
| 最近记录: |