I have this response when it comes to check the user Unauthorized.
i there any possibility to remove the Path from the Unauthorized response ? since it does not gives valuable information for the user
{
"timestamp": "2021-03-18T09:16:09.699+0000",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/test/v1/api/test.com/config/settings"
}
this is how my config looks like
public class ResourceConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.cors();
httpSecurity
.anonymous().disable()
.requestMatchers().antMatchers("/api/**")
.and()
.authorizeRequests()
.antMatchers("/api/**")
.authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
Adding on @linhx idea of using custom AuthenricationEntryPoint
, you can use HandlerExceptionResolver
which resolves to a page.
You can get a detailed comparison of different approaches here.
@Component
public class ABAuthenticationEntryPoint implements AuthenticationEntryPoint {
protected final Logger logger = LoggerFactory.getLogger(ABAuthenticationEntryPoint.class);
private final String realmName = "CustomRealm";
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
resolver.resolveException(request, response, null, authException);
}
}
The HandlerExceptionResolver
uses the handler (HandlerMethod) to obtain the Controller class and scan it for methods annotated with @ExceptionHandler
. If one of this methods matches the exception (ex) then this methods get invoked in order to handle the exception. (else null get returned signaling that this exception resolver feels no responsible).
So, add a class with @ControllerAdvice
:
@ExceptionHandler(value = InsufficientAuthenticationException.class)
public ResponseEntity<Object> handleInsufficientAuthenticationException(InsufficientAuthenticationException ex) {
String methodName = "handleInsufficientAuthenticationException()";
return buildResponseEntity(HttpStatus.UNAUTHORIZED, null, null, ex.getMessage(), null);
}
private ResponseEntity<Object> buildResponseEntity(HttpStatus status, HttpHeaders headers, Integer internalCode, String message, List<Object> errors) {
ResponseBase response = new ResponseBase()
.success(false)
.message(message)
.resultCode(internalCode != null ? internalCode : status.value())
.errors(errors != null
? errors.stream().filter(Objects::nonNull).map(Objects::toString).collect(Collectors.toList())
: null);
return new ResponseEntity<>((Object) response, headers, status);
}
SecurityConfig
class:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
@Autowired
private ABAuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
.....
.and()
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint); //AuthenticationEntryPoint has to be the last
}
}
Finally you will get something like the following, based on how you buildResponseEntity
{
"success": false,
"resultCode": 401,
"message": "Full authentication is required to access this resource"
}