Reauthenticate using ADFS? - adfs

I am being tasked with writing an asp.net web app that will use ADFS for authentication. However, at one stage in the application users will have to re-authenticate and supply their username and password again.
Can this be done with ADFS?

The ASP.NET app can be an active client to the STS as well as a passive one. When you need to step up, provide some input fields and ask the user for additional proof of who they are. Using the WSTrustChannelFactory, pass this info (and possibly the original token) to the STS to get a new token that is fresher and contains claims that are sufficient to authorize the the higher value transaction.

What is the goal of the re-authentication, i.e., what does the user need to prove?
I'm presuming the application wants a sign-in token with a recent authentication timestamp (within, say, the last 10 seconds), so that the application is reasonably sure that the client system is really still under that same user's control.
(Watch out for clock differences between your web server and your AD FS server, by the way.)
In the coming months I will be investigating a similar scenario, and my current idea is to use the SessionAuthenticationModule.SessionSecurityTokenReceived Event, as described in this blog post by Vittorio Bertocci. However, that cannot be the entire solution, since this only forces AD FS to give out a token, but it does not force AD FS to give out a token with a recent authentication timestamp.
So no answer yet, but perhaps these hints help.

This article describes a "step-up" procedure that might help you in this scenario. I haven't used it though, so I can't comment in detail. It looks very close to what you are trying to do.

Reducing TokenLifetime property makes you to re-authenticate users. suppose by TokenLifetime is by default is 60 min but it shows popup before 20 mins. but there may be data loss

For ASP.NET using WIF, you are using WS-Federation as the protocol to interact with ADFS and get a token. Within this, you can specify wrefresh=0 in the sign-in request to ADFS. When this is sent, ADFS ignores any prior cookie state (web SSO) and does a fresh authentication and so a new token will be issued to the app. In the case of intranet domain joined machine case, this will be silent.
To have user interaction, you can do one of 2 things
For 2012R2, I recommend that you use MFA and the app can request MFA by requesting for MFA in this 'step-up' scenario. See http://blogs.msdn.com/b/ramical/archive/2014/02/18/under-the-hood-tour-on-multi-factor-authentication-in-ad-fs-part-2-mfa-aware-relying-parties.aspx
Outside of this, you can also force username/password auth and combine it with wrefresh=0. This ensures that prior SSO state is ignored and U/P auth is performed.
Thanks
//Sam (#MrADFS)

Related

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

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.

What is this Authentication model called in the ASP.NET world

I know ASP.NET supports various authentication models like, Windows, Forms, passports and recently Claims.
I have an asp.net that prompts user to enter user name/password to login, it then compares the input username/password with the entries inside the user table of the application's Database. So, my question is, what is the term/name for this kind of authentication model? Where does this fall in the above mentioned ASP.NET supported authentication model?
I also see that many of the internet sites that I know uses this same approach.
(note: I'ev kept my App simple, of course it has user registeration/add page, profile table to authorize users, etc)
Windows, Forms, Passport, Claims, etc.. authentication are BROWSER authentication schemes. They are the mechanism the browser communicates with the server to present credentials. They have nothing to do with databases or any other storage mechanism (well, mostly..). Those are just implementation details.
FormsAuthentication uses a cookie to store an encrypted value that tells the server that the user has been authenticated. How the user is authenticated, be it by comparing things to databases, using a service, etc.. is all irrelevant if the end result is that a FormsAuthentication cookie is issued.
WindowsAuthentication is a little different in that the browser and the web server communicate to share a Kerberos ticket to verify identity, or the user enters the username password into a box that the server requests the browser to pop up. In this mode, the server itself manages the way that authentication occurs and the app isn't involved.
BasicAuthentication uses an HTTP Header to send the password in cleartext, well, technically it's an encoded password, but it's well known so anyone can unencode it. Again, the actual method that it stores the data is up to the server, and the server does this without an applications knowledge. The important part is that it's accomplished via an HTTP Header.
The same is true of other types of authentication, which are all just variations on the cookie and/or header mechanisms.
The point here is that Authentication is about how any given HTTP request identifies who the user is to the server, and ultimately the application. Not how the data is stored, or validated. So, since you did not tell us how the server and browser communicate, we can't tell you how your authentication is defined, although almost certainly it is a variation of FormsAuthentication.
EDIT:
Just a little history lesson. The reason it's called FormsAuthentication is because the authentication system does not use a pop up dialog box from the browser to enter credentials, but typically the web page provides an HTML Form for the user to enter credentials. The browser is not really involved in the authentication process at all, other than for passing a cookie as requested.
It should be more accurately called "CookieBasedAuthentication", but the name has stuck and will probably stay what it is. ASP.NET provides a specific implementation called FormsAuthentication, but you can do the same thing with any cookie based authentication scheme (although I do not recommend rolling your own, you will almost certainly make security mistakes).
Some people think that storing a flag in Session is good enough. Do not, under any circumstances, ever use Session to store authentication information. Session cookies are not encrypted and are easily stolen and/or spoofed. Use a well known method.
The other answers might have already showed most of the details. But if we categorize carefully on IIS and ASP.NET levels, below are the differences you should pay attention to,
IIS Authentication
This occurs first, as HTTP packets arrive at IIS level first. IIS supports several ways,
Anonymous (the anonymous user account configured in IIS configuration)
Windows (browser side user)
Basic (browser side user)
Digest (browser side user)
How those authentication methods work at packet level requires you to capture network packets and dive into the conversation at that level.
The result of this authentication is that IIS generates a user token and passes on to ASP.NET pipeline.
ASP.NET Authentication
ASP.NET has several authentication methods of its own,
Windows (here ASP.NET trusts and interprets the user token IIS passes, and determines which ASP.NET user identity should be created and which roles it supports, without doing further authentication on ASP.NET level.)
Forms (based) authentication (where ASP.NET ignores the user token, and uses cookies or similar mechanism to build a high level authentication approach. On IIS side you usually set anonymous authentication.)
Claims based authentication, OpenID, OAthen and so on are similar to Forms based, where they don't care much about the user token generated by IIS.
It is possible to use non-anonymous on IIS plus non-Windows on ASP.NET side to set up the so called mixed authentication.
All the Authentication methods that require the user to input a Username and Password that you maintain are a form of Forms Authentication. This is because you are asking them to fill out a form (Username and Password) in order to authenticate them.
Read more about it Here or Here.
Edit: The answer provided by Mystere Man is much more complete and accurate than mine.

Asp.NET WebAPI custom authorization

I want to create a authorization mechanism for an application based on WebAPI and AngularJs.
I've seen some articles, which use BasicHttpAuthentication, but i really don't like the whole idea of sending username, and password on every request. The more it doesn't fit for me is because i want to use OpenId authentication, where you don't have username/password pair.
I'm thinking about a solution, but I don't really know how to implement it. The concept is that user is authenticated as in an usual Web application - posts a form with user / password or selects an OpenId provider. If the user is authenticated succesfully, it is placed in a static object, which stores the User object for a certain ammount of time. Next a usertoken is generated and passed to the Client Application. The client passes the token on each request to the server, if the user exists in the above mentioned static object with the appropriate authentication token it is authorized to get the data.
Firstly - Do you think this is a good approach to the problem?
Secondly - How should I pass the authentication token, WITHOUT using cookies? I guess it should sit in the request headers, like in BasicHttpAuthentication but, I really dont' know how to handle it.
BasicHttpAuthentication
I'm with you on feeling dirty about caching the username and password on the client and forever transferring it with every request. Another aspect of Basic authentication that might work against you is the lack of sign-off. Other than changing the password, you can't "invalidate" a basic authentication session. Tokens on the other hand, will typically offer an expiration date, and if you want server-side invalidation you can check the issue date and say "any tokens older than issue date xyz are invalid".
Server State
You mention "If the user is authenticated successfully, it is placed in a static object". But this is independent of the token? This sounds like you're wanting to implement server state management of authentication sessions, but this isn't strictly necessary. The token itself should be sufficient for user authentication, managing server state is another potential obstacle. Server state can become difficult to manage when you factor app-pool recycles or web-farm environments (what if you want two services to share the same authentication token, but not require communication with a central "authentication server" for storing the state / session?)
Passing Authentication Token
Headers is definitely a good place for it. Really, where else is there? Cookies, Headers, Message. Other than a browser client, cookies don't make a lot of sense, and including it in the message can muddy your message formatting a bit, so headers is the only remaining option that makes much sense in my view.
Client Implementation
You've not specified, but I suspect you're interested in calling the service from .NET? In which case System.Net.Http.HttpClient could be your friend. In particular, the DefaultRequestHeaders collection. You can use this to add a custom header to store your authentication token.
Server Implementation
When researching ASP.NET authentication recently, I learned a lot about customisation by examining the Mixed Authentication Disposition ASP.NET Module (MADAM). I wasn't interested in using MADAM as-is, but learning about it from that article and examining the source code gave me a lot of ideas of how I could insert my own authentication module into the web stack.

Membership / Authorization over a REST service

I'm investigating creating a WCF REST service for an existing asp.net application to be consumed by various clients including Windows Phone 7, Android, iPhone apps etc.
Creating a simple WCF REST service and consuming it from the above platforms is not a problem and works really well. What I am struggling to get my head around is authorization.
The asp.net application uses the Membership provider to provide authentication and authorization and I'm comfortable in using that API from the REST service.
How do I secure my REST service so that the first call has to be to authenticate (passing the username and password) and following calls know who is 'logged in'. I'm guessing the authenticate method will have to pass back some sort of token to be used in subsequent calls identifying the caller. Is this secure enough as the whole site / service is over SSL?
Any suggestions welcome.
The more restful authentication scheme is to use HTTP Authentication, e.g. Basic or Digest. Since your service is over SSL, Basic should be sufficient. The authentification tokens (login/password) are sent with every request, so that the service can be stateless. Every client library that I'm aware of can deal with basic authentication.
In general the token approach is better then just sending username+password (Basic Authentication) in each request. The problem is to implement it correctly: while Basic Authentication is very easy to implement, and actually it's already implemented by most application and web servers, the token is something you'll need to implement yourself - it must be encrypted, so clients won't understand it, so you'll need some keys management, it also must have some expiration date and may be you'll want some revoke functionality.
In addition, it will make client's life harder: instead of just attaching basic authentication header to each request, client must first go to some authentication point, receive a valid taken and then use the token on the requests. If the token expires, the client will need to go to the authentication point again.
So if you have time and knowledge, and your clients are smart, it's better to use the token approach. Otherwise with SSL, basic authentication should be sufficient.
I've seen an example in the latest Windows Azure toolkit for WP7 that might be helpful for you. It basically uses the Membership Provider, logs in a person (the first time the person installs the app) and then generates a Ticket. It then Encrypts this ticket and sends it back as a TOKEN which is then stored on the phone in the isolated storage. The expiration of the ticket is set to int.MaxValue so that the token remains good for a long period of time.
Now, this token is passed over to the Web Services in the Authorization Header where it is decrypted, the identity of the user is verified and then the web service call is made.
Hoping this helps. I am trying to solve a similar scenario and trust me, there isn't much out there that points us in the right direction...which is a pretty sad state of affairs if you ask me.

Resources