views:

2151

answers:

4

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?

+6  A: 

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.

Rice Flour Cookies
Thank you for taking the time to answer my question. I've looked through the compiled html help file that comes with the WIF SDK and also gone through all of the examples. I've picked apart the `FAM` and `SessionAuthenticationModule` with Reflector and think I have a good handle on how it's working, but I was interested to see if there are examples using either the `FAM` or maybe a custom HttpModule in conjunction with the `SessionAuthenticationModule` for claims-based identity. The FAM seems to be easy to use, but not provide much flexibility...
Russ Cam
Perhaps the whole idea is that login should be taking place on a web application STS as it means that you don;t need to worry about building a login screen in each of your web applications. However, I'd like to be able to keep a specific look and feel to the login screen for each application and ideally keep it on the same domain so as not to confuse users (which could happen as there are potentially a lot of non-tech savvy users). I just want to take inputted credentials, wrap them up in a WS-Federated call to an STS to authenticate. Is my thinking misaligned with the idea?
Russ Cam
Your thinking is not necessarily misaligned. I started out already having a separate log-on application that is used for other applications; I simply added the STS to the log-on application.I believe that what you want to do is possible, but it will require some experimentation to get it up and running.I've updated my answer with an idea of how you might make this work.
Rice Flour Cookies
@RisingStar-You seem to be well experienced with using WIF with ASP.NET MVC.I am researching using WIF to integrate with a MVC application and a WebForms application. I downloaded the SDK but I am not sure where to start. Each of these apps have their own login page and I'd like to set it up such that any request that goes to the Login page of the first application would be passed over to the STS for authentication and authorization. Once logged onto the first application, users can skip the login page to the second application.Given this scenario,which of the samples do you suggest I look at?
DotnetDude
@DotnetDude, check out the identity "Developer Training Kit" and be sure to check out this discussion if you have problems getting it to work: http://stackoverflow.com/questions/2052386/getting-windows-identity-foundation-developer-training-kit-examples-to-work. There is an example showing how to use WIF to log a user in to more than one web page.
Rice Flour Cookies
+2  A: 

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 undertsand all underlying principles. This blog post covers the specifics of MVC + WIF:

http://blogs.msdn.com/b/eugeniop/archive/2010/04/03/wif-and-mvc-how-it-works.aspx

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

Eugenio Pace
thanks Eugenio, I thought that I'd read the Claims Identity Guide, evidently not as I missed that Fabrikam was an MVC application. I'll be sure to have a look at it again. I've also had a look at Dominick Baier's blog and think that making a call to an active sts from the web server on the login page is ultimately what I'm after.
Russ Cam
I don't see that using WIF in ASP.net MVC is any different than using ASP.net forms.
Rice Flour Cookies
The principles are exactly the same. There are just a few implementation details.The most common differences are:-In a webforms app you typically rely on WIF for all the protocol exchange (passiveRedirectEnable=true). In a MVC app you will turn that off and handle that programmatically as explained in my blog post.- In an MVC app you typically implement an IAuthorizationFilter attribute. In Web forms, that doesn't exist and you simply rely on the existing ASP.NET authorization mechanism (or call IsInRole, etc)
Eugenio Pace
+1  A: 

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.

jlew
A: 

You could use the FederatedPassiveSignIn Control.

Nixie