I'm building a new application platform using Microservice Architecture but I've been reading alot about different kinds of Authentication/Authorization to use.
I'm settling for OAuth2/OpenID Connect but just to make sure my assumptions is right.
I like to know if my flow is right to handle the authentication/authorization of my application.
Secondly, for my trusted Apps, how can I prevent OAuth from asking user for consent ?
In terms of protocols/standards, going with OAuth 2.0 and OpenID Connect for a system like the one you described is the right decision. They are in active use, have plenty of library and third-party providers support and they were also designed taking in the consideration the heavy reliance on HTTP that present day systems exhibit.
In terms of choosing the correct flow for each application the decision is not influenced by the application being perceived as a third-party or trusted application; it's more about the deployment characteristics of the application and also if the applications wants to access resources on behalf of an end-user or on behalf of the application itself.
Check Auth0 - Which OAuth 2.0 flow should I use? for a good illustration of this decision process.
The distinction between third-party application and trusted application is something left at the discretion of the identity provider/authorization server. This is usually supported so that consent is not explicitly asked to an end-user if the application is trusted; in these cases flagging an application to skip end-user consent is seen as an administration step where someone unilaterally and administratively decides that consent was granted to this application and as such it's not necessary to ask for it to end-users.
If you do indeed decide to support administrative consent for some application have in mind that if the characteristics of these applications don't allow them to be confidential clients (support a secure mechanism to authenticate the client application itself) or have some other way to ensure the client identity then an hostile application may try to fake a trusted application in order to skip the user consent step.
Related
I'm building an OIDC/OAuth server that will provide an SDK much like sign in with Google to be an IDP for mobile apps. We are wondering the risks of deviating from the protocol to simplify the flow.
The flow would be like this:
OIDC Server is setup for company A.
User opens app from company B, using company A OIDC SDK, and enters email
Pin challenge sent to email
Pin entered in app, screen shows consent prompt
On ok, app gets ID + Auth token for user
The token accessible to the app is only scoped to a limited set of resources accessible to the app and can be revoked by the user at any time.
This cuts out a few steps from the normal PKCE+Auth code flow, and I’m having a hard time articulating why this may be worse for security (besides not following a widely accepted standard).
Standards around security are created so that common attack vectors can be more easily mitigated. If you don't follow the standard you will have to make sure yourself that you're meeting security requirements of your product/company.
It's hard to tell from that simple description whether your app will be vulnerable or not. E.g. in point 4 - how do you make sure that the app which sends the OK to consent is the one which asked for the consent in the first place? How do you make sure that the auth token is delivered to the appropriate app? What will be the TTL of such a token? How will you refresh it? What is your plan for a situation when the token gets stolen or intercepted, etc. These are all things which you will have covered if you follow OIDC or OAuth standards and their security recommendations. When you start inventing new ways to guard yourself from those threats, you might end up creating something similar to the standards anyway.
Also, if you implement standard flows, it will be easier for you to change your own OAuth Server to a product available on the market, should that become a necesity.
There is a standardised OAuth 2.0 extension that somewhat resembles your approach, defined in RFC 8628 https://datatracker.ietf.org/doc/html/rfc8628 "OAuth 2.0 Device Authorization Grant".
A few remarks about your flow:
it seems to imply that the ability to read e-mail equals user authentication i.e. the e-mail provider is the authentication provider; that may not be applicable in general
the spec warns that this approach should not be used to replace vanilla browser-based SSO on mobile devices that do have a browser mostly because of loss of flexibility and it results in a more cumbersome user experience
I don't think there are immediate or more security concern than the ones mentioned in RFC 8628 (https://datatracker.ietf.org/doc/html/rfc8628#section-5), but as mentioned before, you'd be on your own to find support in SDKs, apps and OPs when not following the standard
We're building an iOS native app together with two web apps. For identiy/access management we are using Keycloak (supports OpenID Connect and OAuth 2.0).
The iOS apps are installed on MDM managed devices. Only our apps are installed.
I learnt that the current best practice for implementing authentication/authorization is to use OpenId Connect and a browser based flow through an external user agent:
http://lists.jboss.org/pipermail/keycloak-dev/2016-May/007259.html
https://www.rfc-editor.org/rfc/rfc8252.txt
https://auth0.com/blog/oauth-2-best-practices-for-native-apps/
using one of these libraries:
https://github.com/openid/AppAuth-iOS
https://github.com/aerogear/aerogear-ios-oauth2
Is it also recommended for MDM managed iOS devices (with no "evil" third party apps, just our own stuff) to implement a browser based flow? Or is it safe in this case to implement a native login flow (user enters credentials directly into the app)?
I am worried about the user experience... That switch between our app and the browser does not look very smooth...
There is an RFC about OAuth2 for native apps. It's worth reading - it discusses possible implementations and security risks involved. The general recommended way is to use the authorization code flow in a browser (not an internal application component), because this way the application cannot get the user credentials. People use to trust the browser and the authentication provider more than other apps, so the visibility of URL and the verified SSL certificate is important too.
The RFC covers also the iOS implementation details:
Apps can initiate an authorization request in the browser, without the
user leaving the app, through the "SFSafariViewController" class or
its successor "SFAuthenticationSession", which implement the in- app
browser tab pattern. Safari can be used to handle requests on old
versions of iOS without in-app browser tab functionality.
So if you use the SFAuthenticationSession you don't need to open a new Safari window and the user experience should not suffer.
If you use the Resource Owner Password Credentials grant (users enter their credentials into your application directly), you will make it less secure for the same reasons - the credentials get exposed to the application. And using this grant, you cannot use the third party authentication providers in Keycloak (Google, Facebook).
It's up to you (and your organization) how much secure you want the system to be, so you can opt for some compromises, but I would rather stick to the current best practices, since the app may grow later the compromises may turn to problems.
We have a bunch of websites under re-built and few mobile apps under development. We are looking for a Identity Manager / Server that can be used for authentication and authorisation of the users logging into those portals and apps. I did some a brief research but could't find the answer to my questions below:
Does't MIM support OAuth2 / OpenId Connect based authentication protocol?
Can we create user profile and add users claims in it?
Does it have APIs that portals can call to add users into the user storage?
Does it provide API endpoints for change password and forgot password to add self serve password recovery feature on the portals?
I am a developer and have little knowledge about active directory and identity management area.
I was in the same boat you are in, and was trying to decide between MIM and Red Hat Keycloak. I ended up going with Keycloak, it is powerful yet easy to setup, configure, and manage, whereas MIM is a pain in the neck to setup.
It sounds like you are looking for a single signon or federation solution, if that's the case MIM won't be able to help you. MIM is designed to synchronise user accounts from an authoritative source and maintain them in other connected systems (typically HR to AD).
The equivalent product to Keycloak in the Microsoft space would be ADFS (Active Directory Federation Services) or Azure AD.
Before you put me down for asking too basic a question without doing any homework, I'd like to say that I have been doing a lot of reading on these topics, but I'm still confused.
My needs seem simple enough. At my company, we have a bunch of Ruby on Rails applications. I want to build an SSO authentication service which all those applications should use.
Trying to do some research on how to go about doing this, I read about CAS, SAML and OAuth2. (I know that the "Auth" in OAuth stands for authorization, and not authentication, but I read enough articles saying how OAuth can be used for authentication just fine - this is one of them.)
Could someone tell me in simple terms what these 3 are? Are they alternatives (competing)? Is it even right to be comparing them?
And there are so many gems which all seem to be saying very similar stuff:
https://github.com/rubycas/rubycas-server and https://github.com/rubycas/rubycas-client
https://github.com/nbudin/devise_cas_authenticatable
https://github.com/onelogin/ruby-saml
CASino and https://github.com/rbCAS/casino-activerecord_authenticator
And I am sure there are hundreds of OAuth related gems.
I just want a separate Rails application which handles all the authentication for my other Rails apps.
Note: I do not want to allow users to use their Google / Facebook accounts to login. Our users already have accounts on our site. I want them to be able to login using that account once and be able to access all our apps without signing in again. Signing out in any app should sign them out of all apps.
UPDATE
I have come across these two OAuth solutions:
http://dev.mikamai.com/post/110722727899/oauth2-on-rails
http://blog.yorkxin.org/posts/2013/11/05/oauth2-tutorial-grape-api-doorkeeper-en/
They seem to be describing something very similar to what I want. But I haven't found any guide / blog post / tutorial showing how to do this with SAML / CAS.
Suggestions welcome.
UPDATE 2
More details about our use-case.
We do not have any existing SAML architecture in place. Primarily, it is going to be OUR users (registered directly on our website) who are going to be accessing all our applications. In the future, we may have third-party (partner) companies calling our APIs. We may also have users from these third-party (partner) companies (registered on their websites) accessing our apps.
CAS-Server:
A stand-alone central login page where the user enters their credentials (i.e. their username and password).
CAS supports the standardized SAML 1.1 protocol primarily to support
attribute release to clients and single sign-out.
(a table in a SQL database, ActiveDirectory/LDAP, Google accounts, etc.)
Full compatibility with the open, multi-platform CAS protocol (CAS clients are implemented for a wide range of platforms, including PHP, various Java frameworks, .NET, Zope, etc.)
Multi-language localization -- RubyCAS-Server automatically detects the user's preferred language and presents the appropriate interface.
SAML :
Security Assertion Markup Language is an XML-based, open-standard data format for exchanging authentication and authorization data between parties, in particular, between an identity provider and a service provider.
SAML authorization is a two step process and you are expected to implement support for both.
OAuth 2.0:
The OAuth 2.0 authorization framework enables a third-party
application to obtain limited access to an HTTP service, either on
behalf of a resource owner by orchestrating an approval interaction
between the resource owner and the HTTP service, or by allowing the
third-party application to obtain access on its own behalf.
Important Note :
SAML has one feature that OAuth2 lacks: the SAML token contains the user identity information (because of signing). With OAuth2, you don't get that out of the box, and instead, the Resource Server needs to make an additional round trip to validate the token with the Authorization Server.
On the other hand, with OAuth2 you can invalidate an access token on the Authorization Server, and disable it from further access to the Resource Server.
Both approaches have nice features and both will work for SSO. We have proved out both concepts in multiple languages and various kinds of applications. At the end of the day OAuth2 seems to be a better fit for our needs (since there isn't an existing SAML infrastructure in place to utilize).
OAuth2 provides a simpler and more standardized solution which covers
all of our current needs and avoids the use of workarounds for
interoperability with native applications.
When should I use which?
1.If your usecase involves SSO (when at least one actor or participant is an enterprise), then use SAML.
2.If your usecase involves providing access (temporarily or permanent) to resources (such as accounts, pictures, files etc), then use OAuth.
3.If you need to provide access to a partner or customer application to your portal, then use SAML.
4.If your usecase requires a centralized identity source, then use SAML (Identity provider).
5.If your usecase involves mobile devices, then OAuth2 with some form of Bearer Tokens is appropriate.
Reference 1,Reference 2,Reference 3
If you need to authenticate for LDAP or ActiveDirectory then a solution like one of the CAS gems you mentioned above is right for you (RubyCAS, CASino).
If you can afford it, one of the commercial vendors (like Okta) is your best option because they will stay on top of security patches and manage your authentication needs for you. In particular, if you have to support ActiveDirectory, they've already implemented it.
OAuth is most useful for third party authentication, though it can do SSO. So if you wanted to support Google / Facebook logins or be a third party authenticator then it's a great choice. Since you don't want to support Google / Facebook then OAuth is probably not what you want.
If you are only intending to use HTTP POST for your SSO needs then the ruby-saml gem could be the way to go. You would have to implement your own Identity provider and add a service provider component to all your websites (possibly in the form of a gem.) Part of what you would need is a rails api to act as your identity provider. This gem helps support writing API's in rails.
EDIT
You mention the possibility that future third party users might be logging on to your site. This changes your calculus away from rolling your own ruby-saml solution.
The best way to share your authentication API is to implement an OAuth layer. Doorkeeper is a popular solution and is fast becoming the standard for Rails authentication. It's community support, flexibility and ease of use make it the best way to go for a consumable authentication API.
Railscast for implementing doorkeeper
Anjan.
I've used CAS and OAuth in my work. Here are some of my opinions, and hope to help.
Basically
Both CAS and SAML aim to solve SSO situation. And CAS is a service or an authentication system, which can support SAML protocol.
OAuth aims to solve authorization and authentication.
And in practice,
Both CAS and SAML act as an gateway in front of a group of applications which belong to one organization. Just like your case.
OAuth is used to authorize and authenticate between different organizations.
Just my thoughts, and hope to hear more voices.
We have used CAS and SAML in our architecture (Mobile App, Online Portal, and MicroServices) and both are used for different purpose.
Our Online Portal is like online banking that runs in public domain and has to be secure. We don't want to store password and other secure token's in the DB of the online portal, therefore, we use CAS for authentication and authorization. During registration, when user chooses the password, we store the password in CAS and store corresponding token in the DB of Portal
When user login next time, User enters the user name and password in Portal. Portal fetches the token corresponding to user from DB and sends User_name, password, and token to CAS for validation.
But, in case user has already logged in into one application and we redirect user to our another application then we dont want to user to enter username and password again for second application. We use SAML to solve this. First application shares user details with SAML server and gets token in return. First application passes the token to second application. Second application sends token to SAML server to get user details and on success lands user to desired page. Our first application can be Mobile App and second can be Portal in the scenario of App2Web.
Since you have got lot of answers for this question, I would like to suggest you an identity product that can be cater these kind of all protocol in one hand with lot of authentication and user management features. You can just try WSO2 Identity Server version for this.
This is more of a general question but I hope it is still valid for SO.
So far I have learned, that in general, a mobile app (such as official Pinterest app) use the Password credential flow to let their users login and access the API directly. (let's just assume they use OAuth for this)
So they collect username and password, send it to their server and get a token in return which is used for subsequent requests.
Now a user did not want to register and created an account using e.g. Facebook as the authorization server. So my question is:
How is this flow implemented?
My educated guess:
User chooses "Login with Facebook" in mobile app
Facebook Login Page opens with return_uri = mobile app
Mobile app receives auth token
Mobile app uses client credentials and says the API: Use this token for user X
Is this correct?
First of all, apps should not use the Password Credentials Grant. The specification is rather clear about it:
In the traditional client-server authentication model, the client
requests an access-restricted resource (protected resource) on the
server by authenticating with the server using the resource owner's
credentials. In order to provide third-party applications access to
restricted resources, the resource owner shares its credentials with
the third party. This creates several problems and limitations
The specification then goes on describing those problems.
And about the Resource Owner Password Credentials Grant:
The authorization server should take special care when enabling this grant type and only allow it when other flows are not viable.
The entire purpose of OAuth 2.0, I to not have to use something like the Password Credentials Grant, where the user hands over their password to the application.
About your second question: what happens when a user does not want to register and create an account with your app, but wants to use e.g. Facebook for authentication?
Remember that both the Implicit Grant, as well as the Authorization Code Grant, work by using a browser control to authenticate the user. In that browser session with the Authorization Server, you are free to authenticate your user in any which way you want. Certainly, you can use your own user/password database, but you could also use other mechanisms, such as WS-Federation. In your case, it sounds like the user want to authenticate using Facebook.
Authenticating using Facebook is then not done by your client app, but by your Authorization Server. It typically does that by using the Facebook Authorization Code Grant, followed by a call to read the user's profile to obtain their Facebook user id, name, and so on.
If you do not want to build such an Authorization server yourself, you can use an existing one. Several companies offer login-as-a-service solutions, including the one I work for.
UPDATE: You asked several follow up questions in a comment below. I'll answer them briefly here:
First of all, the fact that some companies that use OAuth to secure their services allow for a Password Credentials Grant, does not imply that you should. In fact, there are probably more examples of companies that don't offer this possibility, than companies that do.
There are real trust issues, and real security risks with sharing your password with a device app. To start with, the app on the device is easier to hack than a server. Furthermore, if you give the app your password, presumably that app also needs to store it somewhere for future use. As a user, I just have to hope that that storage is safe form possible malware running on my machine. For more issues, see the introduction in the OAuth 2.0 specification mentioned above.
Secondly, all good Authorization Servers differentiate between First Party Clients and Third Party Clients. A First Party Client such as yours is controlled by the same company that controls the Authorization Server, and for such an app the Authorization Server does not ask for user permission to share data, since it makes no sense to talk about sharing data with yourself. That is why the web sites of these companies don't ask you whether you allow to share the data they hold on your behalf with them. They already have it, and there is no "sharing" going on.
Of course, you might argue that you have never seen any of these companies talking about this distinction between First Party Clients and Third Party Clients. But the reason they don't should be obvious: when you deal with them, you are always a Third Party App. They don't need to tell you that they treat themselves differently.
The mechanism I would choose in your scenario depends on the nature of the client app, and the nature of the services it accesses. What are your requirements?
Anyway, if the device the application is running on has a secure storage facility, such as Windows Phone 8.1, I would probably consider using the Authorization Code Grant without client credentials. That way, the user never has to log in again. If we're talking about a web site or a SPA, I would consider the Implicit Grant (where the "remember me" feature, if any, is offered by the Authorization Server). Again, the specification gives advantages and disadvantages of each grant type for several scenario's.