Add Single Sign-On to Your Spring Boot Web App in 15 Minutes

Brian Demers

Take a look at the latest Spring Boot + Spring Security. IIRC you should be able to configure form login and an OAuth login.
IIRC, you just need to configure “form” login (this is hinted here too: https://projects.spring.io/…

Pal

How does okta lib builds the redirect-url?. my server is behind load balancer which does https. but in the redirect-url which is generated by okta lib, is putting http instead of https.
Could you please help me

Shantanu More

Hello,I understand the difference in OAuth and SSO however I have some confusion about it due to different blog post. I was going through the following blog and I can see that author has followed the same process and used @Enable2AuthSSO annotation in the groovy file instead of creating a class file.

https://developer.okta.com/…

So what is the exact difference in both the blog post.

Brian Demers

With Groovy you can define classes a few different ways, though the most common is to create a .groovy file (same as you would for a java class defined in a .java file)

Java Techie

Hi Team,

Am trying to integrate okta with my spring boot application , even i referred okta official documents for boot but no luck .

Sometimes Principal is getting Null and sometimes its giving spring error with message required user approval

did any one tried with spring boot 2.x please do let me know

PFB Error Log
org.springframework.security.oauth2.client.resource.UserRedirectRequiredException: A redirect is required to get the users approval
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.getRedirectForAuthorization(AuthorizationCodeAccessToke…:359) ~[spring-security-oauth2-2.2.1.RELEASE.jar:na]
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessToke…:205) ~[spring-security-oauth2-2.2.1.RELEASE.jar:na]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221) ~[spring-security-oauth2-2.2.1.RELEASE.jar:na]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173) ~[spring-security-oauth2-2.2.1.RELEASE.jar:na]
at org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter.attemptAuthentication(OAuth2ClientAuthenticationP…:105) ~[spring-security-oauth2-2.2.1.RELEASE.jar:na]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProce…:212) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceF…:105) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationF…:56) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.21.jar:9.0.21]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.21.jar:9.0.21]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.21.jar:9.0.21]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.21.jar:9.0.21]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853) [tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587) [tomcat-embed-core-9.0.21.jar:9.0.21]
at org.apache.tomcat.util.net…(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.21.jar:9.0.21]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_201]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_201]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.21.jar:9.0.21]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_201]

below is my GitHub link , please assist me if am doing anything wrong .

Link : [https://github.com/basanta-…]
https://uploads.disquscdn.c…

regards,
Basant Hota

Java Techie

One more issue i found , request going to controller it means , its not redirecting for security please find attached screenshot https://uploads.disquscdn.c… https://uploads.disquscdn.c…

please assist me to resolve this issue

Matt Raible

Does your main Application class have @EnableOAuth2Sso on it? This causes it to redirect to Okta before coming back to your endpoint.

Balaji Estamsetty

Hi,
1. I’ve been getting the 400 bad request error when enter the http://localhost:8080. It’s not redirecting to Okta login page.
2. After added the okta.oauth2.redirect-uri=/login in the properties file then it’s displayed Okta login page. But credentials provided it redirected to http://localhost:8080/login?error page as below details.

This page isn’t workinglocalhost redirected you too many times.
Try clearing your cookies.
ERR_TOO_MANY_REDIRECTS

System logs are showing as success(as below) . Seems it’s not able to invoke the @GetMapping("/") method.

OAuth2 authorization code request
success

Please suggest.
Thank you.

Brian Demers

I’ve seen something like this when the clientId/clientSecret were not set correctly, which resulted in Spring Security rejecting the code (after the user was logged in on the Okta side)
What ends up happening in this scenario is the Spring session is not authenticated so it redirects to Okta, Okta is authenticated so it redirects back to Spring (and round and round)

Double check our application’s config, and if you still see the problem check your Okta Log (in the admin console).

Keep us posted!

Balaji Estamsetty

Thanks for your reply.

I have verified clientId/ClientSecret are correct.

I used @EnableOAuth2Client (org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;)
instead of @EnableOAuth2Sso.

is this cause any issue. Since I don’t find relevant dependency EnableOAuth2Sso.

If you have any git repository of this blog, please share

Thanks

Brian Demers

You will need to use @EnableOAuth2Sso for this example. If you are trying to use the later versions of Spring Security, you can take a look at this example repo: https://github.com/okta/sam…

Matt Raible

If you’re using Spring Boot 2.1, you need to use the Okta Spring Boot Starter without the spring-security-oauth2-autoconfigure. You also might try checking out our Spring Boot samples.

Brian Demers

Looks like I only answered part of your questions, but for anyone seeing this in the future.

You can configure your load balancer to use X-Forwarded headers, see this Spring Security doc for more info:
https://docs.spring.io/spri…

Syed Ibrez

https://uploads.disquscdn.c… Hi,
I am not getting redirected to okta login page when I enter http://localhost:8080
Here is the error page and okta configuration https://uploads.disquscdn.c…

Brian Demers

Set the “Login redirect URIs” to http://localhost:8080/login
(Spring security will handle the response on /login and then redirect you to your previous page

NOTE: This has changed (and standardized) with recent version of Spring Boot/Spring Security
for example: https://developer.okta.com/…

Manisha Burle

Hi i have tried to include sso and done all the steps which are given in this blog . but , I am getting following exception
java.lang.NoSuchMethodError: org.springframework.boot.env.YamlPropertySourceLoader.load. Could you please help me out.

Matt Raible

This tutorial is for Spring Boot 1.5.x. Are you using a newer version? For Spring Boot 2.x, see our Spring Boot starter’s documentation: https://github.com/okta/okt….

Ashwin Sahay

Hi ,I have an application in spring boot 1.2 , but when I try to @EnableOAuth2Sso,it is not getting annotated , it is not detecting the above dependency , could you help me guide how to do this in spring 1.2 ?

Matt Raible

Are you sure it’s Spring Boot 1.2 and not 2.1? For the differences between Spring Security’s OAuth support between Spring Boot 1.5.x and Spring Boot 2.x, please see Migrate Your Spring Boot App to the Latest and Greatest Spring Security and OAuth 2.0.

Ragala Purushotham

Do we have provision to enable or disable sso on a need basis?