How to correctly decouple SAML logic from Service Provider into its own authentication microservice - authentication

I'm trying to implement SSO with SAML 2.0 in a dynamic web app whose frontend and backend-for-frontend are outsourced and hence not maintained by my company. At the same time, this dashboard is to be used by external organizations so federation with SAML 2.0 is a requirement.
I've been reading a lot on SAML integrations but the vast majority of them involve making changes in the Service Provider itself (in other words, the web app) but, as I mentioned earlier, doing this would require making many changes in the outsourced codebase which – for business reasons – is a no go.
To avoid this, I would like to have an authentication service to handle as much SAML logic as possible. This way, we would be able to easily scale on the amount of identity providers and even SSO protocols in the future while minimizing the modifications on the frontends.
Find sketched sequence diagram here
After sketching the sequence diagram up, I realized I don't quite understand a few things yet:
Is the Service Provider receiving meaningful cookies once the Identity Provider successfully authenticates the user? If so, would it be wise to use them from the Service Provider and the Authentication Service to determine whether the user is authenticated or not?
If not, then the only possible way for a Service Provider to know whether a federated session is already established or not is to ask the Identity Provider every time, on each request it receives to a protected resource, right? Wouldn't this delay each request's response time too much?
Thank you!

Related

Microservice Authentication Architecture

I'm starting to write a few microservices that will have independent web clients, a centralized authentication and authorization service, and an organization service. The organization service will keep track of who belongs to what organization and what that organization has paid for. This will tell me who can access which web client and what parts of each individual microservice. I've only developed authentication using Devise in a single Rails monolith, so I'm exploring how to do it in a multi microservice and web client ecosystem. I've come up with this:
Web Client makes a request to a microservice and is denied because lack of session information sent in the request.
Web Client makes a login request to the Authentication service. The Authentication makes a request to the Organization service to see what organizations the user is a part of as well as the services paid for. The session info is stored in the Web Client for future use in requests.
Web Client makes a request to the Microservice. The Microservice validates the session information (from 2) against the Authentication service, which in turn reaches out to the Organization for the user's organizations and the organization's services. The response from Authentication is stored in the Microservice. The response back to the Web Client is granted if the two sets of session information match.
Web Client makes a request to the Microservice, including the session info (from 2). The Microservice validates the session info against the stored session info (from 3). The response back to the Web Client is granted if the two sets of session information match.
Is this the proper way to authenticate? Is there a better way to do it? Are there small tweaks I should make?
Additionally, should I treat Authentication from the Web Client to the Microservices differently than Authentication between Microservices?
Do yourself a huge favor, and don't try to invent this yourself. Many, many people have written a fully functional auth & auth system, and a few of them have done it right. Unless you are a security specialist (which you likely aren't if you are asking this question), use a framework.
Start by looking at OAuth 2.0 and OpenId Connect providers, it is the de-facto standard in distributed authentication. Whichever language/platform you are using, likely has an implementation that you can leverage out-of-the-box. This will dramatically speed you up, and will likely avoid all the things that you will be doing wrong in your implementation.
Here you are, ready out of the box, Identity Server based on Open ID and Auth2.0 that is all what you need.
welcome-to-identityserver4
If you were interested in the topic of Microservices Architecture the following links are a set of articles that published about microservices in code-project, you can read and comment on your questions if you like.
https://www.codeproject.com/Articles/1264113/Dive-into-Microservices-Architecture-Part-I
https://www.codeproject.com/Articles/1264113/Dive-into-Microservices-Architecture-Part-II
https://www.codeproject.com/Articles/1264113/Dive-into-Microservices-Architecture-Part-III

OAuth 2.0 service to service authentication and best practices

I have to deal with such type of auth flows:
Create auth flows for Web users;
In the same way deal with service to service authentication
Briefly following diagram can depict main components that we'll have:
For users Authentication we'd like to use OAuth2 (the Implicit Flow) and in general it looks more or less clear.
The question about service to service authorization can it be OAuth2 Authorization Code Flow used?
The main problem there that inside of datacenter1 it will be plenty of backend services that's why it will be good as services will work on the similar permission model as a users (at least some some functionality might be retracted ).
And additional question: what is the general recommendation for this use case if Authorization Server is inside of Datacenter1 or outside?
First of all: OAuth 2.0 is not an authentication protocol, it is a delegated access protocol. It is clearly stated here: https://oauth.net/articles/authentication/
Although widely adopted, the OAuth 2.0 "authentication framework" left many details open for interpretations - which commonly leads to security flaws of the implementation.
Check here for the 10 most common implementation vulnerabilities in OAuth 2.0: http://blog.intothesymmetry.com/2015/12/top-10-oauth-2-implementation.html
Therefore, the actual best practice is to use OpenID Connect, a similar protocol (built on top of OAuth 2.0), well defined, that mitigate most of the shortcomings of OAuth 2.0.
OpenID Connect is the best practice to authenticate end-users (mostly web).
If you want to authenticate within the datacenter, the variety of used solutions is somewhat wider - but overall I think the most common best practices are:
"Leaner" implementation: clear HTTP when you appropriate network security (e.g. well-configured VPC, so access from the internet to any of these servers is very unlikely)
"Safter" implementation: Server to Server Basic Authentication (or similar) over HTTPS, while rotating the key every now and then. The keys should be stored in a secure storage, such as Vault
In any case, it is best the service will delegate the request for the user (i.e. by providing user_id as part of the request) - and permissions will be enforced for this user:
You probably don't want to allow a bug allowing one user to access the data of another user.
In any case, it is much better logs / audit will be done with link to user originating the request, and not some generic "system user".

Web API authentication/authorization using SSO instead of OAUTH - will it work?

Updated based on questions from #user18044 below
If a user is authenticated in two different web applications via 2 different SAML-based identity providers, and one of the applications needs to request data from a web API exposed by the other application, would it be possible to call the web API methods securely by virtue of the user's current authenticated status in both applications without separately securing the API methods via an API level authentication protocol such as OAUTH? Note that both applications are owned and operated by my company and share the same 2nd level domains and user base, even though the identity servers are different (one is legacy).
Some further information: Application A is a portal application that is going to host widgets using data supplied from Application B. Application A will only communicate with application B via a web API exposed by application B. Currently application B does not expose a web API (except internally to the application itself). This is new functionality that will need to be added to application B. Application A will use Okta as its SSO. Our lead architect's proposal is to continue to use a custom legacy IDP server that we developed internally based around using the dk.nita.saml20 DLL. They are both SAML based I believe, but I don't think they could share the same identity token without some retrofitting. But this is hitting the limits of my knowledge on the topic of authentication. :) I think our architect's plan was to have the user authenticate separately using the two different identity providers and then only secure the web API using CORS, his reasoning being that since the user is already known and authenticated to use application B, that there wouldn't be any security implications in allowing application A to call application B's web api methods, as the user should be authenticated in application B. This seems quirky to me, in that I can imagine a lot of browser redirects happening that might not be transparent to the user, but other than that, I'm just trying to figure out where the security holes might lie, because it feels to me that there would be some.
I know that this approach would not be considered a best practice, however with that being said, I really want to understand why not. Are there security implications? Would it even work? And if so, are there any "gotchas" or things to consider during implementation?
To reiterate, our lead architect is proposing this solution, and it is failing my gut check, but I don't know enough on the topic to be able to justify my position or else to feel comfortable enough to accept his. Hoping some security experts out there could enlighten me.
It's hard to answer without knowing more on how your current applications and APIs are secured exactly. Do the web application and its API have the same relying party identifier (i.e. can the same token be used to authenticate against both)?
If both web applications use the WS-Federation protocol to authenticate users, then most likely the SAML token will be stored in cookies that were set when the identity provider posted the token back to the application.
You do not have access to these cookies from JavaScript. If the web API that belongs to application B uses the same cookie based authentication mechanism, you could use this provided you allow for cross origin resource sharing.
If your web API uses something like a bearer token authentication scheme (like OAuth) or has a different relying party id in the STS, this would obviously not work.
I think the reason this fails your gut check is because you are basically accessing the web API in a way a cross-site request forgery attack would do it.
A problem I see with this approach is that if the user is not authenticated with the other web application, then the call to your API will also fail.
I agree with user18044 as far as it being based on a cross-site request forgery attack and the security between applications. Is it true that if User X has access to App A, that they will have access to App B and vice versa? If that is not the case, then each application will need to be authenticated separately...and it won't be a SSO. I found these links that might be helpful in your situation.
https://stackoverflow.com/questions/5583460/how-to-implement-secure-single-sign-on-across-various-web-apps
https://developer.salesforce.com/page/Implementing_Single_Sign-On_Across_Multiple_Organizations

WCF using 2 Authentication Methods With Windows Identity Foundation

I'm working on a WCF project that will be our new service layer.
These services will be called by 2 separate clients, the first of which is a WPF application and the other is an ASP.Net web application. The WPF client will be run by internal users and will authenticate with the service via domain authentication and run under the context of that user. The other will be used by external users and needs to authenticate using some separate mechanism then impersonate a "WebUser" account on our domain.
I'm reading a bit about Windows Identity Foundation and it sounds like this might be a good fit. Am I right in thinking I could have 2 token services, one for domain authentication and one for something like ASP.Net membership authentication (Or some similar equivalent) and have each client get it's token from the relevant STS and pass that along to the WCF service?
I'm assuming there is an STS I can use out of the box for domain authentication, but will I have to implement the second one myself to authenticate web users? I can't find a lot of information on this.
Am I thinking along the right lines or should I just be creating duel endpoints for each service each with a different authentication mechanism? Or should I be doing something completely different?
Thanks
The big advantage of using Claims-Based authentication / WIF is that both the task of authenticating the user AND the administration of the user's properties are moved way from the applications to the STS/Identity provider.
You are developing a service layer but the true benefits of using WIF will be for the applications written on top of your layer. The WPF application will no longer need to connect to the AD and fetch the user's groups to figure out what they are allowed to do. The groups will already be visible as claims in the token the user/WIF provides.
The web application (is it just one web application or more?) will no longer need the ASP.Net Membership database with accompanying user administration. This functionality gets moved to the STS.
There is a cost. (There always is, somehow...) Claims-Based authentication has a rather steep learning curve. It takes a while for the quarter to drop for all people involved.
So the answer to your question depends on what kind of users the web application(s?) built upon your service layer have and how many. And how much they wish to know about them. Can you perhaps trust Google / Facebook / Windows Live for authentication? Are the users already in an existing database within your domain? How much work will it take to maintain the user directories? Do your marketing people wish to send them emails regularly? Et cetera.
This is probably not just for the service layer's developers to decide, but something to discuss with people in the rest of your organisation.
If the benefits are not particularly big, the alternative is to simply keep these responsibilities at the web application's server. Each web application will have a good old ASP.Net membership database, it'll authenticate the user all by itself. When asking queries from the service layer, it'll present its web server certificate plus specify the user's name and type.
If the benefits are big enough, you can in principle use ADFS 2.0 for everything. It can also store external users nowadays and it's free if you already have Active Directory. Or the ThinkTecture 2.0 server that Ross recommends. It's easier to customize and perhaps your systems administrators and security folks will not be too enthusiastic about opening the firewall to the ADFS server.
Microsoft has some good reads on WIF, in particular an Overview of Claims-Based Architecture.
You should take a look at identity server as it can indeed handle this scenario.
The person who leads the project above has a great pluralsight video on this exact scenario! You need to sign up to watch it, but they offer a free trial.
Basically you get a token from the identity provider (windows ADFS for the internal client, and what ever you decide for the external users). You will give this token to the federated gateway (identity server probably, but it could be Azure ACS). This will return an authentication token that you can then use with your service.

How to implement active federation provider with WIF

I have several Silverlight, WP7 and ASP.NET MVC client applications Most allow anonymous access to the application but secure various features based on a user's credentials when logged in. All of the clients use a common back-end service application for data access and business processing which require the user's credentials for authentication and authorization.
We currently use Forms Authentication in all client applications and I'd like to migrate our architecture to use federated identity and a claims-based model. Passive federation is not an option.
I am looking for the following flow:
The user triggers the login dialog, enters their username and
password then clicks "OK".
Behind-the-scenes, the application calls an active STS service in
our existing service application for authentication.
The service is actually a federated STS and passes the call through
to the (active) IP_STS which may or may not be ADFS.
When the IP returns the token to the FP, the FP modifies the token
with additional claims from the server data store before returning
the token to the client application.
The client application maintains the token in memory for
authorization checks (in Thread.CurrentPrincipal, for example).
The client also passes the token when making requests to other
service operations in our service application.
These service operations will use the token to
authenticate/authorize the request.
This is a very different use-case from any of the articles and samples I've been able to locate. Can anyone provide some guidance and/or point me in the right direction?
It is my understanding from Dominic Baier that WIF doesn't currently support the approach we are taking. We've taken his suggestion and created our own custom STS that moderates authentication using the Provider model.
Unfortunately, the farther we got into this, the more we realized that WIF isn't flexible enough to satisfy our needs at this point. We stuck with the custom STS approach but are using our own transport and credentialling rather than the WIF tooling. Hopefully a future release will give us what we want.