amiry jd
amiry jd

Reputation: 27585

Microsoft.Owin.Security.IAuthenticationManager doesn't redirect to login page

I'm using Microsoft.Owin.Security in my application (ASP.NET MVC v 5.2.0 on .NET 4.5). But just the security part of OWIN nothing else. When a user wants to access to a protected URL, in local, the request get redirected to the login page. But when I publish the app on server, I get this window instead of redirecting:

enter image description here

my login and log-off methods are:

public void LogIn(long userId, string username, string email, bool persistent) {
    var claims = new List<Claim>{
        new Claim(ClaimTypes.NameIdentifier, userId.ToString(CultureInfo.InvariantCulture)),
        new Claim(ClaimTypes.Name, username),
        new Claim(ClaimTypes.Email, email),
        new Claim(ClaimTypes.IsPersistent, persistent.ToString())
    };
    var id = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
    var ctx = HttpContext.Current.Request.GetOwinContext();
    var authenticationManager = ctx.Authentication;
    authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    authenticationManager.SignIn(new AuthenticationProperties {
        IsPersistent = persistent
    }, id);
}

public void LogOut() {
    var ctx = HttpContext.Current.Request.GetOwinContext();
    var authenticationManager = ctx.Authentication;
    authenticationManager.SignOut();
}

and here is my startup:

public partial class Startup {
    public void ConfigureAuth(IAppBuilder app) {
        app.UseCookieAuthentication(new CookieAuthenticationOptions {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/account/log-in/"),
            AuthenticationMode = AuthenticationMode.Active,
            CookieHttpOnly = true,
            CookieName = ".some-cookie-name",
            ExpireTimeSpan = TimeSpan.FromDays(1),
            LogoutPath = new PathString("/account/log-out/"),
            SlidingExpiration = true,
            ReturnUrlParameter = "continue"
        });
    }
}

I also have this line in global.asax::Application_Start method:

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

and these configuration in web.config:

<system.web>
  <authentication mode="None" />
  <httpModules>
    <remove name="FormsAuthenticationModule" />
    <remove name="RoleManager" />
  </httpModules>
</system.web>
<system.webServer>
  <validation validateIntegratedModeConfiguration="false" />
  <modules runAllManagedModulesForAllRequests="false">
    <remove name="FormsAuthenticationModule" />
    <remove name="RoleManager" />
  </modules>
</system.webServer>

and finally I'm running the application on a Windows 2008 R2 machine with IIS 7.5. Do you have any idea what should I do to make OWIN work correctly on my server, just like my local?

UPDATE: To be clear:

Assume I have these actions:

[AllowAnonymous]
public ActionResult AnonymousAction() { }

[Authorize]
public ActionResult UsersAction() { }

One for anonymous users, and another for logged-in users (which are well decorated with attributes). Anonymous users, can access AnonymousAction easily without any error or misbehavior. But when they (I mean Anonymous users) want to access UsersAction, instead of getting redirected to login page, they will see the window I mentioned above.

Upvotes: 6

Views: 2733

Answers (3)

amiry jd
amiry jd

Reputation: 27585

Well, it was really simple. According to @trailmax's answer (thanks to him), I realized that I should pay attention to the response's http-code. It was a 401 - Unauthorized code. So, I asked myself why is that? Until I found this answer. Then, the only thing I needed was creating the following attribute:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute {
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
        if (filterContext.HttpContext.Request.IsAuthenticated) {
            filterContext.Result = new HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
        } else {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

Upvotes: 1

trailmax
trailmax

Reputation: 35106

Like Erik says, your IIS has incorrect settings, most likely that Authentication is not configured correctly.

Go to your IIS, select your site and choose Authentication section. It should look like this: Anonymous Authentication = Enabled

Make sure your Anonymous Authentication is enabled and everything else is disabled.

Upvotes: 3

Steve Cooper
Steve Cooper

Reputation: 21480

Is it something to do with your login page URL in Startup? I notice this line;

LoginPath = new PathString("/account/log-in/")

is always directing to the root URL of the server. So if you're deploying to, say;

http://myserver.com/application1

then the login page will be

http://myserver.com/account/log-in/

but you probably mean

http://myserver.com/application1/account/log-in/

So you might want to try something like;

LoginPath = new PathString("~/account/log-in/")

with the ~ character. Same thing for the logoff url.

Upvotes: 2

Related Questions