SpringBoot 2 SSO with OAM using SAML2 - spring-boot

I am working on a web application of tech stack contains front end ReactJS and backend SpringBoot 2 Microservices. Now it's time for the SSO integration **(single sign on) using the OAM(Oracle Access Manager) using SAML2 **.
I had a discussion with OAM Team and they had given me below details
Entity ID or Issuer ID
OAM Entry Point or OAM SSO URL
X509 Certificate
Assertion consumer URL (ACS URL) which i had given to them to receive SAML Response
online i could find few SSO option with SSOCIRCLE, OKTA, ONEIDENTITY etc but couldn't find any resources with Springboot2 + SSO + OAM.
Please throw some lights or any response on how to start would be greatly appreciated.

You can start with OAM installation:
https://docs.oracle.com/en/middleware/idm/access-manager/12.2.1.4/tutorial-oam-install-oam/
Refer to the following link to understand deployment and usage in application:
https://docs.oracle.com/en/middleware/idm/access-manager/12.2.1.4/tutorial-oam-protect-wlsapp/#deploy-a-sample-application-to-weblogic-server

You have to integrate below flows
Login flow: From your web application (frontend) redirect to the Federation system endpoint (get their login endpoint), this is a browser redirect. Here 2 types of configurations options are available- Either you send the xml Metadata to them when you redirect to their portal OR
These configurations can be set at OAM manually and you only have to do a simple browser redirect. (I have tried the 2nd option).
User enters the credentials in Federation page which gets authenticated by IdP and after successful authentication the SP is notified on ACS login url. So your login url will be basically a callback url which will be called by them and they will be sending a SAML response on that callback api. Once you get a notification on your callback you need to redirect the user to your portal.
For this your callback url should set http response status code as 302 and response.headers.location as the endpoint (along with saml response) where you want the user to redirect. Take care of validating saml signature before redirecting user to your portal.
On your frontend code, you will have to check for the SAML response with windows.location.search.
These steps will redirect user back to SP portal.
Logout flow: when user clicks on SP logout button, execute your logout api and then redirect user to Federation System's logout url, browser redirection, in this case User's session will also terminate at their(SAML) end and they redirect user to SP portal.
Ensure that user's sessions (both) are in sync. For this keep idle timeout and max session timeout same at both ends.
Hope this helps.

Related

SAMLException: InResponseToField of the Response doesn't correspond to sent message

We are working on an application, which is protected with spring security saml.
Authentication works fine, but there is one problem with the following workflow in production environment.
user requests the unprotected address www.server.com
response is a html page with an inline script that changes window.location.href to the saml protected page (service provider) www.server.com/app/action?param1=value1&param2=value2
spring saml detects that authentication is needed and redirects the user to the login form (identity provider) on www.login-server.com
at this point the login form is the first page that is displayed to the user
user adds this login page as bookmark (including saml related url params for this http session) www.login-server.com/adfs/ls/?SAMLRequest=xxx&SigAlg=xxx&Signature=arGdsZwJtHzTDjQP1oYqbjNO
user works with the application...
at the next day the user opens this bookmark and login
IdP redirects to the SP but the belonging http session has already expired
Now we get the following exception in our application:
org.opensaml.common.SAMLException: InResponseToField of the Response doesn't correspond to sent message arGdsZwJtHzTDjQP1oYqbjNO
Any ideas how to handle this workflow so the user can use the application after successful login?
Thanks for your answers!
We have solved our issue with following changes to the spring saml configuration:
In bean with id successRedirectHandler (org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler) we set the defaultTargetUrl to the init-Action of our application (including all request parameters). This url will be automatically used in case of IdP initiated SSO.
In Bean with id contextProvider (org.springframework.security.saml.context.SAMLContextProviderLB) we set storageFactory to org.springframework.security.saml.storage.EmptyStorageFactory. This disables the check of the InResponseToField.
When you applicate generated an AuthnRequest, the request has an ID which your application somehow keeps. The corresponding response from IdP must have InResponseTo attribute set to that same ID value so that your application can verify that the response is meant to be for the request it sent.
However, when your user bookmarked the adfs link that contains request (www.login-server.com/adfs/ls/?SAMLRequest=xxx...), your application had totally forgotten about that request. In other word, it no longer kept the request ID somewhere and couldn't verify response.
The solution is to tell your users not to bookmark the www.login-server.com/adfs/ls/?SAMLRequest=xxx... link. Instead, they must bookmark a link in your application where it can generate a new request and send to ADFS.

Spring saml SSO

I have a portal application developed using spring security and mvc framework. This portal application connects to IDP (Developed using Spring security and spring saml) for authentication. if the user authentication is success,user will be navigated to homepage where multiple links are provided for external applications… When the user clicks on the application link, user should successfully navigated to the respective application without challenging login page.
Other applications are developed using struts and spring security. How do I make sure that when a link is clicked from the portal, either saml token or context is passed to other application so it will not ask for login.
Any help is greatly appreciated.
The most common flow for SAML is something like the following:
Application (called service provider, or SP) receives request (any request, like request for a business resource) from unauthenticated user
It redirects the user (most commonly via http redirect) to the IdP (in which the SP should already be registered)
If the user is not authenticated to the IdP (not logged in to SSO), a login form is presented and login is managed by the IdP until there is a user session with the IdP
If the user is already authenticated with the IdP (because either he was already or entered a correct user/password), the IdP issues its claim token and posts the user with the token back to the Assertion Consumer Service in the SP (the original application)
The Assertion Consumer Service (practically just an API endpoint) receives and validates the SAML token and creates an own application session with the user. Now the user is authenticated to the application (SP)
Upon the next request to the application (SP), there is already a session, so SAML is not involved
Note that if there is already a session with the IdP, all of this is seamless for the user. A bunch of redirects take place, but the user will just reach the application without entering credentials.
So the short answer to your question is that your external applications need to support SAML SSO and need to be registered with the identity provider, in which case they can just use the IdP for authenticating the user and signing the claims it may have.

OAuth2 Provider with custom authentication

I am trying to implement a OAuth2 Provider, that authenticates users with a custom login.
For understanding I looked at the Spring Boot OAuth2 Tutorial.
I don't quite get, how I can implement my own Authentication meachnism to work with the OAuth2 SSO from my Server.
I want to add custom authentication mechanisms (like "user has to answer a question for authentication" or "user has to enter id and click button for authentication") instead of the Facebook and Github examples.
I read about implementing my own AuthenticationProvider, but I am stuck how to combine all the puzzle parts.
Let's go one step at a time. OAuth is only authz provider so not talk about authentication. Now for your usecase specifically, if you want user to be authenticated then OAuth authz code based flow makes sense (You can even go for implicit flow, check rfc 6749). Now how will this work for you. I am picking up the implicit flow for simplicity, Authz flow is just extension of it where end client gets a temporary code which it exchanges with Identity Server later to get the access token. Here are the steps:
Client App hits the /authorization uri with data as per rfc 6749
After validating the submitted data, server forwards user to Login page (or other page for authentication). After authentication, cookie is set in the browser or data is stored in server to mark a user as authenticated.
After authentication server redirects user to user consent page (You can even skip this if needed depending on need, But OAuth 2 spec contains this) where user specifies which all permissions (scopes) are allowed, here user can allow either allow or deny.
if user allows then these permissions are submitted to server and then server stores the data and redirects the user to client URI with access token in # fragement of client redirect URI (callback URI submitted during actual request)

In spring Oauth 2 authorization server Implementation , how to return an authorization code after user sign up

Normally ,the client redirect to Oauth server ,with client id
http://localhost:8181/sparklr2/oauth/authorize?response_type=code&client_id=tonr-with-redirect&state=xyz
the login page is displayed ,after proper credentials are received and authenticated ,confirmation is not call back done to client with authorization code
http://localhost:9090/tonr2/sparklr/redirect?code=gm4XN3&state=xyz
If the user is not registered and sign up need to be done ,then how to generate a authorization code after sign up with out login
I think this is a general question for Spring security, what you want is a login flow which supports signup and generates a complete authentication at the end of the signup flow.
So you will have to create a custom login form flow that offers signup and then completes the authentication at the end of the signup flow.
If you do this properly Spring oauth should take over and continue the redirect flow just as if you signed on the normal way.

Issue token to logged in user via spring

I have a Spring (3.2) based web app that a user can log into. The site will also provide an API secured via OAuth 2.0. My question then, is how do I go about generating a token for a logged in user?
The underlying idea here is that there will be a mobile app that opens up a web frame to the login page, which will eventually redirect to a url schema with an oauth token that the app will catch and then use for the api calls. Looking at the code for TokenEndpoint, I see that it defers token creation to a list of TokenGranter types. Should I be creating my own TokenGranter extended class, or am I looking at this all wrong?
I ended up writing a controller like this:
OAuthClientRequest request = OAuthClientRequest
.authorizationLocation(csOauthAuthorizeUrl)
.setClientId(csClientId)
.setRedirectURI(
UrlLocator.getBaseUrlBuilder().addSubpath(AUTH_CODE_HANDLER_URL).asUnEscapedString())
.setResponseType("code")
.buildQueryMessage();
UrlUtils.temporarilyRedirect(httpResponse, request.getLocationUri());
return null;
Then handling the code returned. My big problem here was that I had the /oauth/authorize endpoint set to use client credentials. Once I realized that tokens were being issued for the client ID instead of the user, it started to make sense.
So you want to use the Authorization Flow of OAuth. Spring has already support that, if you have configured the spring-security-oauth correctly, you just have to redirect the user/your mobile apps to /oauth/authorize?client_id=xxx&response_type=code this will redirect user to authorization page, if user has not login yet, it will redirect the user to login page then to the authorization page.
After the user completed the authorization process, it will redirect the user to an already registered redirect_url parameter with the authorization_code 'yourapp.com/callback?code=xxxx'.
Your application should exchange this authorization_code with the real token access to /oauth/token?grant_type=authorization_code&code=xxxx&client_id=xxxx&client_secret=xxxx
After that you will receive the token access that can be used to access the resource server.

Resources