How to handle 401 unauthorized error in Springboot app - spring-boot

I need to log 401 unauthorized errors in my Springboot application.
I wanted to log this for a certain end point in my app since its unauthorized error I know this attempt will be caught when invoking the api at the beginning itself.
Are there anyways I can keep track of this in spring boot?
I tried through WebSecurityConfig but didnt help.
I am using springboot 2.
Thanks in advance.

There are 2 ways I can think of, but probably there are more
use custom #ExceptionHandler method in your controller and make it sensitive to UnauthorizedException.class
Use Filter to introspect into request/response - and log whatever you want in case of response beeing 401.

You can get hold of the authentication entry point and handle some 401 logic in the http
security config:
.authenticationEntryPoint((httpServletRequest, httpServletResponse, e) -> {
log.warn(e.getMessage());
httpServletResponse.setStatus(401);
httpServletResponse.getWriter().print(e.getMessage());
})

Related

How to disable auto login redirect in Spring Boot Keycloak Adapter

I am writing an API in Spring Boot that I want to secure using Keycloak.
After doing some setting up, I managed to get the keycloak adapter to work. While I was expecting a 403 on any non-authenticated request, I get an HTTP 302 redirect to login page instead.
As I am working on an API, how can I disable the auto login-redirect and provide a 403 error message, so that I could add some frontend logic to start on the login process?
In your config, you do
http.exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint())
It will start returning 403 on every failed call and you can then catch it and whatever logic you need.
You need to add the propery keycloak.bearer-only: true in the application.properties or application.yml to avoid redirect to login page when there is one error
You will get one 401 error

Client Registration with Spring-boot Oauth2 - tokenUri vs issuerUri

Sorry folks, this may be a newb question. I'm a little lost.
My Spring-boot environment provides me with keycloak for client authorization, it gives me these.
spring.security.oauth2.resourceserver.jwt.issuer-uri
spring.security.oauth2.client.provider.keycloak.issuer-uri
spring.security.oauth2.client.registration.keycloak.* # client-id, secret, provider, grant-type
I noticed on the ClientRegistration that .issuerUri(String uri) is not avaialbe until Spring-Security v5.4.x. I am using 5.3.5, although I could bump up. I am confused what the difference is. As I would expect, I get an error when I do .tokenUri(issuerUri). I believe they are different modes/API, but I am at a loss as to what I should set in the 5.3.5 API.
Caused by: org.springframework.security.oauth2.client.ClientAuthorizationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 405 Method Not Allowed: [{"error":"RESTEASY003650: No resource method found for POST, return 405 with Allow header"}]
So as a newb, I don't get why I have 4 choices of URI and what they do. Google and javadoc haven't been much help, so I figure I just don't know the right place to look to learn it. The only way I know how to fix this is to manual make my own HTTP call to the URI and get my Authentication token, but that would defeat the purpose of the Oauth2 library.
tokenUri represents the URI for the token endpoint. For example:
https://authz.example.org/auth/realms/myrealms/protocol/openid-connect/token
Whereas issuerUri is the URI that identifies the Authorization Server:
https://authz.example.org/auth
It's quite common for the issuer URI to be the root for more specific URIs like the token URI.
Regarding your specific error, I'd imagine that Keycloak is stating that you cannot POST to https://authz.example.org/auth, which is true. You should be POSTing to the token endpoint.
The issuer-uri Spring Boot property should cause Spring Security to look up the other endpoints and add them to a default ClientRegistration. Because of that, I'm not sure why you are also trying to programmatically configure ClientRegistration. That said, if you do need to programmatically create a ClientRegistration, you can use the issuer URI like so, and Spring Security will do the rest:
#Bean
ClientRegistrationRepository registrations() {
ClientRegistration registration = ClientRegistrations
.forIssuerLocation("https://authz.example.org/auth")
.build();
return new InMemoryClientRegistrationRepository(registration);
}

Spring security exception handler

I have spring oauth2 authorization server with authorization_code and refresh_token grant types client. Sometimes it happens that used refresh_token is not valid, which causes long and ugly exception in logs:
org.springframework.security.oauth2.common.exceptions.InvalidGrantException: Invalid refresh token: xxxxxxxx-yyyy-xxxx-yyyy-xxxxxxxxxxxx
at org.springframework.security.oauth2.provider.token.DefaultTokenServices.refreshAccessToken(DefaultTokenServices.java:142) ~[spring-security-oauth2-2.2.1.RELEASE.jar!/:na]
at org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter.getAccessToken(RefreshTokenGranter.java:47) ~[spring-security-oauth2-2.2.1.RELEASE.jar!/:na]
at org.springframework.security.oauth2.provider.token.AbstractTokenGranter.grant(AbstractTokenGranter.java:65) ~[spring-security-oauth2-2.2.1.RELEASE.jar!/:na]
at org.springframework.security.oauth2.provider.CompositeTokenGranter.grant(CompositeTokenGranter.java:38) ~[spring-security-oauth2-2.2.1.RELEASE.jar!/:na]
[...]
Is it there anything like #RestControllerAdvice which would handle such exceptions?
I already tried using mentioned #RestControllerAdvice, but unfortunately it didn't work.
I am not very familiarized with Spring OAUTH2 Authorization, however my answer might be helpful for you.
#RestControllerAdvice is designed to assist #RestController therefore it works if the request is handled by the DispatcherServlet. However, security-related exceptions occurs before that as it is thrown by Filters. Hence, it is required to insert a custom filter AccessDeniedHandler implementation and AuthenticationEntryPoint implementation) earlier in the chain to catch the exception and return accordingly. These filters can be inserted easily in your web security configurations.
Here you can learn how to detect an Authentication Failure in the Client.
You could also check this tutorial .

Spring MVC: how to handle incoming request to wrong context path

How do we handle incoming request to a wrong contextpath in spring mvc?
I have deployed a spring mvc application having contextpath as
http://exampledomain.com/mycontext
But when I try accessing url http://exampledomain.com/wrongcontext I get error as HTTP Status 404 - /wrongcontext/
I have implemented error handling which works fine for all wrong url when correct context path is used but it does not work for wrong context path.
I am trying to understand how do we redirect all incoming request to specific page in production environment..
thanks in advance
Your application can only see requests to its context /mycontext There is nothing your application can do about requests to other contexts.
You can however deploy an application at the root context / and implement an error handler there.
Check out this answer: How to customize JBoss AS7 404 page
That answer relates to JBoss, but the same idea will apply on other servers.
It is not possible to handle wrong context path requests in Spring since it only will handle the requests which goes to your context root. You have to take a look at server configuration parameters to redirect those kind of requests. If you are working on Tomcat, check path parameter of context.xml:
https://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Defining_a_context
We can use #ExceptionHandler inside a #Controller or #ControllerAdvice to handle such kind of exceptions and decide on the view page to be rendered.
#ExceptionHandler({ HttpRequestMethodNotSupportedException.class,
HttpMediaTypeNotSupportedException.class, HttpMediaTypeNotAcceptableException.class,
MissingPathVariableException.class, MissingServletRequestParameterException.class,
ServletRequestBindingException.class,MethodArgumentNotValidException.class, MissingServletRequestPartException.class,
NoHandlerFoundException.class})
public ModelAndView handleException(){
return new ModelAndView("errorpage");
}

Configuring Spring WebSecurityConfigurerAdapter to use exception handler

Spring Boot here. I just read this excellent Baeldung article on Spring Security and implementing basic auth with it. I'm interested in implementing it for a simple REST service (so no UI/webapp) that I need to build.
I'm particularly interested in the BasicAuthenticationEntryPoint impl. In this impl's commence override, the author:
Adds a WWW-Authenticate header to the response; and
Sets the HTTP status code on the response; and
Writes the actual response entity directly to the response; and
Sets the name of the realm
I want to follow this author's example to implement basic auth for my app, but I already have a perfectly functioning ResponseEntityExceptionHandler working for my app:
#ControllerAdvice
public class MyAppExceptionMapper extends ResponseEntityExceptionHandler {
#ExceptionHandler(IllegalArgumentException.class)
#ResponseBody
public ResponseEntity<ErrorResponse> handleIllegalArgumentExeption(IllegalArgumentException iaEx) {
return new ResponseEntity<ErrorResponse>(buildErrorResponse(iaEx,
iaEx.message,
"Please check your request and make sure it contains a valid entity/body."),
HttpStatus.BAD_REQUEST);
}
// other exceptions handled down here, etc.
// TODO: Handle Spring Security-related auth exceptions as well!
}
Is there any way to tie Spring Security and Basic Auth fails into my existing/working ResponseEntityExceptionHandler?
Ideally there's a way to tie my WebSecurityConfigurerAdapter impl into the exception handler such that failed authentication or authorization attempts throw exceptions that are then caught by my exception handler.
My motivation for doing this would be so that my exception handler is the central location for managing and configuring the HTTP response when any exception occurs, whether its auth-related or not.
Is this possible to do, if so, how? And if it is possible, would I need to still add that WWW-Authenticate to the response in my exception handler (why/why not)? Thanks in advance!
I don't think that this is possible. Spring security is applied as a ServletFilter, way before the request ever reaches any #Controller annotated class - thus exceptions thrown by Spring Security cannot be caught by an exception handler (annotated with #ControllerAdvice).
Having had a similar problem, I ended up using a custom org.springframework.security.web.AuthenticationEntryPoint which sends an error, which in turn is forwarded to a custom org.springframework.boot.autoconfigure.web.ErrorController

Resources