1

I'm trying to authenticate users based on an existing cookie. I've done something similar in the past by using a custom IIdentity and an IPrincipal

public class CustomIdentity : IIdentity {

    public string Name { get; set; }
    public bool IsAuthenticated { get { return true; } }
    public string AuthenticationType { get { return String.Empty; } }

}

public class CustomPrincipal : IPrincipal {

    private CustomIdentity _identity;
    private string[] _roles;

    public IIdentity Identity {
        get { return _identity; }
    }

    public CustomPrincipal(CustomIdentity identity, string[] roles) {
        _identity = identity;
        _roles = roles;
    }

    public bool IsInRole(string role) {
        return true;
        //TODO
    }
}

I've set up a simple HttpModule to handle the authentication.

public class Authentication : IHttpModule {

    public void Init(HttpApplication application) {
        application.AuthenticateRequest += new EventHandler(Application_AuthenticateRequest);
    }

    private void Application_AuthenticateRequest(object sender, EventArgs e) {
        //TODO: authentication logic here
        CustomIdentity identity = new CustomIdentity();
        CustomPrincipal principal = new CustomPrincipal(identity, new string[] { });
        HttpContext.Current.User = principal;
    }

    public void Dispose() { }
}

When I disallow anonymous users via the web.config the framework is infinitely redirecting to login.aspx even though HttpContext.Current.Request.IsAuthenticated is true after the authentication event.

This happens for authentication modes Windows, Forms and None.

How do I convince the framework that the request is properly authenticated?

Update:

It turns out there was additional code elsewhere which was calling System.Web.Security.FormsAuthentication.SignOut() so my authentication module was setting the principal, sign out was called and the module would fire again. Thus endless redirect loop.

9
  • Are you sure your module is kicking and is loaded in correct order ? Commented Nov 14, 2013 at 16:57
  • Yes I'm hitting breakpoints in the module & inspecting HttpContext.Current.Request.IsAuthenticated Commented Nov 14, 2013 at 17:00
  • You do something wrong regarding Forms. The runtime just doesn't redirect to login.aspx on its own. Commented Nov 14, 2013 at 17:00
  • @WiktorZychla Yes it does. check the default value for LoginUrl msdn.microsoft.com/en-us/library/… Commented Nov 14, 2013 at 17:03
  • Are you sure forms is disabled in web config and in iis configuration? Commented Nov 14, 2013 at 17:15

4 Answers 4

1

In web.config, set the default provider on the membership element to the name of your custom provider:

...
<membership Default="YourDefaultProvider">
<providers>
<clear/>
<add Name="YourDefaultProvider" etc.. />
</providers>
</membership>
Sign up to request clarification or add additional context in comments.

Comments

0

When you set the authentication mode to Forms in your Web.config file, FormsAuthentication class would get in charge of authenticating requests based on a cookie that ASP.NET has created.

Since ASP.NET has its own formula to create authentication tickets, then any other cookie won't pass the authentication.

Since you have your authentication logic and formula to create and read cookies, I think you have two options:

  1. Either disable default authentication of ASP.NET (by not using web.config, and custimizing your authentication mechanism up to 100%, or in fact, writing custom authentication from scratch)
  2. Use ASP.NET formulas to create authentication cookie. To do that you need to use FormsAuthentication.SetAuthenticationCookie method.

4 Comments

That's why I'm creating a custom http module to handle the authentication, I'm not trying to use the default FormsAuthentication.
@Rob2211, you didn't get it. You've used a custom cookie, but based on Web.config's configuration, ASP.NET's default authentication is in action. You need to use FormsAuthentication methods to create, encrypt and decrypt authentication cookies, or you have to forget about Web.config's authentication configuration, and make one yourself.
@SaeedNeamati no he does not want to understand! :D I give it up
He actually follows 1. from your list. He wrote a dummy authentication module from scratch. It has nothing to do with forms authentication, he doesn't even use cookies at the moment.
0

This is only an assumption and I can't validate it at the moment but I believe you can't set the identity with empty name. Your CustomIdentity constructor doesn't set one.

    CustomIdentity identity = new CustomIdentity();
    identity.Name = "foo";

Try this to check the theory and if it works, proceed with further implementation of your custom authentication logic.

5 Comments

Thanks Wiktor, you seem to be the only one who fully understands the problem. Unfortunately settings the name has no effect.
I've verified your approach in VS2012/IIS and it works. User is authenticated as foo, no redirects to any page, no other strange behavior. The approach is fine then, nothing to do with your code, rather, for some reason, IIS still uses forms in the background.
Try this on another, fresh server, also, create a stub solution with only your module and a simple web page. If it works for me, it has to work for you. Then, step by step, find the culprit.
I am using the VS2010 development server, no IIS. I will break out the test case into a fresh project, thanks
Yes you're right, nothing wrong with the code, it works fine in an isolated test case. The culprit was another security module calling System.Web.Security.FormsAuthentication.SignOut() based on different criteria. Recommendations for the SO question?
0

do you remove the asp.net autorization modules?

<authentication mode="None">
 ....
<modules runAllManagedModulesForAllRequests="false">
  <remove name="WindowsAuthentication" />
  <remove name="PassportAuthentication" />
  <remove name="AnonymousIdentification" />
  <remove name="FormsAuthentication" />
  ...
  <add name="myauthmodule" type="myauthmodule" />

are you using UrlAuthorization?

<authorization>
  <allow roles="Admin" />
  <deny users="?" />
  <deny users="*" />
</authorization>

I think that the problem is due to the fact that you are mixing the 2 world of custom autorization and asp.net authorization.

If you want to go this way you have to read your cookie data and then do what asp.net want: a formauthentication cookie

//create ticket
var ticket = new FormsAuthenticationTicket(
        1, // ticket version
        userName,
        DateTime.Now,
        DateTime.Now.Add(timeout), // timeout
        true, // cookie persistent
        roles,
        FormsAuthentication.FormsCookiePath);

// cookie crypt
string hash = FormsAuthentication.Encrypt(ticket);

var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);
cookie.Domain = FormsAuthentication.CookieDomain;

// cookie timeout as ticket timeout
if (ticket.IsPersistent)
{
    cookie.Expires = ticket.Expiration;
}
CurrentContext.Response.Cookies.Add(cookie);
    ....
HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(ticket), roles);

9 Comments

He doesn't have to if the module is setting the principal.
@WiktorZychla it does if you set in web.config to use formauthentication
@giammin I stated that the behavior is exhibited for all forms of authentication, not just Forms
@Rob2211 you implemented only half of the implementation needed to handle authentication. you are mixing your implementation with default asp.net behavior.
I'm not mixing anything. You seem convinced that I need to use FormsAuthentication. I have a custom module with a custom IPrincipal. The authentication logic is irrelevant to the question.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.