处理Spring Boot Resource Server中的安全性异常 [英] Handle Security exceptions in Spring Boot Resource Server

查看:116
本文介绍了处理Spring Boot Resource Server中的安全性异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获取我的自定义 ResponseEntityExceptionHandler OAuth2ExceptionRenderer 来处理纯资源服务器上Spring安全性引发的异常?

How can I get my custom ResponseEntityExceptionHandler or OAuth2ExceptionRenderer to handle Exceptions raised by Spring security on a pure resource server?

我们实施了

@ControllerAdvice
@RestController
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

所以只要资源服务器上出现错误我们希望它回答

so whenever there is an error on the resource server we want it to answer with

{
  "message": "...",
  "type": "...",
  "status": 400
}

资源服务器使用application.properties设置:

The resource server uses the application.properties setting:

security.oauth2.resource.userInfoUri: http://localhost:9999/auth/user

对我们的auth服务器进行身份验证和授权请求。

to authenticate and authorize a request against our auth server.

但是,任何弹簧安全错误都将始终绕过我们的异常处理程序

However any spring security error will always bypass our exception handler at

    @ExceptionHandler(InvalidTokenException.class)
    public ResponseEntity<Map<String, Object>> handleInvalidTokenException(InvalidTokenException e) {
        return createErrorResponseAndLog(e, 401);
    }

并生成

{
  "timestamp": "2016-12-14T10:40:34.122Z",
  "status": 403,
  "error": "Forbidden",
  "message": "Access Denied",
  "path": "/api/templates/585004226f793042a094d3a9/schema"
}

{
  "error": "invalid_token",
  "error_description": "5d7e4ab5-4a88-4571-b4a4-042bce0a076b"
}

那么如何配置资源服务器的安全性异常处理?我找到的只是如何通过实现自定义 OAuth2ExceptionRenderer 来自定义Auth服务器的示例。但我无法找到将其连接到资源服务器安全链的位置。

So how do I configure the security exception handling for a resource server? All I ever find are examples on how to customize the Auth Server by implementing a custom OAuth2ExceptionRenderer. But I can't find where to wire this to the resource server's security chain.

我们唯一的配置/设置是:

Our only configuration/setup is this:

@SpringBootApplication
@Configuration
@ComponentScan(basePackages = {"our.packages"})
@EnableAutoConfiguration
@EnableResourceServer


推荐答案

如前面的评论中所述,请求被拒绝安全框架到达MVC层之前所以 @ControllerAdvice 这里不是一个选项。

As noted in previous comments the request is rejected by the security framework before it reaches the MVC layer so @ControllerAdvice is not an option here.

有3个接口在这里可能感兴趣的Spring Security框架中:

There are 3 interfaces in the Spring Security framework that may be of interest here:


  • org.springframework.security.web.authentication.AuthenticationSuccessHandler

  • org.springframework.security.web.authentication.AuthenticationFailureHandler

  • org.springframework.security.web.access.AccessDeniedHandler

您可以创建每个的实现这些接口是为了自定义为各种事件发送的响应:成功登录,登录失败,尝试访问权限不足的受保护资源。

You can create implementations of each of these Interfaces in order to customize the response sent for various events: successful login, failed login, attempt to access protected resource with insufficient permissions.

以下内容将返回JSON响应登录尝试失败时:

The following would return a JSON response on unsuccessful login attempt:

@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();
  }
}

您还需要注册您的实施安全框架。在Java配置中,它如下所示:

You also need to register your implementation(s) with the Security framework. In Java config this looks like the below:

@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();
  }
}

这篇关于处理Spring Boot Resource Server中的安全性异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆