因此,我为应用程序创建了自己的授权服务器。它也充当资源服务器的角色,仅用于当前测试。
为了保持一致性,我想为OAuth2端点(令牌请求失败-例如身份验证错误)和资源服务器端点(授权错误)定制响应。我在网上看到过各种资源,其中提到创建自定义AuthenticationEntryPoint
或ExceptionTranslator
,但是没有一个对我有用。
这是ApiError
模型:
public class ApiError {
private List<String> errors = new ArrayList<>();
private LocalDateTime timestamp;
private Cause cause;
private HttpResponseStatus httpResponseStatus;
//constructors, getters, setters
private class HttpResponseStatus {
private int value;
private String message;
public HttpResponseStatus(HttpStatus httpStatus) {
this.value = httpStatus.value();
this.message = httpStatus.getReasonPhrase();
}
public int getValue() {
return value;
}
public String getMessage() {
return message;
}
}
private class Cause {
private String exception;
private String message;
public Cause(Class<?> exception, String message) {
this.exception = exception.getSimpleName();
this.message = message;
}
public String getException() {
return exception;
}
public String getMessage() {
return message;
}
}
}
这是我的AuthenticationEntryPoint
。我尝试将其放在下面的WebSecurityConfigurerAdapter
配置中,但没有用:
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
AuthenticationException e) throws IOException, ServletException {
ObjectMapper objectMapper = new ObjectMapper();
HttpStatus httpStatus = HttpStatus.UNAUTHORIZED;
ApiError apiError = new ApiError(httpStatus, e, "Authentication error");
String jsonResponse = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(apiError);
httpServletResponse.setStatus(httpStatus.value());
httpServletResponse.getOutputStream().print(jsonResponse);
}
这是我想更改的默认Spring Security响应类型:
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}
{
"error": "invalid_token",
"error_description": "Invalid access token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleAiOjE1ODY4NjkyOTYsInVzZXJfbmFtZSI6ImFkaXBvcEBnbWFpbC5jb20iLCJhdXRob3JpdGllcyI6WyJST0xFX01BTkFHRVIiXSwianRpIjoiNGYxZmQ1NTItYmQxNC00NDcyLWJhOTctNjIxY2FlZmYzNGQxIiwiY2xpZW50X2lkIjoic2FmZWRyaXZlLXdlYmFwcCIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSJdfQ.IMCogr_M8Skw0R0g0pqshROh8-nms8U3zt5i1G7CXO48OcJ76V1WXTGizn5anzFFIRHk0xGhw-r46lgHhLoWB89pjCC04PAIjFwl31flKWVSW6js9QfMt4O8CL6TAXnyHShUyJxbLZnnavTL3b40iLOHNJSeIf7Ed6goqOZMwZUBDB2KKCY_rmu80Ntj69uzVBrVfXCdDW7SRy-05uTqIGlBTWf3v4NZ4lV7EYzTJOcjavkBcSJeLcNi0DpYu1enF4rLPP9MeIUdiWT9sD6FOlLjs_vXQ_rZnxj-TVVkGSYRNn4u3-Znx4WZ3QBbcDU_O_w8qrp5_JnQbXy27-fmpg"
}
{
"error": "invalid_grant",
"error_description": "Bad credentials"
}
以下是我的WebSecurityConfigurerAdapter
(通用安全配置-订单1 ,AuthenticationManager
在另一个WebSecurityConfigurerAdapter
中配置了订单100 )如下:
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.headers().frameOptions().disable()
.and()
.antMatcher("/console/**")
.authorizeRequests()
.antMatchers("/console/**").hasRole("ADMIN")
.and()
.httpBasic();
}
ResourceServerConfigurerAdapter
:
@Override
public void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/actuator/**", "/api-docs/**").permitAll()
.antMatchers("/protected/**").hasAnyRole("ADMIN", "MANAGER")
.anyRequest().authenticated();
}
AuthorizationServerConfigurerAdapter
:
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
//enables chaining multiple types of claims containing different information
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenConverter));
endpoints.tokenStore(tokenStore)
.accessTokenConverter(tokenConverter)
.authenticationManager(authenticationManager)
.tokenEnhancer(tokenEnhancerChain);
}
我应该如何设置?我查看了无数资源。哪个HttpSecurity
优先?我有点困惑。