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”);
}

This entry was posted in IdentityModel. Bookmark the permalink.

15 Responses to Using an Active Endpoint to sign into a Web Application

  1. Bert Weersel says:

    It is ridiculous that nobody dares to say anything about what is happening here – that we let someone leave a code which does not work….

    “Ohhhh, everybody knows it is not his fault that the brackets are formatted as opening and closing brackets”…. true, but if you sum it up with the idiotic addresses – it proofs the code is wrong….

    Nowhere is mentioned which usings are to be defined – if you’d paste code, not one, not two, but a bunch of errors show up…….!……. THANKS for the code – it does NOT work

    Oh….. it’s free, so I should be offended?!…. That’s the reason!

  2. Seems Bert can only complain.

    Dave, the code is working fine (sorry about the weird encoding, that’s a wordpress issue). As you can see, the code is quite old and uses WIF (which was a standalone library before they rolled those APIs into .NET 4.5).

    Unfortunately Microsoft did decide to not port the bindings to .NET 4.5 – but you can find them here now: https://github.com/IdentityModel/Thinktecture.IdentityModel/tree/master/source/Wcf

  3. oneil says:

    how does sign out works?

    • Since you are not signin in to the token service – there is no signout.

      The token you get back gets typically converted into a local cookie. Deleting that local cookie is your signout.

  4. oneil says:

    Can this work with SSL off?

  5. Paul says:

    I’m doing this in one application. Seems to work, as far as the returned token identity has IsAuthenticated set to true and I’m writing a new Claims Principal (identity) to a session token, however, if I then attempt to access the actual ADFS server front-end Sign On page, it acts as if I’m not authenticated at all with ADFS and asks I sign in. Same with any relaying party trust sites that are setup and working with ADFS, they also act as if I’m not logged in even though the token came back successfully and wrote the FedAuth response cookie. I was under the impression that this cookie signifies I’m already authenticated with ADFS and thus any other site should see that cookie and allow me through as SSO is supposed to work.

    Is there something else I need to be doing after FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken) ?
    Why is my FedAuth cookie not signifying me as authenticated with ADFS?

    • You will only get SSO when using the passive/redirect based authentication round-trip.

      It is not about the cookie that you set in your application – it is about the SSO cookie that ADFS sets – but that needs a browser round trip.

      • Paul says:

        Wow, thanks for the quick response.

        How can I do this roundtrip once my user logs into my Application (let’s call it Application Site A) without them physically being taken to the ADFS sign in page and signing in?

        I want to maintain users to my Application Site A using it’s own sign in page, not the ADFS Sign in page, but have SSO work across sites setup as relaying party trusts with ADFS… So if a user is in my Application Site A and links to Application Site B (that’s also a RPT with ADFS) it takes them directly into the site….

    • Paul says:

      Well that stinks. I’m not quite understanding why authenticating through an endpoint to ADFS doesn’t allow for SSO? Why can’t ADFS generate the same thing/cookie on its end when authenticating through an endpoint that it does when using the passive/redirect authentication method?

      to better understand our scenario: our application has two target audiences, one audience has ADFS (Active Directory domain) credentials, the other audience does not (sql database stored users), thus why we need to use the Application’s sign in screen, not just the ADFS sign in screen.

      Also, is there any way then I can check in my Application if the user is authenticated with ADFS without ADFS sending them to its sign on page if they’re not? i.e. I’d like to to check if the user is authenticated with ADFS first, if not then give the user a message about going to ADFS to sign in, if they are already authenticated it will just give the user the list of links to the other relaying party trusts sites. In this way we can atleast provide more informative information than attempting to do the same through the somewhat customizabled ADFS sign on page….

  6. Paul says:

    @Dominick, thanks for the information. I greatly appreciate it. Since this is not doable we will look into alternative ideas.

  7. Paul says:

    how can I adjust your code above to specifically return a SAML token instead of a generic one?

  8. The TokenXml has the raw XML – you can then use a SAML token handler to read that and turn it into a SAML token CRL type.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s