pak*_*kkk 8 java security spring-security spring-boot spring-security-oauth2
我想知道是否可以自定义以下授权错误:
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}
Run Code Online (Sandbox Code Playgroud)
当用户请求没有权限时,我得到了它。我想将其自定义为与Spring Boot错误非常相似:
{
"timestamp":1445441285803,
"status":401,
"error":"Unauthorized",
"message":"Bad credentials",
"path":"/oauth/token"
}
Run Code Online (Sandbox Code Playgroud)
有可能吗
非常感谢。
Dhe*_*rik 11
接受的答案对我使用 Oauth2 不起作用。经过一番研究,异常翻译器解决方案奏效了。
基本上,您需要创建一个WebResponseExceptionTranslator并将其注册为您的异常翻译器。
首先,创建一个WebResponseExceptionTranslatorbean:
@Slf4j
@Configuration
public class Oauth2ExceptionTranslatorConfiguration {
@Bean
public WebResponseExceptionTranslator oauth2ResponseExceptionTranslator() {
return new DefaultWebResponseExceptionTranslator() {
@Override
public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
ResponseEntity<OAuth2Exception> responseEntity = super.translate(e);
OAuth2Exception body = responseEntity.getBody();
HttpStatus statusCode = responseEntity.getStatusCode();
body.addAdditionalInformation("timestamp", dateTimeFormat.format(clock.instant()))
body.addAdditionalInformation("status", body.getHttpErrorCode().toString())
body.addAdditionalInformation("message", body.getMessage())
body.addAdditionalInformation("code", body.getOAuth2ErrorCode().toUpperCase())
HttpHeaders headers = new HttpHeaders();
headers.setAll(responseEntity.getHeaders().toSingleValueMap());
// do something with header or response
return new ResponseEntity<>(body, headers, statusCode);
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
现在您需要更改您的 Oauth2 配置以注册 bean WebResponseExceptionTranslator:
@Slf4j
@Configuration
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private ClientDetailsServiceBuilder builder;
@Autowired
private WebResponseExceptionTranslator oauth2ResponseExceptionTranslator;
@Autowired
private UserDetailsService userDetailsService;
@Override
public void configure(ClientDetailsServiceConfigurer clients) {
clients.setBuilder(builder);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(
Arrays.asList(tokenEnhancer(), accessTokenConverter()));
endpoints.tokenStore(tokenStore())
.tokenEnhancer(tokenEnhancerChain)
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)
.exceptionTranslator(oauth2ResponseExceptionTranslator);
}
}
Run Code Online (Sandbox Code Playgroud)
最终结果将是:
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource",
"code": "UNAUTHORIZED",
"message": "Full authentication is required to access this resource",
"status": "401",
"timestamp": "2018-06-28T23:55:28.86Z"
}
Run Code Online (Sandbox Code Playgroud)
你可以看到,我并没有删除error,并error_description从原体OAuth2Exception。我建议维护它们,因为这两个字段遵循 OAuth2 规范。有关更多详细信息,请参阅RFC和OAuth2 API 定义。
您还可以自定义结果:覆盖error或error_description(只是调用addAdditionalInformation),识别特定异常instance of以返回不同的 json 结果等。但也有限制:如果您想将某些字段定义为integer,我认为不是可能,因为该addAdditionalInformation方法只接受String作为类型。
我知道了 :)
我需要创建一个新类,该类实现“ AuthenticationEntryPoint”,如下所示:
public class AuthExceptionEntryPoint implements AuthenticationEntryPoint
{
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2) throws IOException, ServletException
{
final Map<String, Object> mapBodyException = new HashMap<>() ;
mapBodyException.put("error" , "Error from AuthenticationEntryPoint") ;
mapBodyException.put("message" , "Message from AuthenticationEntryPoint") ;
mapBodyException.put("exception", "My stack trace exception") ;
mapBodyException.put("path" , request.getServletPath()) ;
mapBodyException.put("timestamp", (new Date()).getTime()) ;
response.setContentType("application/json") ;
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED) ;
final ObjectMapper mapper = new ObjectMapper() ;
mapper.writeValue(response.getOutputStream(), mapBodyException) ;
}
}
Run Code Online (Sandbox Code Playgroud)
并将其添加到我的ResourceServerConfigurerAdapter实现中:
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter
{
@Override
public void configure(HttpSecurity http) throws Exception
{
http.exceptionHandling().authenticationEntryPoint(new AuthExceptionEntryPoint()) ;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以找到我的GitHub项目,该项目实现了您所需的一切:
https://github.com/pakkk/custom-spring-security
| 归档时间: |
|
| 查看次数: |
4828 次 |
| 最近记录: |