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
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);
}
}
};
});
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);
}
}
});
}
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.