SSO with CAS or OAuth? - security

I wonder if I should use the CAS protocol or OAuth + some authentication provider for single sign-on.
Example Scenario:
A User tries to access a protected resource, but is not authenticated.
The application redirects the user to the SSO server.
If beeing authenticated the user gets a token from the SSO server.
The SSO redirects to the original application.
The original application checks the token against the SSO server.
If the token is ok, access will be allowed and the application knows of the user id.
The user performs a log-out and is logged out from all connected application at the same time (single sign-out).
As far as I understand that is exactly what was CAS invented for. CAS clients have to implement the CAS protocol to use the authentication service. Now I'm wondering about to use CAS or OAuth at the client (consumer) site. Is OAuth a replacement for that part of CAS? Should OAuth as a new de-facto standard be preferred? Is there an easy to use (not Sun OpenSSO!) replacement for the authentication part of CAS supporting different methods like username/password, OpenID, TLS certifactes ...?
Context:
Different applications should rely on the authentication of the SSO server and should use something session-like.
The applications can be GUI web applications or (REST) serivces.
The SSO server must be provide a user id, which is necessary to get more information about the user like roles, email and so on from a central user information store.
Single Sign-out should be possible.
Most clients are written in Java or PHP.
I've just discovered WRAP, which could become the OAuth successor. It is a new protocol specified by Microsoft, Google and Yahoo.
Addendum
I've learned that OAuth was not designed for authentication even it could be used to implement SSO, but only together with a SSO service like OpenID.
OpenID seems to me to be the "new CAS". CAS has some features OpenID misses (like single sign-out), but it should not be to hard to add the missing parts in a particular scenario. I think OpenID has broad acceptance and it is better to integrate OpenID into applications or application servers. I know that CAS also supports OpenID, but I think CAS is dispensable with OpenID.

OpenID is not a 'successor' or 'substitute' for CAS, they're different, in intent and in implementation.
CAS centralizes authentication. Use it if you want all your (probably internal) applications to ask users to login to a single server (all applications are configured to point to a single CAS server).
OpenID decentralizes authentication. Use it if you want your application to accept users login to whatever authentication service they want (the user provides the OpenID server address - in fact, the 'username' is the server's URL).
None of the above handle authorization (without extensions and/or customization).
OAuth handles authorization, but it is not a substitute for the traditional 'USER_ROLES table' (user access). It handles authorization for third-parties.
For example, you want your application to integrate with Twitter: a user could allow it to tweet automatically when they update their data or post new content. You want to access some third-party service or resource on behalf of a user, without getting his password (which is obviously unsecure for the user). The application asks Twitter for access, the user authorizes it (through Twitter), and then the app may have access.
So, OAuth is not about Single Sign-On (nor a substitute for the CAS protocol). It is not about you controlling what the user can access. It is about letting the user to control how their resources may be accessed by third-parties. Two very different use-cases.
To the context you described, CAS is probably the right choice.
[updated]
That said, you can implement SSO with OAuth, if you consider the identity of the user as a secured resource. This is what 'Sign up with GitHub' and the likes do, basically. Probably not the original intent of the protocol, but it can be done. If you control the OAuth server, and restrict the apps to only authenticate with it, that's SSO.
No standard way to force logout, though (CAS has this feature).

I tend to think of it this way:
Use CAS if you control/own the user authentication system and need to support a heterogenous set of servers and apps that need centralized authentication.
Use OAuth if you want to support user authentication from systems that you don't own/support (ie Google, Facebook, etc).

OpenID is an authentication protocol, OAuth and OAuth WRAP are authorization protocols. They can be combined with the hybrid OpenID extension.
I'd strongly prefer to see people building on top of standards that have a lot of momentum (more available support, easier to get third parties involved), even if they aren't an exact fit for the application at hand. In this case, OAuth has the momentum, not CAS. You ought to be able to do all or at least nearly all of what you need to do with OAuth. At some later point in the future, OAuth WRAP should simplify things further (it makes some worthwhile trade-offs by using a bearer token and pushing encryption down to the protocol layer), but it's still in its infancy, and in the meantime, OAuth will probably do the job just fine.
Ultimately, if you choose to use OpenID and OAuth, there are more libraries for more languages available to you and to anyone else who needs to integrate with the system. You also have a lot more eyeballs looking at the protocols, making sure they really are as secure as they're supposed to be.

To me, the real difference between SSO and OAuth is grant, not authentication
because a server that implements OAuth obviously has authentication (you have to be logged in to your google, openId or facebook for OAuth to happen with the client app)
In SSO, a power user/sysadmin grants the final user access to an application beforehand on the "SSO app"
In OAuth, final user grants application access to his "data" on the "OAuth app"
I don't see why OAuth protocol couldn't be used as part of an SSO server. Just take out the grant screen from the flow and let the OAuth server lookup the grant from the backing db.

Old post, but this might be useful:
CAS 3.5 will support oAuth as Client and Server.
See: https://wiki.jasig.org/display/CASUM/OAuth

Related

Are there security standards like OAuth and OIDC but for regular API users (not 3rd party applications)?

I'm trying to secure an API with modern security practices (like refresh tokens with token rotation).
OAuth 2.0 is widely used, and when it comes to security I'd rather use a standard than role my own.
Is there are standard like OAuth 2.0, but for applications which do not have 3rd party consumers?
In our case, we're authenticating users via various SSO providers (Google, Facebook, etc) and registering their email with our API.
Currently we issue a token on each login with a long TTL, but I'd like to switch to a refresh token implementation.
A similar question was asked where the suggestion was to use OAuth as-is and treat the users as coming from a single application: using oauth for API without 3rd party
However, wouldn't the user have to authenticate our app to use our app? That seems counter-intuitive, so I assume I'm missing something.
Also, I'm implementing this in Spring.
Thank You!
I'm not sure about what you mean by "not 3rd party application". Have you considered using an (OpenID) authorization-server with user identity federation features?
Such an authorization-server would be a proxy for the various identity providers: "social" ones (Google, Facebook, etc.) but also corporate ones, if needed (LDAP or plain user DB). Keycloak, for instance does that pretty well and can be easily installed along with your other services ("in house").
UI applications would be configured as regular OpenID clients, using your authorization-server as only identity (and access-tokens) provider. There are great client libs out there to handle that in the framework you use (mobile, Angular, React, etc.)
redirects out to the authorization-server and then back in
tokens refreshing
URIs for which an Authorization header should be attached to the requests
...
Spring applications exposing the API would be configured as regular OAuth2 resource-servers, using your authorization-server as only access-token issuer.

Is Oauth2.0 appropriate for first-party apps?

I am developing a SPA application in angular and I have a lot of confusion about the correct way to implement authentication and authorization.
First of all, the application is a first-party app, which means that I am developing both the authorization server and resource servers.
The users that logs in the application must have full access to their resources on the platform.
So, I am doing it using OAuth2.0 and I have a couple of doubts about the domain of the protocol as well as security concerns.
First question:
The first question is if OAuth should be actually used to authorize first party applications. From my understanding this is a delegation protocol used to grant a third-party application controlled access to the user's resources on the platform, upon user consent. How does this fit in the context of a first-party app? In that case the app should get an access token with a scope that allows full access, right?
Second question:
Since this is a Single Page Application I couldn't store a secret on client side. So I am opting for using the authorization code grant with PKCE which would seem to be appropriate to manage this scenario. In this case I wouldn't ask for a refresh token but I would only retrieve the access token and using silent check to refresh it. I do not want to have refresh token insecurely stored on the browser. Is this PKCE really secure? The secret is generated dynamically but a attacker could eventually create a system using the same public client id and managing the PKCE properly, and finally get an access token that, in my case, gives full access to the users resources.
I could in the future allow controlled access to my app's resources to third party app, that's also one of the reason why I stick with OAuth.
The first question is if OAuth should be actually used to authorize first party applications. From my understanding this is a delegation protocol used to grant a third-party application controlled access to the user's resources on the platform, upon user consent. How does this fit in the context of a first-party app? In that case the app should get an access token with a scope that allows full access, right?
Yes, this makes sense to me. We skip the 'grant permissions' step for our own apps.
Is this PKCE really secure?
Yes, even without PKCE, authorization_code is pretty secure. Adding PKCE solves a a few potential security issues, but I would be somewhat inclined to call them edge cases. It is definitely right now the recommended choice.
The PKCE rfc has more information about the motivations behind PKCE:
https://www.rfc-editor.org/rfc/rfc7636#section-1
I actually came here looking for the answer to Question 1. My take is that in situations where we have no third party apps requiring access to our APIs we do not need OAuth. If we still need to use OAuth, then we can use Resource Owner Password Flow for first party apps. I have not seen any convincing answer anywhere confirming or rejecting this opinion but this is purely based on my understanding of OAuth.
Now, I am mainly writing this to answer Question 2. PKCE protocol is secure and attacker would not get token in this scenario. The reason is that the Authorization Server uses pre-registered "Redirect Uri" to send the token to. To be precise, the Auth Server would simply ask the browser to redirect user to "Redirect Uri appended with Access Token". Browsers do not allow javascript interception of Redirection requests. Therefore, an attacker would not be able to get hold of the token and the user will be redirected from attacker's site to yours at the end.

How to secure an API when the consumer uses claims authentication

Background
I'm building a .NET MVC enterprise web application that must have the ability to authenticate users from different companies. One of the major requirements was to ensure that users don't need to create and remember new credentials to use the application, instead they should continue to use whatever credentials they use to access applications within their company intranet.
Since the application will be hosted on the extranet and needs to handle authenticating against multiple domains (i.e. multiple Active Directories), we are expecting each client to set up a security token service (AD FS) that the application can interface with to implement claims authentication.
The MVC application will check if the user is authenticated, and if not, start the workflow that ends with the MVC application being given a SAML claim being associated with the user.
Problem
At this point, the user is authenticated and given access to the MVC application. However, the application itself is a modern day web application that uses quite a bit of JavaScript to consume a .NET Web API that handles most of the business logic. My main question is how I can secure this API. I want to make sure the only requests being sent to this server are being sent from a valid source, and that the user consuming the service has permissions to do so.
Current Solutions
There are two approaches I can take to consume the API:
Straight from JavaScript (Preferred solution)
Route the request through the MVC server, which will then forward it to the API.
In order to pick an approach, I first need to find a way to secure the API.
HMAC Authentication
The most straight forward solution I've found is HMAC Authentication - http://bitoftech.net/2014/12/15/secure-asp-net-web-api-using-api-key-authentication-hmac-authentication/. However, this approach requires all API requests to come directly from the MVC server, since the secret key will need to sit on the MVC server.
OAuth 2.0
The second approach I can implement is some flavor of OAuth 2.0. The flavors I'm familiar with can be found here http://alexbilbie.com/guide-to-oauth-2-grants/:
Authorization Code
Implicit
Resource owner credentials
Client credentials
Authorization Code Grant
This is not the approach that I want to take. The MVC application has already received claims for the user - they shouldn't have to do it again just because the API needs the claim. (I have a followup question asking if I can simply pass the claim to the API server)
Implicit Grant
I like the way this approach sounds, since I will be able to execute API requests in the client (i.e. JavaScript code), however it suffers from the same problem as the first approach.
Resource Owner Credentials Grant
This approach is out of the question - I don't want either the MVC application or the API to ever hold onto the user's credentials.
Client Credentials Grant
This approach is the only reasonable OAuth approach listed - however I fail to see a major difference between this approach and HMAC authentication detailed above.
Questions
Have I correctly set up the MVC application's authentication structure? Specifically, in this context is it appropriate to have AD FS handle authentication and respond with SAML tokens representing user claims?
I plan to store user data in the server's session. Can I also store the user's claim in the session, and then somehow send that up to the API for authentication?
If I can pass the claim from the MVC server to the API server, and the API server can correctly authenticate the request, is it safe to pass the claim to the client (browser / JS code) so that consuming the API can bypass the MVC server?
Is the HMAC Authentication approach the best way to go?
Yes, using ADFS or any IdP products as an IdP for your application is a good way to implement SSO. Doing this way help you delegate all the federated access management as well as claim rules to ADFS.
Yes, you can store claims in session and somehow send them to the WebAPI. Please note that if you are using WIF, it already stores claims in Thread.CurrentPrincipal as a ClaimsPrincipal object. Another thing is that I assume you only want to somehow send the claims only, not the whole SAML2 token.
I would say it is as safe as the mechanism you use to protect the token on the client side. Check https://auth0.com/blog/ten-things-you-should-know-about-tokens-and-cookies/ and https://security.stackexchange.com/questions/80727/best-place-to-store-authentication-tokens-client-side for more details.
I can't say if it is best for you, but it seems to be a viable way, given that you have control over the WebAPI too. However, it also seems that using JWT token would be easier: https://vosseburchttechblog.azurewebsites.net/index.php/2015/09/19/generating-and-consuming-json-web-tokens-with-net/. Talking about JWT token, you can also ask ADFS to issue it for you: https://blogs.technet.microsoft.com/maheshu/2015/05/26/json-web-token-jwt-support-in-adfs/.

OAuth authentication client side security issues

I understand the security issues around attempting to use OAuth for authentication from a provider's point of view. However I've been asked to provide users the facility to log on to a new web application using OAuth and obtain their basic identity info from the likes of Google and Twitter, from which a new user account within the client application will be created. Additionally users will be able to regster/login directly via user/passwords for anyone not wishing to use third party accounts.
We do not require any access to the user's details/info or providers APIs, just their basic identity when they first logon, and of course allow them to login via the provider in the future. Not exactly the use case OAuth is intended for, OpenId would have been preferred, but OAuth has been specified and without valid concerns would need to be adhered to.
My question is how safe is it to assume that the user has correctly authenticated themselves with the relevant provider. If I trust say Google to perform adequate authentication and I obtain an access token and their identity, presumably I can consider that a legitimate user? There are obviously issues if some one has access to the resource owners machine and saved passwords in the browser but that issue is present for those users who elect to register directly.
Presumably it possible to fake an access token, e.g. man in the middle pretending to be google? A MITM could fake an access token and supply identity details that matched a registered user's google id? I don't see anything for a client to know that the information definitely came from the provider. Obviously this problem is not unique to OAuth.
Are there another ways someone could illegitimately access an account that used OAuth to authenticate themselves.
OAuth allows that an application to access a specific user resource (that has been provided permission by the user) and it cannot go outside that scope. I have not seen the documentation that refers to creating a new user using OAuth based application.
That being said:
We do not require any access to the user's details/info or providers
APIs, just their basic identity when they first logon
This violates OAuth authorization process. The Service Provider does the authentication and provides the relevant tokens (based on the success of the authentication). This is to ensure that there are no 3rd party authentication done during the OAuth authentication process.
My question is how safe is it to assume that the user has correctly
authenticated themselves with the relevant provider.
This all depends on the service provider itself. To conform to OAuth protocol, one of the requirement is that user authentication must be done in a secured transport layer with a digital certificate (for HTTP, it must be done in HTTPS). OAuth consumer don't have any reference to the authentication process. Also the authentication process basically asks the user if the consumer can access the resource of the specific user (and not anyone else, since he doesn't have authorization to it).
Is it possible to fake an access token, e.g. man in the middle
pretending to be google?
Spoofing a Service Provider IS possible but it'll be tedious. For one, you will have to create a whole OAuth handshake process, create the exact API as the service provider, also setup an environment that is secured (as OAuth recommends). The only thing the spoofing service provider can obtain is the client credentials. If it has its user credentials, there is no need to use the application as there is no way of providing a user credentials using an application to do malicious damage.
Secondly, access tokens do expire so even if you spoof and retrieve an access token, the original application owner can ask for the service provider to block the application and the access token can be useless.
A man in the middle attack won't be possible. You will have to replicate the service provider in a sense that the end user won't be able to distinguish between the original and the spoofing service provider in order to capture all relevant credentials (from both the application and end user).
Sadly saying, the scenario from your last sentence is the truth.
But you should realise that the security is a huge and complex issue, especially in client side. It's not happen just in a single point but many points through the whole internet access life cycle. The scenario you given is not what OAuth try to solve.

Why should I use OpenID for Authentication rather than OAuth?

I've read repeatedly that OpenID is better for authentication than OAuth (which is for authorization), including several other posts on SO.
The case also seems to be made in this often-cited article.
However, I'm a bit unclear on why I should favor OpenID for authentication, vs. an honest OAuth provider (e.g. Twitter or Facebook OAuth 2.0). The other SO posts I've read explain the different use-cases, and I understand the difference between what the protocols are designed to do, but they don't explain why one could not use OAuth to authenticate.
Here are the reasons I can come up with and my (perhaps misguided) repsonses:
OAuth is really for Authorization. Having users authenticate using OAuth gives a consumer more privilege than they need.
Response: This is generally true, but is far more limited in the case of fine-grained OAuth (such as Facebook provides) that allows me to only request very minimal permissions. In fact, many sites such as Facebook provide OAuth, but not OpenID, presumably because they are more interested in authorizing consumers than authenticating clients. If I want to provide clients with more authentication options, OAuth seems to give that to me.
OAuth sessions tend to live longer
Response: Not relevant if I'm a consumer intent on authenticating clients; I'll do my own session management and could even get rid of the OAuth tokens immediately as soon as I'm done authenticating my users.
What authentication advantages does OpenID provide compared to using large-scale OAuth providers for authentication?
The main question you need to ask yourself is if you know ahead of time which providers you want to support. If you want to allow users to use any provider they way (with OpenID support such as Google, Yahoo, AOL, etc.), you should use OpenID. But if you know most of your users will want to use Twitter, Facebook, or one of the other popular OAuth providers, use those.
The technical terminology is that OAuth provides delegated authentication while OpenID provides federated authentication. Now, it is true that OAuth is an authorization protocol and not an authentication protocol, but by providing you with /me (Facebook) or /account/verify_credentials (Twitter), these providers extended OAuth for use as an authentication protocol.
But you shouldn't use OpenID. It's a dead protocol.
The fundamental challenge with using OAuth for authentication is that you would need to assume ones identity based on access to a given resource. In some cases, this may be a valid assumption, but OAuth does not guarantee it. If access to the resource you are using for authentication is delegated to another party, and you are presuming an identity based on access to that resource, then that is a vulnerability that can allow an imposter to authenticate on another subscriber's behalf. This has nothing to do with the OAuth provider's honesty or lack thereof, and everything to do with a tool being used in a manner for which it was not designed.
In the case of Facebook, OAuth can support authentication predicated on only the subscriber being able to authorize the application: if you receive authorization to access an individual's profile, it means the subscriber must have authenticated to Facebook. It appears this is a supported use case. However, if Facebook later allows, for instance, other applications or users to authorize resources on behalf of its subscribers, then that guarantee is lost.
Ultimately, to use OAuth for authentication, you need to make a lot of assumptions. You need to assume that the user you are authenticating and only that user have access to delegate a given resource; you have to assume that the request data you receive is sufficient to bind to a known identity; you have to assume that the authentication mechanism was sufficient for authentication to a third party (what if the file wasn't sensitive and anonymous access could be granted?); and you have to assume that these qualities are persistent over time. OpenID is built specifically for this; OAuth is not.
Can you safely make these assumptions? In the case of Facebook, possibly; they appear to be documented and supported use cases (I'm not familiar with the specific API). But generally, it's not a supported OAuth use case.

Resources