Issue while running the Spring boot application with Cloud run - spring-boot

In Springboot application we are facing issue after authentication with AD and while doing redirection.
We have added the below redirection in application.properties file:
aad.redirectHomeUri=https://icaps-userhelpertool-dev-cloudrun-kwyk47pogq-ez.a.run.app/resetpassword
Above url is cloud run url where we have deployed our code and same url we have added in AD also . But after authentication its not redirecting and we are getting below error.
19-01-2023 10:08:07.259 ERROR c.m.a.m.ConfidentialClientApplication - [Correlation ID: b396dc37-982d-4f56-ac5d-a754f24f4f53] Execution of class com.microsoft.aad.msal4j.AcquireTokenByAuthorizationGrantSupplier failed.
com.microsoft.aad.msal4j.MsalServiceException: AADSTS500112: The reply address 'http://icaps-userhelpertool-dev-cloudrun-kwyk47pogq-ez.a.run.app/resetpassword' does not match the reply address 'https://icaps-userhelpertool-dev-cloudrun-kwyk47pogq-ez.a.run.app/resetpassword' provided when requesting Authorization code.

I tried to reproduce the same in my environment
Received the error:
AADSTS50011: The redirect URI 'http://xxx/signin-oidc' specified in the request does not match the redirect URIs configured for the application '50065a5f-d3e4-426f-a4f4-1e6fbd2ed06e'. Make sure the redirect URI sent in the request matches one added to your application in the Azure portal.
This error occurred as in my code ,the http protocol it used is http But the one registered in portal is https .
This can be set properly with HttpsRedirection middleware configuration
In spring ,this occurs when your Tomcat server is behind a proxy which redirects to http protocol.
Set the below configurations in application.properties with the proper url in registered-redirect-uri and x-forwarded-proto as mentioned here spring-boot-application-with-azure-ad-throws-reply-url-does-not-match | StackOverflow
application.properties
security.oauth2.client.pre-established-redirect-uri=https://yourappurl.net/login
security.oauth2.client.registered-redirect-uri=https://yourappurl.net/login
security.oauth2.client.use-current-uri=false
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
server.tomcat.use-relative-redirects=true
server.use-forward-headers=true
server.tomcat.internal-proxies=.*
and Add server.forward-headers-strategy=native
Reference : spring-redirect-happening-to-http-login-instead-of-https-login | Stack Overflow

Related

Spring Boot Security and Keycloak - receive 403 forbidden /sso/login after successfull login when using HTTPS

I have a Spring Boot App using Spring Security and Keycloak as IDP.
Keycloak is available under https://auth.example.com, having a realm backo with a client backo-core and a testuser configured with the required roles.
If I configure my local app, using
keycloak.enabled=true
keycloak.auth-server-url=https://auth.example.com/auth
keycloak.realm=backo
keycloak.public-client=true
keycloak.resource=backo-core
keycloak.ssl-required=external
keycloak.confidential-port=443
Everything works fine.
If I deploy it to my DEV environment under https://backo.example.com/backo with https://backo.example.com/sso/login, when accessing the app I get redirect to the Keycloak login. After successful login I get redirected to the redirect URL with the state, session-state and code parameters but receive 403.
https://backo.example.com/sso/login?state=...&session_state=...&code=...
with request initiator chain coming from https://auth.example.com/auth/realms/backo/login-action/authenticate?...
If I set locally keycloak.ssl-required=all, the redirect_url parameter when accessing the login page is https://localhost/sso/login, so I can change it manually to http://localhost:8080/sso/login. After a successful login I have the exact same problem with a 403 Forbidden response for
http://localhost:8080/sso/login?state=...&session_state=...&code=...
with request initiator chain coming from https://auth.example.com/auth/realms/backo/login-action/authenticate?...
This is how my security config looks like
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.authorizeRequests()
.antMatchers("/backo").hasAnyRole(ROLE_ADMIN, ROLE_BACKOFFICE)
.anyRequest().permitAll();
http.csrf().disable();
http.headers().frameOptions().disable(); // otherwise Vaadin doesn't work properly
http
.logout()
.addLogoutHandler(keycloakLogoutHandler())
.logoutUrl("/sso/logout").permitAll()
.logoutSuccessUrl("/");
}
You can ignore this Vaadin workaround, as it fails in /sso/login already.
http.csrf().disable(); is required to prevent other 403 Forbidden errors on post request while authorization.
One thing that could be worth mentioning:
The Spring Boot App has no HTTPS enabled, in our dev environment it sits behind an AWS Application loadbalancer ALB. HTTPS is terminated in the ALB.
We have faced the similar problem three days ago with spring boot thymeleaf application. We have used keycloak adapter (13.0.1) for spring boot.
After successful login it was redirecting to /sso/login page with 403 error.
After lots of effort we finally got the configuration required to fix this issue. you need to use the below application properties :
server.use-forward-headers=true
keycloak.public-client=true
keycloak.ssl-required=all
keycloak.confidential-port=443

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

springdoc-openapi swagger-ui behind proxy configuration

I have added swagger-ui on a spring boot 2.3.1 app, it works fine locally.
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.3.9</version>
</dependency>
This application is deployed in a kubernetes cluster but it's not accessible (no ingress)
Instead we deployed another spring boot app that is accessible and can call this service.
API calls get redirected fine but swagger-ui does not work.
Basically, my proxy app is accessible like this :
https://app-dev.domain.io/proxy-service/v2/my-service/**
=> https://app-dev.domain.io/proxy-service/v2/my-service/swagger-ui.html
In my proxy service, I set the X-Forwarded headers like this :
X-Forwarded-Host = Host header (app-dev.domain.io)
X-Forwarded-Proto = https
X-Forwarded-Prefix = /proxy-service/v2/my-service/
I also set the header Accept-Encoding=identity
The proxy service then calls http://my-service inside the cluster
In MyService configuration I set :
server.forward-headers-strategy=framework
It seems to find static files, but i get javascript errors and a blank page :
Uncaught SyntaxError: Unexpected end of input
swagger-ui-standalone-preset.js:21 Uncaught SyntaxError: Invalid or unexpected token
index.html?configUrl=/proxy-service/v2/my-service/v3/api-docs/swagger-config:41 Uncaught ReferenceError: SwaggerUIBundle is not defined
at window.onload
From what I have searched, I did what was needed (headers-strategy in called service and X-Forwarded in proxy)
Any help would be awesome, as I would like for the services to be easily testable without maintaining a postman collection manually or something similar. ( always forgotten at some point )
Thanks
I have found out that the javascript files are getting truncated.
So the javascript errors make sense.
I'll try again after fixing this
Edit :
It is now working with the complete javascript files.
I used HttpURLConnection instead of RestTemplate which tuncates the files for no reason

Spring Security in Grails runnable jar redirects to HTTP

I'm using a grails 3 runnable jar with spring Security behind a reverse proxy handling https to http traffic (and https to http redirects), forwarding it to http://my-host:8080
For all my /login/** calls , grails is sending "302 redirect" to http
For example a /login/authenticate XHR is redirected with the header
Location: http://my-big-ip/login/ajaxSuccess, etc.
It's not using the serverURL parameter that I set in application.yml to https://my-big-ip
My jar is using embedded tomcat since I have this in my build.gradle
compile "org.springframework.boot:spring-boot-starter-tomcat"
The logs I get about this redirect
2019-03-27 15:56:34,415 DEBUG http-nio-8088-exec-5 org.springframework.security.web.savedrequest.HttpSessionRequestCache - Removing DefaultSavedRequest from session if present
2019-03-27 15:56:34,415 DEBUG http-nio-8088-exec-5 grails.plugin.springsecurity.web.authentication.AjaxAwareAuthenticationSuccessHandler - Redirecting to Ajax Success Url: /login/ajaxSuccess
2019-03-27 15:56:34,415 DEBUG http-nio-8088-exec-5 grails.plugin.springsecurity.web.GrailsRedirectStrategy - Redirecting to '/login/ajaxSuccess'
I believe that you will need to add this to your application/runtime.(groovy|yml):
server."use-forward-headers" = true
There is a good bit of documentation (about this and other things) here https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-web-servers.html that may be helpful if you are interested in additional details.

404 when do logout in Spring Security Rest Plugin for Grails

I'm setting the security system on my project (Grails - Angularjs) with Spring Security Rest Plugin v1.5.4 (using spring security core 2.0.0) for Grails 2.4.4. Doc about this plugin can be found here.
I'm testing the login and logout with postman chrome rest client and I'm able to do a login OK, but I'm getting a 404 when I do logout.
In the documentation clearly says:
The logout filter exposes an endpoint for deleting tokens. It will
read the token from an HTTP header. If found, will delete it from the
storage, sending a 200 response. Otherwise, it will send a 404
response
You can configure it in Config.groovy using this properties:
Config key...................................................................................Default
value
grails.plugin.springsecurity.rest.logout.endpointUrl....................../api/logout
grails.plugin.springsecurity.rest.token.validation.headerName....X-Auth-Token
So, after doing a login successfully, I tried to do a logout to that url (my_host_url/api/logout) with a GET method and sending a header X-Auth-Token with the token I got previously from login.
But I keep getting a 404. See image below
Edit: I'm setting the chain map like this (in order to get a stateless behavior):
grails.plugin.springsecurity.filterChain.chainMap = [
'/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter', // Stateless chain
'/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter' // Traditional chain
]
So. What am I doing wrong here, or what am I missing?
Thanks in advance!
You missed another excerpt from the docs. It's a warning message literally before the chunk you quoted, and says:
Logout is not possible when using JWT tokens (the default strategy), as no state is kept in the server.
If you still want to have logout, you can provide your own implementation by creating a subclass of JwtTokenStorageService and overriding the methods storeToken and removeToken. Then, register your implementation in resources.groovy as tokenStorageService.

Resources