Accoriding to the Spring SAML Extension document :
Local logout terminates only the local session and doesn't affect neither session at IDP, nor sessions at other SPs where user logged in using single sign-on. Local logout can be initialized at scheme://server:port/contextPath/saml/logout?local=true.
For global logout, we have to hit the scheme://server:port/contextPath/saml/logout URL, but for me, it only logs out from the local session, but doesn't logout from the IDP.
This is the [WebSecurityConfig] (https://github.com/vdenotaris/spring-boot-security-saml-sample/blob/master/src/main/java/com/vdenotaris/spring/boot/security/saml/web/config/WebSecurityConfig.java) , that I'm using to create the SAML SP.
My question is, am I doing something wrong here? or is this a problem because of the IDP I'm using (can't mention the IDP as it's one of my firm's SAML SSO).
Or do I have to define any global logout handler here? If yes, How?
Global Logout in case of Single Sign On (SSO) needs support from both the service providers (SP) as well as the Identity Providers (IdP). What you are doing is only enabling the Global Logout endpoint from the SP side which only ensures that the SP will generate a Global Logout request to itself & to the IdP (depending on the SAML profiles/bindings you are using), now how the IdP handles it depends on IdP as well.
In SSO a session at IdP, a session at SP and cookies at user-agent is set on login. To facilitate a single global logout there comes a gap between user expectations and technical limitations. I suggest you to read about SLO issues here: https://wiki.shibboleth.net/confluence/display/CONCEPT/SLOIssues
Shibboleth IdPv3 has provided partial support for Single Logout using both front-channeling (user-agent involved in sending logout to all SPs & IdP) as well as back-channeling (user-agent sends logout request to current SP & IdP, the IdP in turn sends logout request to all logged-in SPs). You can read how Shibboleth IdP v3.2.0 handles logout here: https://wiki.shibboleth.net/confluence/display/IDP30/LogoutConfiguration
I would check the IdP metadata that you have configured. It sounds like an endpoint specified is wrong so it's not receiving what it needs.
With that said, you ought to confirm whether there has been any activity on your IdP's logs regarding any form of logout. Consider DEBUG or TRACE level.
Related
Does ORY Hydra currently have a feature that verifies if a client is logged in via OpenID Connect? I notice there is an API to logout via front-channel
When a user revisits the identity provider, however, I have no way of knowing if they are currently logged in or not. They could delete their client-side HTTP cookies and then I am out of sync with Hydra. Meaning: Hydra has them as logged in, but I have them now as logged out. Also, in the event of a back-channel logout, I want to be able to query for this state.
Is there an API I am overlooking that allows me to know whether a client currently has an active OpenID Connect login via Hydra?
It appears as of right now the only thing one can do is redirect the user to the authorization endpoint since we have no way of knowing if they are authorized or not.
The following two tables that ship with Hydra seem to be the source of truth for the data I am after: hydra_oauth2_access and hydra_oauth2_authentication_session. Does it ever make sense to query those directly if there is no supported HTTP API out of the box to see if a user has an active authentication session?
Sending an authentication request via a redirect to the Provider including prompt=none addresses this use case: it will silently login and return new tokens if there's an ongoing SSO session at the Provider, it will return an error code login_required if not.
Notice there will never be explicit user interaction in both cases so this is convenient (and meant) to run in an hidden iframe.
LOGGED IN STATE
An OAuth client is most commonly a UI application with multiple users. Each user's logged in state is represented by an Authorization Server session cookie that neither the application or user have access to:
The Authorization Server (AS) issues an SSO cookie, to be stored in the system browser for the AS domain
Both Web UIs and Native UIs send it implicitly on subsequent requests, when they invoke the system browser
AUTHORIZATION REDIRECTS
When an OAuth UI redirects the user, it is generally unknown whether:
The user will be prompted to login
The user will be signed in silently (eg the user could have signed in to another app)
For a Web UI it is possible to send an authorization redirect on a hidden iframe with a prompt=none parameter. If the user needs to sign in a login_required error code will be returned. See my Silent Token Renewal Page for further details.
This is not fully reliable however, and has some browser issues in 2020. Also it may be unsuitable if you are using a different type of client.
FEDERATED LOGINS
In some setups the AS redirects further to an Identity Provider (IDP), and the user's login state is further influenced by an IDP session cookie.
There is no way for an app to get hold of the user's IDP login state, since the app only ever interacts with the AS.
IS THERE A USABILITY PROBLEM?
If so, post back and we can discuss further ...
I have to authenticate user either by saml or by database credentials depending on how user wishes to get authenticated .
I am stuck with two problems
1)I am receiving the saml response to the call back back url. I am not sure how to integrate it with devise.
2)I am not sure how to authenticate the user either by database or by saml response dynamically based on user choice.
Any suggestion would be really helpful
You will have to use a WebView to embed the logon page in your App.
If the user chooses Database logon you will have to challenge the user to submit their user name and password. Once the user is identified by your API, your business logic will be kicked in.
If the user chooses SAML login, it will be federated login and you will send the Authen Request to the Idp. The Idp page will be rendered in WebView within your app. Once the Idp will identify the user after logon process, they would redirect the page to the URL as specified in your Authen request for the attribute AssertionConsumerService. You will have to intercept the Request to extract the SAML token which you will have to eventually submit in a API service in your environment. The API service will have to do the token processing and will generate a User profile that is identical to the one generated by the database authentication.
I recently implemented SAML with Devise in my application, and found that the omniauth-saml gem is the quickest route to getting it to work. It will handle your callback flow, usage of the ruby-saml library, and all the other details that would be a pain to implement on your own. And if you need to handle an arbitrary number of SAML providers, omniauth-multi-provider-saml worked well for me.
we are implementing a Single Sign On process using WSO2 Identity Server. We have both Microsoft and Java web applications involved and we are facing a problem during the Single LogOut processing with Microsoft based web apps. The issue is related to session invalidation on Identity Provider initiated SLO.
This is the scenario:
WSO2 Identity Server with a single Identity Provider configured
an Asp.Net MVC application using ComponentSpace SAML2 assembly and Forms authentication marking controllers with the [Authorize] attribute to ensure that users are authenticated to access them.
the DEMO Java Web application provided by WSO2 to test SSO
The login process works fine. We get a session ID from WSO2 and the user is authenticated landing on WSO2 login form in the first app, and transparently in the sencond one.
In the Asp.Net webapp, when a successfull login occurs, we authenticate the user to access [Authorize] marked controllers calling FormsAuthentication.SetAuthCookie(userName, false); . When the user logout from one of the apps, WSO2 sends a SLO request to other partecipants on a configured URI. When this request is reveived by the Microsoft one, we call the FormsAuthentication.SignOut(); method but the session is not destroyed. If the user refresh the browser page its User.Authenticated property is still True so he can still access [Authorize] marked controllers. This makes sense in my opinion because the caller is WSO2 and not the user browser.
We performed some investigation in the code of the JAR provided by WSO2 for Java applications and it creates a filter on Tomcat implementing a singleton to store WSO2 Session ID relation with Session objects each time a success login operation occurs. When WSO2 request a SLO the filter gets WSO2 Session ID as parameter, accesses the singleton HashTable to retrieve the Session object and calls the Session.Invalidate() method of the session object. If the user refreshes the browser, he gets redirected to login page. We tryied to implement something similar on Asp.Net side but even if we get the Session object on server side and call the Session.Abandon() method nothing happens when the user refresh the browser. He is still marked as authenticated.
I am not very familiar with Cookies and I have the feeling that is something related to them.
Had anyone faced a similar issue?
Any advice or suggestion will be very appreciated.
Thanks
Calling FormsAuthentication.SignOut should clear the authentication cookie. I suggest capturing the HTTP flow and confirming whether the authentication cookie has been deleted. The default name for the authentication cookie is .ASPXAUTH. Alternatively it will be the name specified in your web.config's section. For example, forms name="mycookie" would rename the cookie to mycookie. You shouldn't have to delete the ASP.NET_SessionId session ID cookie.
I have a use case where a web application needs to let users authenticate in two different ways but using the same user data store (aka IDP) via SAML.
User's browser is redirected to IDP and redirected back with SAML assertion (aka WebSSO Profile).
User makes request to SP providing their credentials via Basic Authentication. SP would then need to send the user's credentials to the IDP and the IDP would provide an assertion all through a back channel (server to server).
I'm using Spring Security SAML extension. The sample application in Spring SAML contains both basic authentication with username and password and SAML-based authentication but the Basic Auth portion uses local accounts defined in the securityContext.xml file. I need to use the user accounts on the IDP. Is this possible? If so, how do I configure Spring SAML?
There is no standard SAML WebSSO mechanism which would allow SP to request assertion for a specific user by providing her credentials. You might want to look into WS-Trust standard which covers such use-cases using its Request security token methods (RST/RSTR calls). Another quite standardized way to do this is Client Credentials grant of OAuth 2.0. Both are out of scope for Spring SAML, but can be combined with it.
I'm using the Spring Security SAML extension for my SP. After a user is authenticated from the IDP, the SP uses some sort of method to allow subsequent calls to not have to be reauthenticated with the IDP. How is this done in the Spring Security SAML extension?
A related question:
Authenticating mobile users against SAML IDP
In the accepted answer from the above related question, the SP should create a token and pass it back to the client for future requests. I'm not seeing anything like this when watching the flow in Chrome's Network Tool. What should I be looking for?
Update 1: I'm coming to the conclusion that Spring SAML doesn't pass anything back to a browser in the form of a token. It must be keeping track of the user on the server side. Can I get confirmation on this? Is it possible to generate a token to pass back to the client in the case of a REST call?
Spring SAML is relaying on Spring Security for handling of user's authentication state. By default user state is stored in SecurityContext and Authentication objects which are put into user's HTTP Session (identified by secure cookie typically JSESSIONID which is passed to the browser). You'll be able to find all details related to this in the Spring Security documentation.
In case your user is calling REST APIs from browser where she authenticated, and the API is deployed together with the Spring Security application, the call will be providing same cookies as you would get for normal server calls and they will be authenticated using the same mechanism without need for any tokens.
In case you want to perform calls to a 3rd party REST API where you have not established a session or authenticated using other means, one way to secure such scenario is e.g. issue and use OAuth 2.0 Bearer tokens.
After the user is authenticated from the IDP, the IDP sends back a SAML assertion to the SP. The Spring Security SAML extension validates this assertion.
If the validation is successful, Spring Security establishes a user session, which is generally persisted through the cookie mechanism.
In the case of a REST service, your suggestion is basically what is done on OAuth-enabled REST services. The client sends an authorization token with each request.