我在 VS17 中使用“Web 应用程序(模型- View - Controller )”模板和“.Net Framework”+“ASP.NET Core 2”作为配置创建了一个新的 ASP.NET Core Web 应用程序项目。身份验证配置设置为“个人用户帐户”。
我有以下示例端点:
[Produces("application/json")]
[Route("api/price")]
[Authorize(Roles = "PriceViwer", AuthenticationSchemes = "Cookies,Bearer")]
public class PriceController : Controller
{
public IActionResult Get()
{
return Ok(new Dictionary<string, string> { {"Galleon/Pound",
"999.999" } );
}
}
"Cookies,Bearer"
通过连接 CookieAuthenticationDefaults.AuthenticationScheme
得出和 JwtBearerDefaults.AuthenticationScheme
.目标是能够为端点配置授权,以便可以使用 token 和 cookie 身份验证方法访问它。
这是我在 Startup.cs 中进行身份验证的设置:
services.AddAuthentication()
.AddCookie(cfg => { cfg.SlidingExpiration = true;})
.AddJwtBearer(cfg => {
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters() {
ValidIssuer = Configuration["Tokens:Issuer"],
ValidAudience = Configuration["Tokens:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
};
});
因此,当我尝试使用浏览器访问端点时,我会收到带有空白 html 页面的 401 响应。
然后我登录,当我再次尝试访问端点时,我得到了相同的响应。
然后,我尝试通过指定承载 token 来访问端点。这将返回带有 200 响应的所需结果。
那么,如果我删除
[Authorize(AuthenticationSchemes = "Cookies,Bearer")]
, 情况正好相反 - cookie 身份验证有效并返回 200,但是与上面使用的相同的不记名 token 方法没有给出任何结果,只是重定向到默认的 AspIdentity 登录页面。我可以在这里看到两个可能的问题:
1) ASP.NET Core 不允许“组合”身份验证。
2) 'Cookies' 不是有效的模式名称。但是,什么是正确的使用呢?
请指教。谢谢你。
最佳答案
经过数小时的研究和摸索,这就是在 ASP.NET Core 2.2 -> ASP.NET 5.0 中对我有用的方法:
您不需要在每个 Controller 操作上指定方案,并且两者都适用。 【授权】就够了。
services.AddAuthentication( config =>
{
config.DefaultScheme = "smart";
} )
.AddPolicyScheme( "smart", "Bearer or Jwt", options =>
{
options.ForwardDefaultSelector = context =>
{
var bearerAuth = context.Request.Headers["Authorization"].FirstOrDefault()?.StartsWith( "Bearer " ) ?? false;
// You could also check for the actual path here if that's your requirement:
// eg: if (context.HttpContext.Request.Path.StartsWithSegments("/api", StringComparison.InvariantCulture))
if ( bearerAuth )
return JwtBearerDefaults.AuthenticationScheme;
else
return CookieAuthenticationDefaults.AuthenticationScheme;
};
} )
.AddCookie( CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = new PathString( "/Account/Login" );
options.AccessDeniedPath = new PathString( "/Account/Login" );
options.LogoutPath = new PathString( "/Account/Logout" );
options.Cookie.Name = "CustomerPortal.Identity";
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromDays( 1 ); //Account.Login overrides this default value
} )
.AddJwtBearer( JwtBearerDefaults.AuthenticationScheme, options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey( key ),
ValidateIssuer = false,
ValidateAudience = false
};
} );
services.AddAuthorization( options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder( CookieAuthenticationDefaults.AuthenticationScheme, JwtBearerDefaults.AuthenticationScheme )
.RequireAuthenticatedUser()
.Build();
} );
关于c# - ASP.NET Core 2.0 为同一端点结合了 Cookie 和承载授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46938248/