在Spring Boot Resource Server中处理安全异常

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

我们实施了

@ControllerAdvice

@RestController

public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

因此,只要资源服务器上出现错误,我们都希望它回答

{

"message": "...",

"type": "...",

"status": 400

}

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

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

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

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

    @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"

}

那么,如何为资源服务器配置安全异常处理?我所发现的都是有关如何通过实现custom来定制Auth

Server的示例OAuth2ExceptionRenderer。但是我找不到将其连接到资源服务器安全链的位置。

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

@SpringBootApplication

@Configuration

@ComponentScan(basePackages = {"our.packages"})

@EnableAutoConfiguration

@EnableResourceServer

回答:

如前面的注释中所述,该请求在到达MVC层之前被安全框架拒绝,因此@ControllerAdvice这里不是一个选择。

Spring Security框架中有3个接口可能是您感兴趣的:

  • org.springframework.security.web.authentication.AuthenticationSuccessHandler
  • org.springframework.security.web.authentication.AuthenticationFailureHandler
  • org.springframework.security.web.access.AccessDeniedHandler

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

以下将在登录尝试失败时返回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();

}

}

您还需要向安全框架注册您的实现。在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();

}

}

以上是 在Spring Boot Resource Server中处理安全异常 的全部内容, 来源链接: utcz.com/qa/424667.html

回到顶部