Use Case
To minimize the need for users to perform Sing On I would like to run an active session for as long as possible.
The user does SSO and SP allows the user to have access until the point where IDP says - session (or account) is not active anymore.
SP would need to ask IDP - is session active for this user?
My question
Is the above possible and if so what is the best practice of implementing SP asking IDP of session (account) activity for a specific user?
As I imagine, after successful initial authentication SAML Response body would hold a session-token which can be stored against a user. The same session-token can be used to query IDP to understand if session (account) is still active. However what service would that be?
Any guidance much appreciated.
There's nothing in the SAML specification that you can use to query account status.
What you can do is use the isPassive flag on a SAML request to see if there's an ongoing SSO session at the user's IDP. You could ask the IDP to modify its behavior and return account status instead but that would be a one-to-one agreement outside of the standard.
The alternative is to use a backchannel call with a protocol like SCIM, see: https://www.rfc-editor.org/rfc/rfc7644#section-3.4.1, that would allow you to query the status of a users's account with a REST call. But of course that is a different protocol than SAML and something that must be supported by the IDP.
Related
As part of integrating with Okta using OIDC, I am trying to understand if we need to contact Okta to end the session when a user logs out in the app? I am able to login using Okta as an IdP and then logout from the app at which point logging in again requires contacting Okta again. So what is the real need for ending session when a user logs out?
Okta is best-placed to answer in their particular case - being the OP (OIDC Provider) that you're using, but at least in terms of invalidating your tokens - both potentially on their (backend) side, as well as orchestrating all that is required (as part of their possibly custom workflow/process) upon the client side too, so that both sides are fully aware of the log out having taken place; so yes, it's best to, for one (probable) reason or another.
I'm currently testing my SAML SP code against the SSOCircle IDP. The SP is currently set to timeout a login after 7200 seconds (2 hours); that is, if the user tries to authenticate 2 hours after they last did so, they need to enter their credentials into the IDP again, to get a new AuthnStatement that is within 2 hours before now.
However, the IDP has a different timeout. I'm not sure how long it is, but it's longer than 2 hours. What this means is that there's a window when the SP demands the user log in again, but the IDP will automatically use the same AuthnStatement anyway. This, of course, fails to validate. The way around this is for the user to manually go to SSOCircle and logout.
This seems awfully inconvenient. It would make more sense to me if the SP could redirect the user to re-enter their credentials at the IDP. But I have not seen anything in the documentation or online referring to this window. I can manually set WebSSOProfileConsumerImpl.maxAuthenticationAge to match the IDP, but seems like a flimsy bandage.
I assume that all IDPs would perform similarly in this regard. Is that correct? What should the SP be doing differently during this window?
I assume that all IDPs would perform similarly in this regard. Is that correct?
More or less, yes but this is not about how IdPs behave vs SPs. This is about the fact that the application session established by the SP is entirely separate from the SSO session established by the IdP. It's not about what should happen. It's about what you want to see. There are many scenarios where this use case proves annoying or great many others where this is perfectly acceptable. You need to decide what works for you.
What should the SP be doing differently during this window?
If you wish to force the IdP to re-ask for credentials and disregard its own session, you may want to tag the authentication request sent to use forcedAuthn=true. The IdP should then challenge the user, assuming it supports SAML forced authentication requests.
Client sends username and password to the server.
Server then checks if this user is authenticated.
If yes, the server returns an access token for the client...
Then user can use this access token to access protected resources...
The advantage here, is that we are not sending user info via API calls, and the access token will not last for long time, so hackers won't be able to find out user authentication info (user name and password), and if he finds out, the access token won't last long enough to do anything with it.
That's how I understand Laravel passport API security.
The confusing thing here, is that on first API call, user has to send user name and password, so hacker still have big chance to find out user info!!!
I know that there is something wrong with my understanding, and that's why I get confused, any explanation would be very appreciated.
There must be a way to prove your identity to authorization server, and one way is to provide username and password. The way you're gonna achieve communication between authorization server and your client application is totally up to you as long as it uses HTTP. As stated in RFC-6749:
This specification is designed for use with HTTP ([RFC2616]). The
use of OAuth over any protocol other than HTTP is out of scope.
Of course it's always advised to use HTTPS whenever possible. Just because HTTP is mentioned in document, doesn't mean HTTPS cannot be used because HTTPS is just encrypted version of HTTP.
Other thing I wanted to mention is that you don't need to provide username and password, there are several grant types where you can, for example, instead of username and password you can provide client_id and client_secret which is used in Client Credentials grant type.
If you are new to this I believe this all is little bit confusing for you. To summarize the purpose of OAuth2 to you (as far as I get it), is:
To separate role of the client (which can be browser, mobile etc.) from the resource owner (usually the owner of account). Why? Because if there is no separation, the client has access to user's sensitive data.
Imagine that the first point is secure enough for communication. But what happens if someone gets their hands on the session you have? They have access to all! This is why OAuth introduces scopes, where depending on the scope user has with provided access token has limited access to resources. Scope can be read, write, share etc. - this implementation is up to developer. So if someone gets their hands on your access token, because of scope they only have a limited access to resource.
These are one of my reasons, while RFC-6749 has better explanation:
Third-party applications are required to store the resource
owner's credentials for future use, typically a password in
clear-text.
Servers are required to support password authentication, despite
the security weaknesses inherent in passwords.
Third-party applications gain overly broad access to the resource
owner's protected resources, leaving resource owners without any
ability to restrict duration or access to a limited subset of
resources.
Resource owners cannot revoke access to an individual third party
without revoking access to all third parties, and must do so by
changing the third party's password.
Compromise of any third-party application results in compromise of
the end-user's password and all of the data protected by that
password.
To learn more about OAuth2, it's grant types and purposes, I recommend you to read this:
An Introduction to OAuth 2
Mentioned RFC-6749, even though it can be difficult to read because of technical writing.
Hope I clarified at least a small piece of blur.
My IdentityServer application is configured to use Google login. I am using OIDC. This question is about external claims.
At login time, my application has access to all of the claims Google sends back from the auth request. I can access them in my custom implementation of UserServiceBase in the method AuthenticateExternalAsync (via the context). I can even add them to the AuthenticateResult object so when GetProfileDataAsync gets executed after the user has accepted the consent, I can access them via the ProfileDataRequestContext.Subject.Claims list. But this is the last point they will be in memory.
If I do not save these claims in a database, how can I access them once the login process is over? I want to keep my id_token simple so I do not put claims (other than sub) in the token. So I need to call the /userinfo end point to get the claims, but by this point they are no longer in memory.
What is the cleanest way of getting these claims back? To be clear, I want to get the claims from Google when the user calls /userinfo and translate them to the claims naming convention of my application. (I do not want to store them in the id_token at login time if possible... as per OIDC spec)
Note: This question is similar to mine, but that does not address how to do it using IdentityServer3.
Yes, you will need some persistence mechanism for the claims from the external provider. You should already have this, as the subject claim that you are issuing from IdentityServer should be unique to your token service (and not the unique id google gives you).
I'm a little new to this and please bear with me if I ask dumb questions.
As what I know, session is something saved at server (either in file or in database), and client access it via sessionid saved in cookie. To keep user login information, we can simply put a 'logged_in' column and an 'expired' column in session file or session table.
As far as I know, Oauth2.0 is designed for third party client to access the server. The whole process is controlled by an access_token, which is quite similar to sessionid (at least from my knowledge).
So, here's my question, is it possible to use Oauth2.0 to completely replace session? I.e., even people are using the website designed by me (NOT third party website) to access my own server? So that I have a unified authorization framework for user accesses both from my own website and any thrid party website.
Is there any pros&cons of using session & oauth 2.0?
Lastly, how about mobile app? I know for third party mobile app, they normally use oauth to access the server (many websites provides oauth api). How about if I am going to write my own app for my own server (NOT third party)? Does Oauth 2.0 apply here too?
To summarize, my question is actually is, is Oauth 2.0 universal that can be used in all kinds of user authorization control situations from all kinds of devices?
Thank you very much.
Though both are short-living entities, session IDs and OAuth tokens are fundamentally different and used for distinct scenarios. A session is used to identify a user of a web application, thus related to the end user. An OAuth token is used to grant access to a third-party service to access a limited set of protected user resources (e.g. read user contact information or send a mail from the user account). Though the token refers to the granter (i.e. end user authorized the grant), the token related more to the third-party application.
To give you an analogous example: imagine that you have a safe at your bank (i.e. your protected resource). The session is your id for the bank: give it to someone else and he will be you, he can get everything from your safe. On the other hand, a token is a limited authorization to someone else to your safe: e.g. your approval that he can get 10$ from your safe while a security guard is watching.
As a summary, sessions and tokens are not interchangable.