BUG With FormsAuthentication

Discussion in 'ASP .Net Security' started by Faassen, B., Aug 6, 2004.

  1. Faassen, B.

    Faassen, B. Guest

    The authentication cookie with custom user is not available or the user data is gone after a redirect.
    In other words all the examples on the net on how to do custom FormsAuthentication don't work!

    Is there a workaround for this?

    Barry
    Software Engineer
    Hogeschool Rotterdam
    The Netherlands
     
    Faassen, B., Aug 6, 2004
    #1
    1. Advertising

  2. Faassen, B.

    Raterus Guest

    There is no bug this major with formsauthentication, perhaps you can provide us more details/code as to what you are doing and we will try to tell you what you are doing wrong.

    "Faassen, B." <> wrote in message news:...
    > The authentication cookie with custom user is not available or the user data is gone after a redirect.
    > In other words all the examples on the net on how to do custom FormsAuthentication don't work!
    >
    > Is there a workaround for this?
    >
    > Barry
    > Software Engineer
    > Hogeschool Rotterdam
    > The Netherlands
     
    Raterus, Aug 6, 2004
    #2
    1. Advertising

  3. Hello

    Well I have implemented the IPrincipal and IIdentity interfaces. The
    resulting classes are CustomPrincipal wich has a static Login member and
    uses LDAP to authenticate and retrieves the user info stored in a
    stucture if the login was succesfull. This works fine. No I want to Use
    the Principal wich holds all the struct and other info like roles etc.
    in my ASP.NET application. One way to do this is to generate a ticket
    encrypt it and store the principal in a auth. cookie. Then add this
    cookie to the Coookies collection. From this I do a redirect to the page
    the user requested. In the Global.ASX I have implemented a event member
    AcquireRequestState. In this member I trie to get the auth. cookie I
    just generated and decrypt the ticket and decrypt the principal wich
    should be stored in the ticket. After retrieving the Principal I can set
    it on the HttpContext.Current.User and go on..
    But first of all there is no cookie to get in the Global.ASAX. I never
    get a cookie back except when I use FormsAuthenticate.SetAuthCookie(..)
    in the Login handler
    but I cant use this cookie because its empty.. If I generate the cookie
    on another way the cookie will be lost after Response.Redirect(..)

    I folowed the example of R. Lhotka which has a nice article about
    authentication. I also used examples found in the VS.2003 MSDN docs. I
    also tried some other examples but all give the same result. My cookie
    will be lost somewhere.
    Another trick I tried is to add an extra cookie and first call
    FormsAuthencation.SetAuthCookie(..) and then create a new one add this
    cookie to the collection ... In this case I will get a cookie back but
    then again it is empty..

    Here is my code:

    public static void RedirectFromLoginPage( CustomPrincipal principal )
    {
    string principalText;
    bool persistCookie = false;
    if ( principal != null ) {
    // Encrypt the principal so it can be safely stored
    // in a cookie
    principalText = CustomAuthentication.Encrypt( principal );

    HttpCookie cookie = FormsAuthentication.GetAuthCookie(
    principal.Identity.Name, false );
    FormsAuthenticationTicket ticket =
    FormsAuthentication.Decrypt(cookie.Value);
    FormsAuthenticationTicket newticket = new FormsAuthenticationTicket(
    ticket.Version,
    ticket.Name,
    ticket.IssueDate,
    ticket.Expiration,
    ticket.IsPersistent,
    principalText, ticket.CookiePath);
    cookie.Value = FormsAuthentication.Encrypt(newticket);
    cookie.Expires = ticket.Expiration;
    HttpContext.Current.Response.Cookies.Set( cookie );

    HttpContext.Current.Response.Redirect(
    FormsAuthentication.GetRedirectUrl(
    newticket.Name,
    newticket.IsPersistent )
    );
    }

    public static string Encrypt(CustomPrincipal principal)
    {
    MemoryStream buffer;
    IFormatter formatter;
    string principalText = string.Empty;
    if ( principal != null )
    {
    buffer = new MemoryStream();
    formatter = new BinaryFormatter();
    formatter.Serialize(buffer, principal);
    buffer.Position = 0;
    principalText = Convert.ToBase64String( buffer.GetBuffer() );
    }
    return principalText;
    }

    public static CustomPrincipal Decrypt( string encryptedInput )
    {
    CustomPrincipal principal = null;
    MemoryStream buffer = new MemoryStream( Convert.FromBase64String(
    encryptedInput ) );
    BinaryFormatter formatter = new BinaryFormatter();
    principal = (CustomPrincipal)formatter.Deserialize( buffer );
    return principal;

    }

    private void Global_AcquireRequestState(object sender, EventArgs e)
    {
    HttpCookie cookie =
    Request.Cookies.Get(FormsAuthentication.FormsCookieName);
    if ( cookie != null )
    {
    FormsAuthenticationTicket ticket =
    FormsAuthentication.Decrypt(cookie.Value);
    if ( ticket.Expired )
    {
    FormsAuthentication.SignOut();
    Response.Redirect("login.aspx");
    }
    else
    {
    IPrincipal principal = CustomAuthentication.Decrypt( ticket.UserData );
    HttpContext.Current.User = principal;
    Thread.CurrentPrincipal = HttpContext.Current.User;
    }
    }
    }

    *** Sent via Developersdex http://www.developersdex.com ***
    Don't just participate in USENET...get rewarded for it!
     
    Barry Faassen, Aug 6, 2004
    #3
  4. Faassen, B.

    Raterus Guest

    If you are having a dissapearing cookie problem, I'd ensure the path of the cookie is set how you would like it. Setting the path to "/" is probably best to make sure this isn't the problem. Also where is this redirect going? Same site, same domain? if you are using cookies it is going to have to be at least the same down to the second level domain. You can't use forms authentication on www.domain1.com and have it will work when you move over to www.domain2.com.

    Just some thoughts,
    --Michael

    "Barry Faassen" <> wrote in message news:...
    >
    > Hello
    >
    > Well I have implemented the IPrincipal and IIdentity interfaces. The
    > resulting classes are CustomPrincipal wich has a static Login member and
    > uses LDAP to authenticate and retrieves the user info stored in a
    > stucture if the login was succesfull. This works fine. No I want to Use
    > the Principal wich holds all the struct and other info like roles etc.
    > in my ASP.NET application. One way to do this is to generate a ticket
    > encrypt it and store the principal in a auth. cookie. Then add this
    > cookie to the Coookies collection. From this I do a redirect to the page
    > the user requested. In the Global.ASX I have implemented a event member
    > AcquireRequestState. In this member I trie to get the auth. cookie I
    > just generated and decrypt the ticket and decrypt the principal wich
    > should be stored in the ticket. After retrieving the Principal I can set
    > it on the HttpContext.Current.User and go on..
    > But first of all there is no cookie to get in the Global.ASAX. I never
    > get a cookie back except when I use FormsAuthenticate.SetAuthCookie(..)
    > in the Login handler
    > but I cant use this cookie because its empty.. If I generate the cookie
    > on another way the cookie will be lost after Response.Redirect(..)
    >
    > I folowed the example of R. Lhotka which has a nice article about
    > authentication. I also used examples found in the VS.2003 MSDN docs. I
    > also tried some other examples but all give the same result. My cookie
    > will be lost somewhere.
    > Another trick I tried is to add an extra cookie and first call
    > FormsAuthencation.SetAuthCookie(..) and then create a new one add this
    > cookie to the collection ... In this case I will get a cookie back but
    > then again it is empty..
    >
    > Here is my code:
    >
    > public static void RedirectFromLoginPage( CustomPrincipal principal )
    > {
    > string principalText;
    > bool persistCookie = false;
    > if ( principal != null ) {
    > // Encrypt the principal so it can be safely stored
    > // in a cookie
    > principalText = CustomAuthentication.Encrypt( principal );
    >
    > HttpCookie cookie = FormsAuthentication.GetAuthCookie(
    > principal.Identity.Name, false );
    > FormsAuthenticationTicket ticket =
    > FormsAuthentication.Decrypt(cookie.Value);
    > FormsAuthenticationTicket newticket = new FormsAuthenticationTicket(
    > ticket.Version,
    > ticket.Name,
    > ticket.IssueDate,
    > ticket.Expiration,
    > ticket.IsPersistent,
    > principalText, ticket.CookiePath);
    > cookie.Value = FormsAuthentication.Encrypt(newticket);
    > cookie.Expires = ticket.Expiration;
    > HttpContext.Current.Response.Cookies.Set( cookie );
    >
    > HttpContext.Current.Response.Redirect(
    > FormsAuthentication.GetRedirectUrl(
    > newticket.Name,
    > newticket.IsPersistent )
    > );
    > }
    >
    > public static string Encrypt(CustomPrincipal principal)
    > {
    > MemoryStream buffer;
    > IFormatter formatter;
    > string principalText = string.Empty;
    > if ( principal != null )
    > {
    > buffer = new MemoryStream();
    > formatter = new BinaryFormatter();
    > formatter.Serialize(buffer, principal);
    > buffer.Position = 0;
    > principalText = Convert.ToBase64String( buffer.GetBuffer() );
    > }
    > return principalText;
    > }
    >
    > public static CustomPrincipal Decrypt( string encryptedInput )
    > {
    > CustomPrincipal principal = null;
    > MemoryStream buffer = new MemoryStream( Convert.FromBase64String(
    > encryptedInput ) );
    > BinaryFormatter formatter = new BinaryFormatter();
    > principal = (CustomPrincipal)formatter.Deserialize( buffer );
    > return principal;
    >
    > }
    >
    > private void Global_AcquireRequestState(object sender, EventArgs e)
    > {
    > HttpCookie cookie =
    > Request.Cookies.Get(FormsAuthentication.FormsCookieName);
    > if ( cookie != null )
    > {
    > FormsAuthenticationTicket ticket =
    > FormsAuthentication.Decrypt(cookie.Value);
    > if ( ticket.Expired )
    > {
    > FormsAuthentication.SignOut();
    > Response.Redirect("login.aspx");
    > }
    > else
    > {
    > IPrincipal principal = CustomAuthentication.Decrypt( ticket.UserData );
    > HttpContext.Current.User = principal;
    > Thread.CurrentPrincipal = HttpContext.Current.User;
    > }
    > }
    > }
    >
    > *** Sent via Developersdex http://www.developersdex.com ***
    > Don't just participate in USENET...get rewarded for it!
     
    Raterus, Aug 6, 2004
    #4
  5. Watch out for the cookie size of you store custom info inside the FormsAuth
    ticket.
    Check out this posts:

    http://weblogs.asp.net/hernandl/archive/2004/07/30/FormsAuthRolesRev.aspx
    http://weblogs.asp.net/hernandl/archive/2004/08/05/FormsAuthRoles2.aspx

    Regards.
    --
    Hernan de Lahitte
    Lagash Systems S.A.
    http://weblogs.asp.net/hernandl


    This posting is provided "AS IS" with no warranties, and confers no rights.

    "Raterus" <> wrote in message
    news:...
    If you are having a dissapearing cookie problem, I'd ensure the path of the
    cookie is set how you would like it. Setting the path to "/" is probably
    best to make sure this isn't the problem. Also where is this redirect
    going? Same site, same domain? if you are using cookies it is going to
    have to be at least the same down to the second level domain. You can't use
    forms authentication on www.domain1.com and have it will work when you move
    over to www.domain2.com.

    Just some thoughts,
    --Michael

    "Barry Faassen" <> wrote in message
    news:...
    >
    > Hello
    >
    > Well I have implemented the IPrincipal and IIdentity interfaces. The
    > resulting classes are CustomPrincipal wich has a static Login member and
    > uses LDAP to authenticate and retrieves the user info stored in a
    > stucture if the login was succesfull. This works fine. No I want to Use
    > the Principal wich holds all the struct and other info like roles etc.
    > in my ASP.NET application. One way to do this is to generate a ticket
    > encrypt it and store the principal in a auth. cookie. Then add this
    > cookie to the Coookies collection. From this I do a redirect to the page
    > the user requested. In the Global.ASX I have implemented a event member
    > AcquireRequestState. In this member I trie to get the auth. cookie I
    > just generated and decrypt the ticket and decrypt the principal wich
    > should be stored in the ticket. After retrieving the Principal I can set
    > it on the HttpContext.Current.User and go on..
    > But first of all there is no cookie to get in the Global.ASAX. I never
    > get a cookie back except when I use FormsAuthenticate.SetAuthCookie(..)
    > in the Login handler
    > but I cant use this cookie because its empty.. If I generate the cookie
    > on another way the cookie will be lost after Response.Redirect(..)
    >
    > I folowed the example of R. Lhotka which has a nice article about
    > authentication. I also used examples found in the VS.2003 MSDN docs. I
    > also tried some other examples but all give the same result. My cookie
    > will be lost somewhere.
    > Another trick I tried is to add an extra cookie and first call
    > FormsAuthencation.SetAuthCookie(..) and then create a new one add this
    > cookie to the collection ... In this case I will get a cookie back but
    > then again it is empty..
    >
    > Here is my code:
    >
    > public static void RedirectFromLoginPage( CustomPrincipal principal )
    > {
    > string principalText;
    > bool persistCookie = false;
    > if ( principal != null ) {
    > // Encrypt the principal so it can be safely stored
    > // in a cookie
    > principalText = CustomAuthentication.Encrypt( principal );
    >
    > HttpCookie cookie = FormsAuthentication.GetAuthCookie(
    > principal.Identity.Name, false );
    > FormsAuthenticationTicket ticket =
    > FormsAuthentication.Decrypt(cookie.Value);
    > FormsAuthenticationTicket newticket = new FormsAuthenticationTicket(
    > ticket.Version,
    > ticket.Name,
    > ticket.IssueDate,
    > ticket.Expiration,
    > ticket.IsPersistent,
    > principalText, ticket.CookiePath);
    > cookie.Value = FormsAuthentication.Encrypt(newticket);
    > cookie.Expires = ticket.Expiration;
    > HttpContext.Current.Response.Cookies.Set( cookie );
    >
    > HttpContext.Current.Response.Redirect(
    > FormsAuthentication.GetRedirectUrl(
    > newticket.Name,
    > newticket.IsPersistent )
    > );
    > }
    >
    > public static string Encrypt(CustomPrincipal principal)
    > {
    > MemoryStream buffer;
    > IFormatter formatter;
    > string principalText = string.Empty;
    > if ( principal != null )
    > {
    > buffer = new MemoryStream();
    > formatter = new BinaryFormatter();
    > formatter.Serialize(buffer, principal);
    > buffer.Position = 0;
    > principalText = Convert.ToBase64String( buffer.GetBuffer() );
    > }
    > return principalText;
    > }
    >
    > public static CustomPrincipal Decrypt( string encryptedInput )
    > {
    > CustomPrincipal principal = null;
    > MemoryStream buffer = new MemoryStream( Convert.FromBase64String(
    > encryptedInput ) );
    > BinaryFormatter formatter = new BinaryFormatter();
    > principal = (CustomPrincipal)formatter.Deserialize( buffer );
    > return principal;
    >
    > }
    >
    > private void Global_AcquireRequestState(object sender, EventArgs e)
    > {
    > HttpCookie cookie =
    > Request.Cookies.Get(FormsAuthentication.FormsCookieName);
    > if ( cookie != null )
    > {
    > FormsAuthenticationTicket ticket =
    > FormsAuthentication.Decrypt(cookie.Value);
    > if ( ticket.Expired )
    > {
    > FormsAuthentication.SignOut();
    > Response.Redirect("login.aspx");
    > }
    > else
    > {
    > IPrincipal principal = CustomAuthentication.Decrypt( ticket.UserData );
    > HttpContext.Current.User = principal;
    > Thread.CurrentPrincipal = HttpContext.Current.User;
    > }
    > }
    > }
    >
    > *** Sent via Developersdex http://www.developersdex.com ***
    > Don't just participate in USENET...get rewarded for it!
     
    Hernan de Lahitte, Aug 6, 2004
    #5
  6. Faassen, B.

    Faassen, B. Guest

    Sorry but I still say there is a BUG in the FormsAuthentication class, because it still works like shit.

    On some browsers it works and on some it doesnt!
     
    Faassen, B., Aug 30, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. fadi
    Replies:
    1
    Views:
    507
  2. TaeHo Yoo
    Replies:
    1
    Views:
    523
    Teemu Keiski
    Jul 9, 2003
  3. Jeff Johnson
    Replies:
    6
    Views:
    3,762
    tharadk
    Jul 24, 2009
  4. Tommy
    Replies:
    1
    Views:
    2,073
    S. Justin Gengo
    Aug 7, 2003
  5. Mark Olbert
    Replies:
    19
    Views:
    701
    Mark Olbert
    Jan 17, 2004
Loading...

Share This Page