ASP.Net MVC 6 + WebAPI 身份验证 - 将 MVC 重定向到登录但如果是 WebAPI 则为 401
ASP.Net MVC 6 + WebAPI Auth - Redirect MVC to logon but 401 if WebAPI
我有一个 AngularJS + MVC + WebAPI 我正在尝试:
- 使用标准(个人帐户)进行 MVC 身份验证;
- 使用相同的用户和密码进行基于 WebAPI 的身份验证。
问题,从 AngularJS 开始一切正常,cookie 交换发生,Web API returns 值,但是当我尝试访问 WebAPI 来自 Postman,我得到了一个重定向到登录页面而不是 401 Unauthorized。
实现此目的最简单的方法是什么?我是否必须子类化 Authorize 并手动实现逻辑?
谢谢
您可以简单地为重定向事件应用自定义操作。在 App_Start/Startup.Auth.cs
文件中找到 app.UseCookieAuthentication()
方法并像这样修改:
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);
}
}
});
}
对于 ASP.Net 5 最新的 beta8,答案是将以下内容添加到 Startup.cs 上的 ConfigureServices:
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);
}
}
};
});
在 RC1-Final (VS2015.1) 中,我完成了以下操作:
在身份配置中将 AutomaticChallenge 设置为 false 和 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();
然后控制器,我想重定向到登录,我添加 ActiveAuthenticationSchemes = "ApplicationCookie"
[Authorize(ActiveAuthenticationSchemes = "ApplicationCookie")]
public async Task<IActionResult> Logout()
{
// cut
}
但是其他控制器(在我的例子中是 WebAPI)我用参数 less Authorize 属性标记。
来自 AuthenticationOptions.cs AutomaticChallenge 的内联帮助:
If false the authentication middleware will only alter responses when explicitly indicated by the AuthenticationScheme.
我有一个 AngularJS + MVC + WebAPI 我正在尝试: - 使用标准(个人帐户)进行 MVC 身份验证; - 使用相同的用户和密码进行基于 WebAPI 的身份验证。
问题,从 AngularJS 开始一切正常,cookie 交换发生,Web API returns 值,但是当我尝试访问 WebAPI 来自 Postman,我得到了一个重定向到登录页面而不是 401 Unauthorized。
实现此目的最简单的方法是什么?我是否必须子类化 Authorize 并手动实现逻辑?
谢谢
您可以简单地为重定向事件应用自定义操作。在 App_Start/Startup.Auth.cs
文件中找到 app.UseCookieAuthentication()
方法并像这样修改:
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);
}
}
});
}
对于 ASP.Net 5 最新的 beta8,答案是将以下内容添加到 Startup.cs 上的 ConfigureServices:
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);
}
}
};
});
在 RC1-Final (VS2015.1) 中,我完成了以下操作: 在身份配置中将 AutomaticChallenge 设置为 false 和 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();
然后控制器,我想重定向到登录,我添加 ActiveAuthenticationSchemes = "ApplicationCookie"
[Authorize(ActiveAuthenticationSchemes = "ApplicationCookie")]
public async Task<IActionResult> Logout()
{
// cut
}
但是其他控制器(在我的例子中是 WebAPI)我用参数 less Authorize 属性标记。
来自 AuthenticationOptions.cs AutomaticChallenge 的内联帮助:
If false the authentication middleware will only alter responses when explicitly indicated by the AuthenticationScheme.