OpenAM, OpenId, REST API, In-House applications: how do I connect them all? - asp.net

I'm having trouble tying all of this together. Partially due to lack of understanding, and partially because I've not use OpenAM before.
I'm trying to implement Single Sign-on. Here are the players.
OpenAm. https://www.forgerock.com/en-us/products/access-management/
A 3rd party proprietary app that can use it's own username/password database, or authenticate against an SAML or OpenId provider.
Several In-house applications written in either angularjs or .net webforms.
An in-house REST API written in nodejs.
I need to be able to have a user sign-on/register in openam, and then they don't sign-in to any of the other applications. We see this all over the web, so the use-case is pretty normal, but I've never actually implemented it myself before.
See what I'm trying to do using the image below for starters.
Here's what I'm stuggling with:
For SSO purposes, OpenAM seems to store the authenticated user information in a cookie. How does my Proprietary app pick up this cookie and use it if it can only authenticate via openid or saml? It can't use the openam API by going through the /json/* endpoints.
With the in-house apps, I'm assuming I can just pass the cookie along and the appropriate parties can validate the cookie's session info or token and that's that. Is this correct, or am I looking at this wrong?
Can I have the user login to the OpenAm login page, and then use the /oauth2/* endpoints to validate the user's requests? I could see this working better, but am unsure if this is how it's supposed to happen.
Basically, I feel like I've scrambled my brain this last week trying to sort this out. I need some help to get some direction here. As I said above, a good portion of this is new. I've done front-end->rest api->database using a token, but this SSO scenario has given me a real headache.
Any help would be appreciated.

It sounds to me that you miss the "redirection" aspect of SAML SSO. I'll try to explain how it works in a nutshell:
Step 1:
When a user sends a request to one of your in house applications (call it the Service Provider, SP, from here), the SP detects that this is an unauthenticated request and redirects the browser to the OpenAM server (call it the Identity Provider, IdP, from here).
Step 2:
The IdP analyses the redirection request and expects to find a "SAML authnResponse", this is encoded XML metadata added in the redirection request by the SP. It finds out that your SP wants to authenticate a user. The IdP will respond to the request by showing a login page. Here the user can authenticate to the IdP. After the user succesfully authenticated to the IdP, it will redirect him back to the SP adding a "SAML authnResponse" to the request.
Step 3:
The SP will analyse this "SAML authnResponse", which is again just a form of XML metadata. If the validation of the signature is OK,find out which user successfully authenticated, create a session for him and redirect him to the resource he initially tried to access.
Remark 1:
In Step 2, if the user already authenticated to the IdP before, he will have an active session to the IdP. The IdP will not require him to login again but just inmediately redirect him back to the SP with a valid "SAML authnResponse". In this way the user will barely notice all these redirects and it will look like he 'seamlessly' got access to the SP.
Remark 2:
So don't worry to much about cookies, they're used by the IdP to recognize already authenticated user sessions etc. but you should only bother with redirects and analyzing the SAML Responses and Requests. Does this make sense?
Remark 3:
The way how the browser (GET 302 or JS POST) of the user will be redirected depends on your chosen "SAML Profile".

Related

asp.net SSO and SAML from WebApi simply because that is all the client has

I have inherited this and am stuck with this approach. I am just trying to figure out if it will in fact work.
The project involves your standard asp.net web api application with android and ios clients. The trick is with the authentication. The application is for a 3rd party, and the only way that the user can be authenticated from the outside world is by using their IDP. The 3rd party does not care what happens after the user is authenticated.
All I have to go by is the architecture diagram that the former team members created. The diagram has 3 layers. User/Mobile Device, SAML SP Web APP and Client IDP. The important part of the flow is as follows:
Mobile App calls SAML SP Web App with the IDP user name and password.
SAML Web App calls the IDP login using the user's credentials
User Authenticated ? Responds to SAML SP Web App with success and SAML Assertion/Token
SAML SP Web App responds to mobile App with approved message
Once the user is authenticated through the IDP, the plan was then to issue a bearer token to the mobile device.
Unless things have changed a lot since I last had to play with SAML (2011), it seems I am missing a client browser to redirect from the SP to the IDP and then redirect back to the SP when a valid SAMl assertion is created.
Am I missing something here, such as a way to emulate a browser to allow for these redirects and plugging in the correct user name and password, or is there a way to call the IDP directly from the SP and have it issue a response directly back to the SP? Or am I just reading the diagram wrong or inheriting some very bad assumptions? I'm in the awkward position where I don't want to go back to the client and revisit a process that was supposedly decided upon at the start of the year unless I absolutely have to.
Things don't change a lot with SAML, so your knowledge from 2011 is still definitely valid.
I'm also missing the browser redirect step. It is a quite common misunderstanding that the SP can send username/password to the Idp and get an assertion back, but that is not supported by the SAML WebSSO Profile (which is the one that's actually used).
Using SAML2 for a mobile application is hard, there's no good support in the SAML2 protocol for redirecting back to the client. A common way to work around it is to use OpenID Connect. I've been involved in setups where the mobile client authenticates to IdentityServer3 via OpenID Connect. Then IdentityServer3 acts as a SAML2 SP (through the Kentor.AuthServices middleware) to the upstream SAML2 Idp.
I understand that you are in a delicate situation but I think that you have to go back and ask how it is supposed to work. Specifically you should ask where the user is supposed to enter credentials and how the communication between the SP and Idp is supposed to work.

Is it possible to use an external Identity Provider in a Web API with ASP.NET 5?

Reading this question, #Pinpoint's answer and the further discussion on comments, I'm well aware that natively we can't add an identity provider to our apps developed with ASP.NET 5. One possible replacement for the legacy OAuthAuthorizationServerMiddleware is then provided by the AspNet.Security.OpenIdConnect.Server as I've found in many places.
Now, there is one point that I'm still unsure about all this because I'm really not an expert in security, so my knowledge about OAuth is not very deep. My doubt is the following: is it possible to use an external identity provider when using OAuth to protect one RESTful API?
Notice that I'm not talking about adding social login to one website, I'm talking about using one external identity provider in one RESTful API.
My point is, this makes me a little confused yet, because I always thought this should be a concern of my app.
So my question here is: when using OAuth and ASP.NET 5, is it possible to use an external identity provider, other than implementing one? If it is possible, how this works in short? I mean, my app still needs to be able to manage the identities of users, in the sense that it needs to manage claims and so on.
In that case, if it is really possible, how the flow would be? The external identity provider should issue the tokens? But how my app would be able to verify those tokens and manage users identities?
EDIT: One of the reasons I feel unsure about that is that when we use the UseOAuthAuthentication extension method, we set up one callback path which is described as
The request path within the application's base path where the user-agent will be returned. The middleware will process this request when it arrives.
Now, if we are developing a site, then this really does make sense. The person goes there, click a button to login with a provider like Facebook. The user is redirected to Facebook's page and then after he logs in, he is redirected to some page of the site.
On the other hand, with a RESTful API this is meaningless. There is no notion of being redirected.
This makes it seems that the usage of external providers is only for sites and not for RESTful API's. This is the main point of my question.
My doubt is the following: is it possible to use an external identity provider when using OAuth to protect one RESTful API?
Yes, it's definitely possible. This is exactly what you do when you use Azure Active Directory to protect your API endpoints:
app.UseOAuthBearerAuthentication(options => {
options.AutomaticAuthenticate = true;
options.Authority = "https://login.windows.net/tushartest.onmicrosoft.com";
options.Audience = "https://TusharTest.onmicrosoft.com/TodoListService-ManualJwt";
});
The next legitimate question is: if you can use the tokens issued by AAD to protect your API, why couldn't you do the same thing with Facebook or Google tokens?
Unlike Facebook or Google, AAD issues completely standardized tokens named JWT tokens that the OAuth2 bearer middleware can "read" and "verify" to determine whether the token is still valid and was really issued for your API (i.e if the audience attached with the token corresponds to your API. You can control this value using the resource parameter when making your authorization request).
You can't do something similar with FB or Google tokens, since they are totally opaque. Actually, it's not really surprising since these tokens have only one objective: allowing you to query FB or Google APIs, not your own ones (these social providers don't allow to set the audience of the access token).
Since you can't read the token yourself, the only option is to ask FB or Google whether it is still valid to make sure your API doesn't accept invalid tokens. That's something you can (easily) do with Facebook as they offer a "token inspection endpoint" you can query for that: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow (see the Inspecting access tokens chapter). This way, you can ensure the token is not expired and determine the user corresponding to the token.
Sadly, this approach has two downsides:
You have to make an extra HTTP call to the Facebook endpoint to validate the access token, which implies caching received tokens to avoid flooding Facebook with too many requests.
As the access token is not issued for your own API, you MUST absolutely ensure that the access token was issued to a client application you fully trust, or it will allow any third party developer to use his own FB/Google tokens with your API without having to request user's consent. This is - obviously - a major security concern.
You can find more information in the last part of this SO answer (it's for Katana and about Dropbox, but you should get the idea): OWIN/OAuth2 3rd party login: Authentication from Client App, Authorization from Web API
So my question here is: when using OAuth and ASP.NET 5, is it possible to use an external identity provider, other than implementing one? If it is possible, how this works in short? I mean, my app still needs to be able to manage the identities of users, in the sense that it needs to manage claims and so on.
In that case, if it is really possible, how the flow would be? The external identity provider should issue the tokens? But how my app would be able to verify those tokens and manage users identities?
To work around the limitations mentioned in the previous part, the best option is - as you've already figured out - to create your own authorization/authentication server. This way, your API doesn't (directly) accept FB or Google tokens but the tokens issued by your own server, that can possibly redirect your users to FB or Google for authentication.
This is exactly what this sample does: https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/tree/vNext/samples/Mvc
The user is invited by the client application (Mvc.Client) to authenticate with your authorization server (Mvc.Server) so he can get an access token to later query the API (also in Mvc.Server). For that, the user is redirected to your authorization server, which itself offers you to authenticate with Google or Twitter.
When this external authentication step is done, the user is redirected back to your authorization server (Mvc.Server), where he's asked to give his consent for the client app (Mvc.Client) to access his personal data.
When the consent is given, the user is redirected back to the client application with the access token you can use to query the API endpoint.

Authentication and authorization related doubts with asp.net web api

I have to start a new project to be developed in MVC 4 and Web API. I have prior experience with MVC 4 but with Web API this will be my first project. I understand that web api is there to be consumed by different platforms.
I have a few concerns related to web api. I am presenting them to you guys as following:
1) My first concern is related to user authentication. I looked into this SO question and followed the link1 and link2 given in the selected answer. I still have a couple of questions:
a) When we do user authentication through Form Authentication we create a cookie, that track if the user is authenticated or not, but with web api we do not store cookie, instead user credentials are passed in content header. I didn't get how user's logged in status is tracked in this case ?
b) My another concern is related to restrict unauthorized access, which I think I can find find out in link 1 and link2 provided above, if I am not wrong.
c) I looked at the Edward Brey answer (in the same SO question) as well for authentication but I didn't get the idea completely.
2) My second doubt is about mixing Form authentication and Basic Http authentication. Is it possible that for login I use forms authentication and then for consuming web api I use basic http authentication? If yes then please guide me.
My questions may sound inappropriate but please bear with me
1.a) Restful APIs are stateless, so you are not keeping track of user's logged in status, rather you are sending credentials which are verified for each of the requests
1.b) Yes, if not there are number of articles on web for that. Authorization Filters can help you in achieving this.
1.c) In short, he has mentioned simple logic to authorize user before executing any of the methods in your API. Call EnsureAuthenticated before executing any of the methods in a controller, or put that logic in you Authorize filter.
2) Yes you can do it. In Restful API's each call can be a new instance and you can pass in credentials with api requests whichever you are making.
If you go in discussion of Link 1 that you have provided, you will see:
In our specific case, the server generates the auth token by encoding
the concatenated username and password as Base64 (the reverse of what
is described in the article) and sending it back to the client via a
HTTP header when it performs their ‘log in’ action. The clients then
store this auth token and send it with each subsequent request that
requires it.
If the format of the auth token is well known (as it is in my case),
you could also just generate this yourself on the client and send that
without having the server do this work.
You can use your login to generate an authentication token for client, which you can use to send attached to your web api requests.

Token authentication and authorisation for a self-hosted ASP.NET Web API 2 REST service

I'm using VS2013 and Web API 2 to create a self-hosted (using OWIN), RESTful service over SSL using token authentication. Although I'm not a novice developer, this is my first time looking at ASP.NET technologies, so please keep that in mind.
I've got everything more-or-less working except for the authentication and authorisation parts. I fully understand the difference of authenticating a user (who is this user?) and authorising an already authenticated user to access a resource (can this user access this particular resource?).
A very simple overview of my auth process is as follows (makes some assumptions for brevity):
An unknown client connects to the API, e.g. GET api/values.
The server responds with a 401 and this response header: "WWW-Authenticate: Token".
Upon seeing this, the unknown client knows to connect to a different API endpoint here: POST api/auth (routed to the Login function), supplying the username and password.
The server will try to figure out if this is a valid user and can accept or reject the user depending on the validity of the credentials.
(Rejected) The server returns an error status code (403?). End of process.
(Accepted) The server creates a random token (e.g. a GUID) and stores it against the user record. Then it sends the token to the client.
The now authenticated client reconnects to the API, GET api/values, and this time also supplies the token.
The user returns the resource data to the client.
...
The user can log out by connecting to the same API as he used to log in: POST api/auth (this time, his request will be routed to the Logout function). This will remove the token from the server and the client will also have to remove its own token.
As you can see, this is a relatively simple process, but I can't find any concrete and simple examples to understand how best to achieve this with a self-hosted Web API 2.
I don't need to register users or do any password/roles management, etc. and there is no external authentication. All valid users have the same rights to access the resources and they're already created in the system by a separate process over which I have no control (I can only read their credentials for validation). Most examples I found are talking about security frameworks that I don't need, so I've ruled out using any of the following: Basic Authentication, Windows Authentication, Forms Authentication, Individual Accounts, ASP.NET Membership/Identity, OAuth, Thinktecture or any other security framework.
I've read articles about authenticating in a message handler and others about authentication in a custom Authorize attribute filter, while others even suggest I should use the new (in Web API 2) IAuthenticateFilter attribute. This is very confusing. Can you please advise on a very simple way to achieve my auth objectives? Any specific code examples will be greatly appreciated, even if they're just skeleton implementation or pseudocode. I just need some ideas to get me started.
After a lot of googling, I found this article on CodeProject: http://www.codeproject.com/Articles/630986/Cross-Platform-Authentication-With-ASP-NET-Web-API. While this is not Web API 2 or self-hosted, it has given me a number of ideas on how to proceed.
Someone also posted a comment to that CodeProject article referencing a NuGet package that may interest anyone looking for something similar: https://www.nuget.org/packages/WebApiTokenAuth. In my case, it is a bit much.
Finally, in addition to the authentication options mentioned in the question, there's also the option to write an OWIN middleware to do authentication if self-hosting using OWIN (as per the official MS recommendation). However, I plan to implement this particular form of token authentication with a message handler, as there's more support for this method available than for writing OWIN middleware.

SAML: Communication between Service Providers?

I've been tasked with writing a SP (Service Provider) for SAML v2.0 in ASP.NET, and I wonder the following;
If a user logs in on the main SP for a service (where my SP becomes accessible for a user as an anchor/link, unless previously bookmarked), and then requests access to my SP, how should I handle their login?
They will have logged in and become authorized by the IdP on the main SP, but how will that SP tell my SP that the user is logged in?
Will I have to send a new authorization request to the IdP to determine whether the user is logged in or should it be passed on as post data/redirect with a query string from the SP?
I've read the technical overview as well as the basics, but they don't cover this part.
I will contact the main SP and ask how to proceed, but I wanted to cover my bases first and see if there's a standard way on how to deal with this situation.
The easiest thing to do is to have the "main SP" construct the link so that IDP-Init SSO is initiated for users to log into your application. So the user would show up with a new Assertion from the IDP (customer) to your SP.
You could also have them directly link to your site to invoke SP-Init SSO for the given Identity Provider/Customer.
Either way you choose to do this will require you to handle multiple use cases and options for SAML 2.0. You can have this up and running in short order if you want to check out the SaaS Partner Program offered by Ping Identity. www.pingidentity.com
Let me know if you'd like more info on what we've seen other
In order to do SP-initiated SSO, you either need for there to be only one identity provider that you might need to send authentication requests to, or you need some means of determining the proper identity provider for a particular user -- either the user needs to provide some IdP-identifying info (such as StackOverflow does when you want to log in using your Google or other ID) or there may be something embedded in the URL. (For the app I work on, different clients have their own site domains, so IdPs get mapped to those.)
So, yes, if you're going to go the SP-initiated route, you will need to make an authentication request to the IdP to determine who the user is, and you will want to use RelayState to get them back to the originally requested page. If they're already authenticated at the IdP, then most likely this exchange will happen without requiring any input from the user.

Resources