Итак, я создал свой собственный сервер авторизации для своего приложения. Он также играет роль сервера ресурсов, просто для тестирования в данный момент.
Для согласованности я хотел бы настроить ответы как для конечных точек 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
(общая конфигурация безопасности c - заказ 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
имеет приоритет? Я немного смущен.