ASP.Net MVC 6 + WebAPI Auth - Redirect MVC to logo

2019-06-27 10:07发布

问题:

I have a AngularJS + MVC + WebAPI where I'm trying to: - Use standard (individual accounts) for MVC authentication; - Use those same users and password for WebAPI based authentication.

Problem, from AngularJS everything works fine, the cookie exchange happens, and Web API returns the value, but when I'm trying to access the WebAPI from Postman, I get a redirect to logon page instead of a 401 Unauthorized.

What is the easiest way to achieve this? Do I have to subclass Authorize and implement the logic manually?

Thank you

回答1:

For the ASP.Net 5 latest beta8, the answer is to add the following to ConfigureServices on Startup.cs:

         services.Configure<IdentityOptions>(config =>
        {
            options.Cookies.ApplicationCookie.LoginPath = "/Account/Login";
            options.Cookies.ApplicationCookie.CookieHttpOnly = true;
            options.Cookies.ApplicationCookie.CookieSecure = CookieSecureOption.SameAsRequest;
            options.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents()
            {
                OnRedirect = ctx =>
                {
                    if (ctx.Request.Path.StartsWithSegments("/api") &&
                    ctx.Response.StatusCode == 200)
                    {
                        ctx.Response.StatusCode = 401;
                        return Task.FromResult<object>(null);
                    }
                    else
                    {
                        ctx.Response.Redirect(ctx.RedirectUri);
                        return Task.FromResult<object>(null);
                    }
                }
            };
        });


回答2:

You could simply apply a custom action for Redirect event. On App_Start/Startup.Auth.cs file find app.UseCookieAuthentication() method and alter like this:

public void ConfigureAuth(IAppBuilder app)
{
    // some omitted configurations 

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        // some omitted configurations 

        Provider = new CookieAuthenticationProvider
        {
            // some omitted configurations 

            OnApplyRedirect = context => 
            {
                // assuming your API's url starts with /api
                if(!context.Request.Path.StartsWithSegments(new PathString("/api")))
                    context.Response.Redirect(context.RedirectUri);
            }
        }
    });
}


回答3:

In RC1-Final (VS2015.1) I've done with the following: in Identity configuration set AutomaticChallenge to false and ApplicationCookieAuthenticationScheme = "ApplicationCookie":

services.AddIdentity<AppUser>(options =>
        {
            // cut

            options.Cookies.ApplicationCookie.AutomaticAuthenticate = true;
            options.Cookies.ApplicationCookie.AutomaticChallenge = false;
            options.Cookies.ApplicationCookieAuthenticationScheme = "ApplicationCookie";
        })
            .AddUserStore<AppUserStore<AppUser, AppDbContext>>()
            .AddDefaultTokenProviders();

Then controllers, that I want to redirect to login, I add ActiveAuthenticationSchemes = "ApplicationCookie"

[Authorize(ActiveAuthenticationSchemes = "ApplicationCookie")]
    public async Task<IActionResult> Logout()
    {
        // cut
    }

but other controllers (WebAPI in my case) I marked with parameter less Authorize attribute.

From AuthenticationOptions.cs inline help for AutomaticChallenge:

If false the authentication middleware will only alter responses when explicitly indicated by the AuthenticationScheme.