ASP.NET MVC 2 and authentication using WIF (Windows Identity Foundation) - asp.net-mvc

Are there any decent examples of the following available:
Looking through the WIF SDK, there are examples of using WIF in conjunction with ASP.NET using the WSFederationAuthenticationModule (FAM) to redirect to an ASP.NET site thin skin on top of a Security Token Service (STS) that user uses to authenticate (via supplying a username and password).
If I understand WIF and claims-based access correctly, I would like my application to provide its own login screen where users provide their username and password and let this delegate to an STS for authentication, sending the login details to an endpoint via a security standard (WS-*), and expecting a SAML token to be returned. Ideally, the SessionAuthenticationModule would work as per the examples using FAM in conjunction with SessionAuthenticationModule i.e. be responsible for reconstructing the IClaimsPrincipal from the session security chunked cookie and redirecting to my application login page when the security session expires.
Is what I describe possible using FAM and SessionAuthenticationModule with appropriate web.config settings, or do I need to think about writing a HttpModule myself to handle this? Alternatively, is redirecting to a thin web site STS where users log in the de facto approach in a passive requestor scenario?

An example of WIF + MVC is available in this chapter of the "Claims Identity Guide":
http://msdn.microsoft.com/en-us/library/ff359105.aspx
I do suggest reading the first couple chapters to understand all underlying principles. This blog post covers the specifics of MVC + WIF:
Link
Controlling the login experience is perfectly fine. You should just deploy your own STS (in your domain, with your look & feel, etc). Your apps would simply rely on it for AuthN (that's why a app is usually called a "relying party").
The advantage of the architecture is that authN is delegated to 1 component (the STS) and not spread out throughout many apps. But the other (huge) advantage is that you can enable more sophisticated scenarios very easily. For example you can now federate with other organization's identity providers.
Hope it helps
Eugenio
#RisingStar:
The token (containing the claims) can be optionally encrypted (otherwise they will be in clear text). That's why SSL is always recommended for interactions between the browser and the STS.
Notice that even though they are in clear text, tampering is not possible because the token is digitally signed.

That's an interesting question you've asked. I know that for whatever reason, Microsoft put out this "Windows Identity Foundation" framework without much documentation. I know this because I've been tasked with figuring out how to use it with a new project and integrating it with existing infrastructure. I've been searching the web for months looking for good information.
I've taken a somewhat different angle to solving the problem you describe.
I took an existing log-on application and integrated Microsoft's WIF plumbing into it. By that, I mean that I have an application where a user logs in. The log-on application submits the credentials supplied by the user to another server which returns the users identity (or indicates log-on failure).
Looking at some of Microsoft's examples, I see that they do the following:
Construct a SignInRequestMessage from a querystring (generated by a relying party application), construct a security token service from a custom class, and finally call FederatedSecurityTokenServiceOperations.ProcessSignInresponse with the current httpcontext.response. Unfortunately, I can't really explain it well here; you really need to look at the code samples.
Some of my code is very similar to the code sample. Where you're going to be interested in implementing a lot of your own logic is in the GetOutputClaimsIdentity. This is the function that constructs the claims-identity that describes the logged-in user.
Now, here's what I think you're really interested in knowing. This is what Microsoft doesn't tell you in their documentation, AFAIK.
Once the user logs in, they are redirected back to the relying party application. Regardless of how the log-on application works, the WIF classes will send a response to the user's browser that contains a "hidden" HTML input that contains the token signing certificate and the user's claims. (The claims will be in clear text). At the end of this response is a redirect to your relying-party website. I only know about this action because I captured it with "Fiddler"
Once back at the relying party web site, the WIF classes will handle the response (before any of your code is run). The certificate will be validated. By default, if you've set up your relying party web site with FedUtil.exe (by clicking "Add STS Reference in your relying party application from Visual Studio), Microsoft's class will verify the certificate thumbprint.
Finally, the WIF framework sets cookies in the user's browser (In my experience, the cookie names start out with "FedAuth") that contain the users claims. The cookies are not human readable.
Once that happens, you may optionally perform operations on the user's claims within the relying party website using the ClaimsAuthenticationClass. This is where your code is running again.
I know this is different from what you describe, but I have this setup working. I hope this helps!
ps. Please check out the other questions I've asked about Windows Identity Foundation.
UPDATE: To answer question in comment below:
One thing that I left out is that redirection to the STS log-on application happens by way of a redirect with a query-string containing the URL of the application the user is logging in to. This redirect happens automatically the first time a user tries to access a page that requires authentication. Alternatively, I believe that you could do the redirect manually with the WSFederationAuthentication module.
I've never tried to do this, but if you want to use a log-on page within the application itself, I believe the framework should allow you to use the following:
1) Encapsulate your STS code within a library.
2) Reference the library from your application.
3) Create a log-on page within your application. Make sure that such page does not require authentication.
4) Set the issuer property of the wsFederation element within the Microsoft.IdentityModel section of your web.config to the login page.

What you want to do is an active signin. WIF includes WSTrustChannel(Factory) which allows you to communicate directly with the STS and obtain a security token. If you want your login form to work this way, you can follow the "WSTrustChannel" sample from the WIF 4.0 SDK. Once you have obtained the token, the following code will take that token and call the WIF handler to create a session token and set the appropriate cookie:
public void EstablishAuthSession(GenericXmlSecurityToken genericToken)
{
var handlers = FederatedAuthentication.ServiceConfiguration.SecurityTokenHandlers;
var token = handlers.ReadToken(new XmlTextReader(
new StringReader(genericToken.TokenXml.OuterXml)));
var identity = handlers.ValidateToken(token).First();
// create session token
var sessionToken = new SessionSecurityToken(
ClaimsPrincipal.CreateFromIdentity(identity));
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
}
Once you have done this, your site ought to behave the same as if passive signing had occurred.

You could use the FederatedPassiveSignIn Control.

Setting your cookie like this:
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
Doens't work for SSO to other domains.
To cookie should be set by the STS not at the RP.

Related

How can I include authentication in api endpoint in .NET 6 web app with identity

I have a ASP.NET Core 6 web app. I'm using Identity for an authentication. It is in its simplest form - users need to put credentials in the login page to access parts of aplication.
Now I need to expose one endpoint. It should be accessible by application from a different server. Therefore a solution with redirection to a login page and storing credential in caches doesn't make sense (keep in mind I want to keep it, just add some filtering on a particular api).
Instead I would prefer to allow hitting this enpoint with some kind of token. Another solution that comes to my mind is to whitelist the server of the application not to require authorization.
I don't know which of these are possible or recommended. Will gladly hear your advices.

How to handle authorization and authentication on SPA with OAuth2?

I am developing an SPA and would like to have SSO.
As I understood so far, OAuth2 with OIDC is the best solution for SPA SSO.
Better than, for example, SAML.
What I didn't understand so far is how to use authorization token in SPA's JS code to handle authorization on various resources of SPA. For example, I would like the users with a role 'buyer' to have access to the shopping history tab, where other users won't have access to.
Should I parse access token obtained from Authorization server in JS code and check whether a user has an appropriate role to see the tab, or should this decision be made on server (API) side, in which case SPA's code would just read the answer from API and based on that customize UI?
In case of the first approach, is there any standard way of doing the checking (in form of some JS library)?
When it comes to authentication, what is the better approach (more secure, etc):
to let SPA (at that point already loaded in the browser) do the authentication flow and based on result let the user use it's protected functionalities. This is pseudo authentication actually since the code is in the user's browser and means the user is authenticating himself to the code in his hands i.e. to himself. Does this authentication make sense at all?
require the user to authenticate himself in order to be able to even load the SPA in his browser. This is probably not SPA architecture then since backend which serves the SPA should be able to create a backchannel with the Authentication server.
According to user description, your application must vary depending on user type. If this is the case I would suggest you to use a backend for authentication and decide application content to be served from the backend. Otherwise, as you have figured out, running authentication on browser and altering user view is not secure.
IMO this not necessarily break SPA architecture. What you are doing is altering what you server based on tokens presented to you. Also, maintaining a session will be required with this approach. And SPA's calls for backend will require to contain this session to obtain contents.
As soon as the User is logged in, you would request for authentication and based on his UserId, and the role he belongs to you should receive all the permissions that User is entitled to.
You convert these permissions into claims and can send them back to UI and use it appropriately to show the features accordingly.
You also enforce same on the server side api to prevent any unauthorized access besides from your UI.

How to integrate OAuth with a single page application?

When using OAuth (2) I need a redirection endpoint in my application that the OAuth-offering service can redirect to, once I have been authenticated.
How do I handle this in a single page application? Of course, a redirect to the OAuth-offering service is not nice here, and it may not even be possible to redirect back.
I know that OAuth also supports a username / password based token generation. This works perfectly with an AJAX call, but requires my single page application to ask for a username and password.
How do you usually handle this?
Most of the time, a redirect is okay even for SPA because users don't like to put their X service credentials on any other website than X. An alternative will be to use an small popup window, you can check what Discourse does. IMHO a redirect is better than a popup.
Google Some providers support the resource owner flow which is what you described as sending username and password, but this is not nice. These are the problems I see:
Asking google credentials to users in your site will be a no-go for some users.
The resource owner flows need the client_secret too and this is something that you must NOT put in your client side javascript. If you instantiate the resource owner flow from your server-side application and your application is not in the same geographically region than the user, the user will get a warning "hey someone is trying to access with your credentials from India".
OAuth describes a client-side flow called implicit flow. Using this flow you don't need any interaction in your server-side and you don't need the client_secret. The OAuth provider redirects to your application with a "#access_token=xx". It is called implicit because you don't need to exchange authorization code per access token, you get an access_token directly.
Google implement the implicit flow, check: Using OAuth2 for Client-Side apps.
If you want to use the implicit flow with some provider that doesn't support it like Github, you can use an authentication broker like Auth0.
disclaimer: I work for Auth0.
What José F. Romaniello said is correct. However, your question is broad and thus I feel any offered conclusions are just generalities at this point.
Application state
For example, without knowing how complex your application state is at the time you want to let your users log in, nobody can know for sure if using a redirection is even practical at all. Consider that you might be willing to let the user log in very late in his workflow/application usage, at a point where your application holds state that you really don't want to serialize and save for no good reason. Let alone write code to rebuild it.
Note: You will see plenty of advice to simply ignore this on the web. This is because many people store most of the state of their application in server-side session storage and very little on their (thin) client. Sometimes by mistake, sometimes it really makes sense -- be sure it does for you if you choose to ignore it. If you're developing a thick client, it usually doesn't.
Popup dialogs
I realize that popups have a bad rep on the web because of all their misuses, but one has to consider good uses. In this case, they serve exactly the same purposes as trusted dialogs in other types of systems (think Windows UAC, fd.o polkit, etc). These interfaces all make themselves recognizable and use their underlying platform's features to make sure that they can't be spoofed and that input nor display can't be intercepted by the unprivileged application. The exact parallel is that the browser chrome and particularly the certificate padlock can't be spoofed, and that the single-origin policy prevents the application from accessing the popup's DOM. Interaction between the dialog (popup) and the application can happen using cross-document messaging or other techniques.
This is probably the optimal way, at least until the browsers somehow standardize privilege authorization, if they ever do. Even then, authorization processes for certain resource providers may not fit standardized practices, so flexible custom dialogs as we see today may just be necessary.
Same-window transitions
With this in mind, it's true that the aesthetics behind a popup are subjective. In the future, browsers might provide APIs to allow a document to be loaded on an existing window without unloading the existing document, then allow the new document to unload and restore the previous document. Whether the "hidden" application keeps running or is frozen (akin to how virtualization technologies can freeze processes) is another debate. This would allow the same procedure than what you get with popups. There is no proposal to do this that I know of.
Note: You can simulate this by somehow making all your application state easily serializable, and having a procedure that stores and restores it in/from local storage (or a remote server). You can then use old-school redirections. As implied in the beginning though, this is potentially very intrusive to the application code.
Tabs
Yet another alternative of course is to open a new tab instead, communicate with it exactly like you would a popup, then close it the same way.
On taking user credentials from the unprivileged application
Of course it can only work if your users trust you enough not to send the credentials to your server (or anywhere they don't want them to end up). If you open-source your code and do deterministic builds/minimization, it's theoretically possible for users to audit or have someone audit the code, then automatically verify that you didn't tamper with the runtime version -- thus gaining their trust. Tooling to do this on the web is nonexistent AFAIK.
That being said, sometimes you want to use OAuth with an identity provider under you control/authority/brand. In this case, this whole discussion is moot -- the user trusts you already.
Conclusion
In the end, it comes down to (1) how thick your client is, and (2) what you want the UX to be like.
OAuth2 has 4 flows a.k.a. grant types, each serving a specific purpose:
Authorization Code (the one you alluded to, which requires redirection)
Implicit
Client Credential
Resource Owner Password Credential
The short answer is: use Implicit flow.
Why? Choosing a flow or grant type relies on whether any part of your code can remain private, thus is capable of storing a secret key. If so, you can choose the most secure OAuth2 flow - Authorization Code, otherwise you will need to compromise on a less secure OAuth2 flow. e.g., for single-page application (SPA) that will be Implicit flow.
Client Credential flow only works if the web service and the user are the same entity, i.e., the web service serves only that specific user, while Resource Owner Password Credential flow is least secure and used as last resort since the user is required to give her social login credentials to the service.
To fully understand the difference between recommended Implicit flow and Authorization Code flow (the one that you alluded to and requires redirection), take a look at the flow side-by-side:
This diagram was taken from: https://blog.oauth.io/introduction-oauth2-flow-diagrams/

Claim based security with MVC custom login page

I am developing MVC application and want to use WIF & Claim based security.
However I am very disappointed with the way login is perfomed. I mean redirection to STS login page and then redirecting back to my page. That is not user-friendly at all.
I want to implement login page in my application (it fact it will be popup dialog). Than using Web API I want to be able to perform STS request and get security token and initialize WIF infrastructure (Principle etc).
Is it a good way to go with?
Did anybody do something similar?
Does anybody have some samples of what I am trying to do?
I just worry that I don't have control over the STS login page layout & style.
Also I will have mobile application and must perform login using Web API service.
What can you advice?
Thanks
Well - you can do that of course. This does not need to be WIF specific. Call a service, pass credentials - and when OK set the login cookie.
But if you want SSO you have to make a user agent roundtrip to the STS - otherwise you cannot establish a logon session.
Consider using MembershipReboot membership provider which uses claims-based security and is not based on microsoft's traditional membership provider.
It does not have a documentation, but in the zip file you can find 2 sample projects that uses MemebershipReboot provider, which explains all you need to know about it.
In fact after reading this blog post today, I decided to use this approach in my current project. I'm still struggling with it now and I'm so excited !
In addition to Ashkan's recommendation Brock Allen provides solid documentation about how to implement MembershipReboot in association with IdentityServer. You can find that their is a way to configure a custom implementation Here. Also their are a few tutorials on vimeo from Dominick Baier (leastprivilege) that will provide a full walk through on getting started! I hope this helps!

Will using a master login username and password when implementing web services considered secure

I am working on an asp.net mvc-4 web application and I have started implementing some web services which provides statistical information about my site. But to make sure that only authorized and authenticated consumers can call and consume the web services I am thinking of defining a master login username and password for each consumer, and when a consumer sends a web service request he should include these master login username and password (stored as a hash value ) in the web service calls.
For example the web service link to call specific web service from my web site will look as follow:-
/web/json/statistic/getsummaryinfo/areacode?j_username=masterusername&hash=D012B772672A55A0B561EAA53CA7734E
So my question is whether the approach I am following will provide a secure solution to my web services and to the consumers? OR my approach have security holes I am unaware of ?
:::EDITED::
I am using the WebAPI controllers to implement the web services inside my asp.net mvc-4.**
Best Regards
There are a few ways to make sure things are secure.
http://techcrunch.com/2012/11/08/soa-softwares-api-management-platform-and-how-it-compares-to-its-sexy-counterparts/ This article just came out today highlighting some API tools. I'm not sure how big you are or are planning to be, but if you're looking for scale, these tools seem to be pretty popular (note: I haven't had a large scale API project myself, so I haven't used these).
You can use something like ServiceStack to build your API layer. It has authorization and authentication built in with a boatload of authentication providers. It scales well and, after a call to authenticate, is session-based so you don't have to authenticate each call.
You can use "signed" requests. Signed requests often look something like: "take all the parameters for the request as a querystring, append a 'secret consumer key' to the end of the request', and then sign the request by appending the md5 hash of the results (without the secret key!!) to the request." This is a safe way of doing things because even if the request is made client-side (AJAX) it is generated server-side using a secret key. So you can ensure that things weren't tampered with.
You can go the oauth/token route (which often still uses method #3 above).
You can go with a simple API key that can be revoked (again, fotne used with method #3). bit.ly uses this method I think.
Option #2 is my favorite. I like ServiceStack. But to be honest the learning curve for your first project can be a little steep.
A master username and hashed password feels weak to me, so I'd strongly consider at least looking around at how others are doing it.
HTH
I do not consider your way to be safe. If I could listen on the wire and cache the request I will have the login an the password to the service. There even does not matter if the password is hashed or not. I like the point 3. in Eli Gassert's answer. It sounds very useful and light weight and you are not exposing the password because it is hashed "somewhere" in the request.

Resources