Skip to content
This repository has been archived by the owner on Dec 20, 2018. It is now read-only.

Aspnet Core 2.0 Authorization issues after deploying to IIS #1543

Closed
HaythemJ opened this issue Dec 26, 2017 · 7 comments
Closed

Aspnet Core 2.0 Authorization issues after deploying to IIS #1543

HaythemJ opened this issue Dec 26, 2017 · 7 comments

Comments

@HaythemJ
Copy link

I have a Aspnet Core 2.0 application. I configured both Identity and Jwt as below:

  `// Register identity framework services and also Mongo storage. 
        services.AddIdentityWithMongoStores(settings)
            .AddDefaultTokenProviders();
        services.ConfigureApplicationCookie(options =>
        {
            options.LoginPath = "/Account/Login";
            options.Cookie.HttpOnly = true;
            options.Events = new CookieAuthenticationEvents
            {
                OnRedirectToLogin = ctx =>
                {
                    if (ctx.Request.Path.StartsWithSegments("/api"))
                    {
                        ctx.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
                    }
                    else
                    {
                        ctx.Response.Redirect(ctx.RedirectUri);
                    }
                    return Task.FromResult(0);
                }
            };
        });

         services.AddAuthentication().AddJwtBearer(cfg =>
        {
            cfg.RequireHttpsMetadata = false;

            cfg.SaveToken = true;

            cfg.TokenValidationParameters = new TokenValidationParameters
            {
                ValidIssuer = Configuration["JwtSecurityToken:Issuer"],
                ValidAudience = Configuration["JwtSecurityToken:Audience"],
                //ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSecurityToken:Key"])),
                //ValidateLifetime = true,
                //ClockSkew = TimeSpan.MaxValue // remove delay of token when expire
            };
        });


        // Add application services.
        services.AddTransient<IEmailSender, EmailSender>();

        ///Instead of services.AddMvc(), we need to asjust the AuthenticationSchema
        ///in order to support both Identity Cookies and Jwt
        services.AddMvc(
            config =>
        {
            var defaultPolicy = new AuthorizationPolicyBuilder(new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme })
                             .RequireAuthenticatedUser()
                             .Build();
            config.Filters.Add(new AuthorizeFilter(defaultPolicy));
            config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        }
        )
            .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

`
Everything runs ok on Visual Studio and I have both Identity Cookies and Jwt enabled.

but once deployed to IIS on my Machine, the calls are all Unauthorized 401 HTTP Code.

I debugged using Remote Debugger on IIS and I was able to see that the user was authenticated and authorized in the below method:

       `public async Task<IActionResult> Login(AuthenticationViewModel model, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        if (ModelState.IsValid)
        {
            // This doesn't count login failures towards account lockout
            // To enable password failures to trigger account lockout, set lockoutOnFailure: true
            var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password, 
            model.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                _logger.LogInformation(1, "User logged in.");
                return RedirectToAction(nameof(AppController.App), "App");
                //return RedirectToLocal(returnUrl);
            }
            
            if (result.IsLockedOut)
            {
                _logger.LogWarning(2, "User account locked out.");
                return View("Lockout");
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                return View(model);
            }
        }`

image

But when executing this instruction return RedirectToAction(nameof(AppController.App), "App"); where I am redirecting to the main page it returns 302 HTTP:

image

I don't know why in VS it is working well and not in IIS.

@HaythemJ HaythemJ changed the title Issues after deploying to IIS Aspnet Core 2.0 Authorization issues after deploying to IIS Dec 26, 2017
@HaythemJ
Copy link
Author

For a raison that I ignore, it works when I started the application using my host name instead of "localhost/". Is there a configuration for a such thing?

@dcarr42
Copy link

dcarr42 commented Dec 27, 2017

I think this is IIS setup and not an identity issue. Probably default website configured incorrectly.

@HaythemJ
Copy link
Author

It works fine on a VM having the same environment. And was not obliged accessing the Application using the host name of an FQN. My site on IIS is the default (running on port 80)

@blowdart
Copy link
Member

blowdart commented Jan 2, 2018

302 is the redirect, so that's an expected status code. Have you tried using fiddler and seeing if an auth cookie is created?

@blowdart
Copy link
Member

We're closing this issue as no response or updates have been provided in a timely manner. If you have more details and are encountering this issue please add a new reply and re-open the issue.

@stevenxi
Copy link

stevenxi commented Jun 8, 2018

@blowdart , we just found something similar.

Rather than get 302 from RedirectToAction(), the status was set right after calling .PasswordSignInAsync()

Apparently "PasswordSignInAsync()" sets status code 302 when user is valid.

Normally it's ok, but we're using OTP, and not expecting a redirecting at this stage. (We don't redirect to an OTP code page, but just outputs different view)

Would this consider to be a bug? the PasswordSignInAsync() should not handle the redirect operations.

Before:

capture before

After:

capture after

We're using 2.0.3. Similar behavior was not found on 2.1.0

@alonstar
Copy link

I also have the same issue on 2.1.3

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants