none
Newbie: After successful authentication and redirect, how to get the unique token?

    Question

  • Hello,

    After a successful login and ACS has redirected to our asp.net webpage, how can I get the unique token for the authenticated user? Do you know where I can read about this part of the process, in detail?

    Thanks,

    Mike

    Thursday, June 14, 2012 11:56 PM

Answers

  • After a ton of research and experimentation, I have answered these questions...

    Q1) Is it possible to get a persistent, unqiue identifier for a user who has been authenticated through ACS?

    Azure ACS does support SAML 2.0, so it can provide the nameidentifier value to your application for the authentication provider.  When you "Add STS References..." to

    your Visual Studio project, it created a file in your project named "Federation Metadata.xml".  Open this file and add the following line to the end of the

    <fed:ClaimTypesRequested> list:

    <auth:ClaimType Uri="http://schemas.microsoft.com/ws/2008/06/identity/claims/nameidentifier" Optional="false" xmlns:auth="http://docs.oasis-

    open.org/wsfed/authorization/200706" />

    So, now you will receive this item in the claims that are returned after logging into an authentication provider.  So, how do you access the nameidentifer value?  In

    your .aspx.cs file that will be accessed after authentication:

    Add the following namespace:
    using Microsoft.IdentityModel.Claims;

    In your method where you will verify the authentication, do the following:

                if (HttpContext.Current.User.Identity.IsAuthenticated)
                {
                    // Cast the Thread.CurrentPrincipal
                    IClaimsPrincipal icp = Thread.CurrentPrincipal as IClaimsPrincipal;

                    // Access IClaimsIdentity which contains claims
                    IClaimsIdentity claimsIdentity = (IClaimsIdentity)icp.Identity;

                    // Access claims
                    foreach (Claim claim in claimsIdentity.Claims)
                    {
                        if (claim.ClaimType.CompareTo(@"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier") == 0)
                        {
                            // Okay, let's get the persistent name identifier...
                            string nameId = claim.Value;
       .
       .
       .
                        }
                    }

    I know that Google ensures that the nameidentifier will be persistent and unique for the user unless you change the domain name that you've assigned when signing up

    for authentication services for your domain on their website.  We are only using Google for authentication at this time, so we have resolved our issue with the

    changes that I have mentioned.  A quick look at the results from logging into Live! and Yahoo! is that I am getting sensible nameidentifier values, but I do not know

    for a fact that they are persistent and if they are persistent or under what conditions they may change.  Hopefully, another user will post info for Live! and Yahoo!

    Q2) How to completely log out (i.e. completely log out of Google)
    There is a lot of confusion out there about this issue.  From what I have read, it is not the intention, at this time, to provide the ability to log out of the

    authentication provider when leaving our application because it would affect a user's other sessions in which they signed in using the same authentication provider. 

    So, we are experimenting with passing the following POPE Extensions when authentication has begun so that when the user logs out of our application, he/she must

    enter a password to access it again.

    openid.ns.pape
    openid.pape.max_auth_age

    This seems like a reasonable approach, if it works...

    Here is where we are at with our logout process, but we are still working on it...
    using Microsoft.IdentityModel.Web;
    using System.Web.Security;
    .
    .
    .
                    if (FederatedAuthentication.SessionAuthenticationModule != null)
                    {                  
                        FederatedAuthentication.SessionAuthenticationModule.CookieHandler.Delete();
                        FederatedAuthentication.SessionAuthenticationModule.DeleteSessionTokenCookie();
                        FederatedAuthentication.WSFederationAuthenticationModule.SignOut(false);
                        FormsAuthentication.SignOut();

                        // Redirect to our login page?
                    }


    Please note that I am simply posting this information in the hope that it may help others...  I am not saying that my solution is the best or only one.  It simply

    meets our requirements. 

    Thanks,

    Mike

     

    • Marked as answer by A Bit of Help Saturday, June 16, 2012 10:29 PM
    Saturday, June 16, 2012 10:29 PM

All replies

  • So, I've found a little more information...  I've created the following function in Global.asax.  It is invoked by ASP.NET after STS authentication and the Session has been established.  This is working, but I still need to determine how to make a unique identifier out of the authentication token, which I can use in our application to recognize an authorized user.

    Help, please! :)

    Mike

    protected void Session_Start(object sender, EventArgs e){        
    if (this.Context.User.Identity.IsAuthenticated){ 
    // At this point we can access the authenticated user information            
    var id = this.Context.User.Identity;        
    }

    Friday, June 15, 2012 5:22 AM
  • Hi,

    Do you want to get token string in the ASP.NET page? Token is unique but include some user info (such username).

    From the Request.Form property when you log in (Please set a break point for view it), you will find Token and ACS information with it (you need decode it for several time, url decode or base 64 decode).

    Hope this helps.


    Please mark the replies as answers if they help or unmark if not. If you have any feedback about my replies, please contact msdnmg@microsoft.com Microsoft One Code Framework

    Friday, June 15, 2012 9:09 AM
    Moderator
  • Hi Arwind,

    I kind of addressed this question in the other posting that I answered for you...

    Basically, I need a persistent, unique identifier from ACS that is similar to OpenId's claimed property.  Is there such a thing?

    Thank you for your help!

    Mike

    Friday, June 15, 2012 6:11 PM
  • After a ton of research and experimentation, I have answered these questions...

    Q1) Is it possible to get a persistent, unqiue identifier for a user who has been authenticated through ACS?

    Azure ACS does support SAML 2.0, so it can provide the nameidentifier value to your application for the authentication provider.  When you "Add STS References..." to

    your Visual Studio project, it created a file in your project named "Federation Metadata.xml".  Open this file and add the following line to the end of the

    <fed:ClaimTypesRequested> list:

    <auth:ClaimType Uri="http://schemas.microsoft.com/ws/2008/06/identity/claims/nameidentifier" Optional="false" xmlns:auth="http://docs.oasis-

    open.org/wsfed/authorization/200706" />

    So, now you will receive this item in the claims that are returned after logging into an authentication provider.  So, how do you access the nameidentifer value?  In

    your .aspx.cs file that will be accessed after authentication:

    Add the following namespace:
    using Microsoft.IdentityModel.Claims;

    In your method where you will verify the authentication, do the following:

                if (HttpContext.Current.User.Identity.IsAuthenticated)
                {
                    // Cast the Thread.CurrentPrincipal
                    IClaimsPrincipal icp = Thread.CurrentPrincipal as IClaimsPrincipal;

                    // Access IClaimsIdentity which contains claims
                    IClaimsIdentity claimsIdentity = (IClaimsIdentity)icp.Identity;

                    // Access claims
                    foreach (Claim claim in claimsIdentity.Claims)
                    {
                        if (claim.ClaimType.CompareTo(@"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier") == 0)
                        {
                            // Okay, let's get the persistent name identifier...
                            string nameId = claim.Value;
       .
       .
       .
                        }
                    }

    I know that Google ensures that the nameidentifier will be persistent and unique for the user unless you change the domain name that you've assigned when signing up

    for authentication services for your domain on their website.  We are only using Google for authentication at this time, so we have resolved our issue with the

    changes that I have mentioned.  A quick look at the results from logging into Live! and Yahoo! is that I am getting sensible nameidentifier values, but I do not know

    for a fact that they are persistent and if they are persistent or under what conditions they may change.  Hopefully, another user will post info for Live! and Yahoo!

    Q2) How to completely log out (i.e. completely log out of Google)
    There is a lot of confusion out there about this issue.  From what I have read, it is not the intention, at this time, to provide the ability to log out of the

    authentication provider when leaving our application because it would affect a user's other sessions in which they signed in using the same authentication provider. 

    So, we are experimenting with passing the following POPE Extensions when authentication has begun so that when the user logs out of our application, he/she must

    enter a password to access it again.

    openid.ns.pape
    openid.pape.max_auth_age

    This seems like a reasonable approach, if it works...

    Here is where we are at with our logout process, but we are still working on it...
    using Microsoft.IdentityModel.Web;
    using System.Web.Security;
    .
    .
    .
                    if (FederatedAuthentication.SessionAuthenticationModule != null)
                    {                  
                        FederatedAuthentication.SessionAuthenticationModule.CookieHandler.Delete();
                        FederatedAuthentication.SessionAuthenticationModule.DeleteSessionTokenCookie();
                        FederatedAuthentication.WSFederationAuthenticationModule.SignOut(false);
                        FormsAuthentication.SignOut();

                        // Redirect to our login page?
                    }


    Please note that I am simply posting this information in the hope that it may help others...  I am not saying that my solution is the best or only one.  It simply

    meets our requirements. 

    Thanks,

    Mike

     

    • Marked as answer by A Bit of Help Saturday, June 16, 2012 10:29 PM
    Saturday, June 16, 2012 10:29 PM
  • +1.  I too wondered about this.  Without a "persistent unique identifier" (as the original poster puts it), how do we tie an authenticated user to his/her data?

    Friday, July 13, 2012 5:51 PM