Wednesday, April 14, 2010

Using an Active Endpoint to sign into a Web Application

This question comes up from time to time, so I thought I’ll document it here.

The scenario is, that you don’t want to do a passive redirect in a web app – but directly talk to an active STS endpoint to authenticate and request a token. The reasons for that could be that you need a local sign-in page in the web app – or that the token service is not publicly reachable.

The following code can be used on a login page:

protected void _btnLogin_Click(object sender, EventArgs e)
{
    // authenticate with WS-Trust endpoint
    var factory = new WSTrustChannelFactory(
        new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
        new EndpointAddress("https://sts/endpoint"));

   
factory.Credentials.UserName.UserName = _txtUserName.Text;
    factory.Credentials.UserName.Password = _txtPassword.Text;
 
    var channel = factory.CreateChannel();
 
    var rst = new RequestSecurityToken
    {
        RequestType = RequestTypes.Issue,
        AppliesTo = new EndpointAddress("https://rp/"),
        KeyType = KeyTypes.Bearer
    };
 
    var genericToken = channel.Issue(rst) as GenericXmlSecurityToken;
 
    // parse token
    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);
 
    Response.Redirect("~/users/default.aspx");
}


IdentityModel
Wednesday, April 14, 2010 12:51:50 PM UTC  #