Combine STS and relying party into same website - asp.net

I'm working on an MVC project and I'd like to abstract authentication out completely using WIF. By default, without any additional configuration, this app needs to be it's own STS in additional to also being a relying party. Has anyone done that and have any suggestions?

I tried to think of exactly the same mechanism some time ago and I failed.
My reasoning was that to be an RP, the application has to get a signed SAML token issued by an STS. Upon receiving the token, the federation cookie is created.
But to be the STS, the application should have a login page and a mechanism to persist the login session so that users do not have to login again. Then it should react to wsignin1.0 requests and issue SAML tokens.
This leads to a contradiction in my opinion. The application should have a federation cookie (to maintain users sessions as an STS) before it issues the SAML token but in the same time it can create a federation cookie (as an RP) just after it receives the SAML token.
Of course, you could possibly maintain two cookies, a federation cookie for the RP part and a forms cookie (probably) for the STS part but it sounds impractical and against the idea of abstracting the authentication.
In a short way: this is not easily possible in my opinion. However, I would be glad to hear other ideas from someone.

Related

Owin Authentication: SSO token vs ID token

I have implemented sign-in to Microsoft to my ASP.NET web application. Everything works as intended, but I am struggling to comprehend how the sessions work. I am using OWIN middleware and OpenID connect.
What is the difference between the SSO-Token and the ID-token? Which
one keeps me logged in?
What happens if I try to access claims ( e.g.
userClaims?.FindFirst(System.Security.Claims.ClaimTypes.sid)?.Value)
from an expired ID token?
How does !Request.IsAuthenticated realize that the current user is
Authenticated after the microsoft login? Is this because The Generic
Identity, is now a Claims Identity, that returns true?
If I am logged in, and keep refreshing the site, at what point will
I be forced to Authenticate again? And what controls this time?
I understand what an ID-token is, and that it carries claims, and how I access and use the claims. I am just confused about how the session works after a user has logged in with their Microsoft account.
There is no SSO token. The id token represents proof of authentication and some basic user info is included in it. So your web app can get name, email etc.
Expiry is based on an auth cookie that the MS libraries issue. This is tied to another token, the refresh token, which represents the session time.
The id token has a digital signature that is cryptographically verified. Also your app supplies a client secret to help ensure that tokens can be trusted.
The cookie is given an expiry related to the refresh token. When the cookie expires the user has to login again.
FOR BETTER UNDERSTANDING
I would strongly recommend tracing messages, via a tool such as Fiddler, as in this blog post of mine.
Personally I prefer Single Page Apps, which only use tokens and not cookies. They make OAuth aspects easier to understand and code can be simpler, though there are still plenty of subtleties.

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.

Refreshing token with Hybrid Flow

I'm sure I'm missing something.
I have an MVC app & an SSO site that uses Thinktecture Identity Server. The MVC app use hybrid flow to authenticate users on the SSO site. The MVC site uses the Microsoft OpenIdConnect OWIN client to talk to SSO. My tokens have quite a short lifespan - about 5 mins, but I have refresh tokens so the user is constantly re-authenticated. This is a quite useful feature.
However when the token needs refreshing, the user is bounced via the SSO site, which breaks form posts, ajax calls, etc. This is less useful.
Can I not do this renewal on the server, rather than having the user-agent do it? I can't see a way to do this.
I'm also about to look into sliding expiration to try to solve this problem, although I'd been lead to believe sliding expiration was a bad think from a security point of view.
I was missing something. I was getting confused about who was responsible for various activities.
The user should be bounced via the SSO site when their token has expired. I now have sliding expiration on the cookie with an absolute time limit. Ideally this limit should correspond with the expiration of the tokens, but I have a refresh token, so that could be used to refresh the tokens from the server.
Once the relying party has received a valid response, it is responsible for keeping the user logged in, not the SSO site. The SSO site can be used once the tokens need refreshing.

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

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".

Authentication lifetime with WS-Federation via ADFS and WIF

Some background
I work on an ASP.NET MVC web application which implements federated authentication using WIF.
For reasons beyond my control, I am forced to use a proxy STS which, on the one hand, serves as the IdP for my MVC app, but at the same time it implements it's own federated authentication via an ADFS server.
This way, the user authentication process in the MVC application looks like this:
User enters MVC application.
The application redirects the user to the proxy STS for authentication.
The proxy STS redirects the user to the ADFS server for authentication.
The ADFS server authenticates the user and redirects back to the proxy STS.
The proxy STS redirects the user back to the application, with the same authentication info which the ADFS server issued.
The ADFS server is not something I have direct access to (in terms of management), whereas the proxy STS is just a little service (implemented using this tutorial) which I control fully.
The problem (and what I tried to do to solve it)
Using the above setup, I noticed that the users' authentication wears off after about an hour, and then they need to be re-authenticated, so now I'm looking for a way to extend the authentication lifetime.
As of my understanding, it should be enough to extend the lifetime of the security token issued by the proxy STS, which I did. But it didn't solve the problem - the users still needed to be re-authenticated frequently.
So I tried doing the following things hoping it would help:
Setting the persistentCookiesOnPassiveRedirects option to true in the MVC application's ws-federation configuration with a 1-week long expiry time (to make sure that the auth cookie is not being lost due to session expiry).
Setting the HTTP session lifetime in the MVC app to last a week (to make sure that the security token is not being lost on the server side due to session expiry).
Setting the security token lifetime for tokens issued by the proxy STS to 1 week (which I made sure is being applied by examining the security tokens received by the MVC app).
Doing the things described in bullets 1 and 2 on the proxy STS as well.
Setting the IIS auto app-pool recycling time for the MVC app's application pool to be once a week.
None of the above didn't seem to solve the problem, but then I tried:
Setting the security token lifetime for tokens issued by the ADFS server to 8 hours.
As a result, the authentication duration got longer, even as much as 10-11 hours.
The question
What controls the authentication duration with WS-Federation in the above scenario?
Which of the above things that I tried should really be relevant to my issue, and which should not affect it at all (specifically, I would like to understand whether the ADFS token lifetime should really have any effect, and if so - why, or did I just have bad luck with my tests, and it was really something else that might have helped with the issue)?
Thanks in advance!
You have hit a lot of relevant parameters. I will talk about the WIF/.NET part and SAML Tokens only. Not about Pool recycling etc. They are different topics. You will have to take a look at the XML in the SAML messages and Tokens if you really want to control this.
One of the problems is that there are differences between SAML1 and SAML2 Tokens. Besides that some validity timestamps are in the SAML Protocol, which is not used between WIF and an IdP.
Summarized:
It appears that WIF uses Conditions for the SessionToken. That is the only thing available in SAML 1.1. OK there.
SecurityTokenHandler.ValidateToken(token) calls DetectReplayedTokens().
The SecurityTokenHandler.DetectReplayedTokens(SecurityToken) method verifies the validity if the incoming Token (SubjectConfirmationData #NotOnOrAfter). It is not present in SAML 1.1 there WIF uses Conditions#NotOnOrAfter.
This is essentially correct for Replay detection in SAML 2. Somewhat silly (too broad, too long) for SAML1.1.
Applications can (and do) override this behavior in TokenHandler(s) or in events of WSFAM and SesAM. See for instance Vittorio about Sliding Expiration.

Resources