我有一个MVC web应用程序和一个公开的API,我想为web应用程序使用cookieauth,为公开的API使用JWT。我正在测试API,由于某种原因,它似乎总是默认为中间件中的cookie验证处理程序。
在下面的启动中,我添加了两个事件处理程序,只是为了测试断点,API会命中cookie事件处理程序而不是JWT处理程序。我在行动中具体说明了这个计划,所以不确定为什么它不起作用。
Startup.cs配置服务
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
options.SlidingExpiration = true;
options.AccessDeniedPath = "/Error/Index";
options.LoginPath = "/Login/Login";
options.Cookie.Name = "CookieAuthentication";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Events.OnRedirectToLogin = e =>
{
return Task.CompletedTask;
};
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Environment.GetEnvironmentVariable("JwtIssuer") ?? Configuration["Jwt:Issuer"],
ValidAudience = Environment.GetEnvironmentVariable("JwtIssuer") ?? Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Environment.GetEnvironmentVariable("JwtKey") ?? Configuration["Jwt:Key"])),
};
options.Events.OnChallenge = e =>
{
return Task.CompletedTask;
};
});
}
}
启动配置
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseAuthentication();
app.UseAuthorization();
}
举个例子,我用我的API这样做,并且在启动时没有达到正确的方案
[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public IActionResult Foo()
{
return Ok();
}
您必须注册2个类似的身份验证方案:
//Cookie
_ = services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
options.SlidingExpiration = true;
options.AccessDeniedPath = "/Error/Index";
options.LoginPath = "/Login/Login";
options.Cookie.Name = "CookieAuthentication";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Events.OnRedirectToLogin = e =>
{
return Task.CompletedTask;
};
});
//Jwt
_ = services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Environment.GetEnvironmentVariable("JwtIssuer") ?? Configuration["Jwt:Issuer"],
ValidAudience = Environment.GetEnvironmentVariable("JwtIssuer") ?? Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Environment.GetEnvironmentVariable("JwtKey") ?? Configuration["Jwt:Key"])),
};
options.Events.OnChallenge = e =>
{
return Task.CompletedTask;
};
});
并用您需要的身份验证方案装饰您的行为:
[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public IActionResult Foo()
{
return Ok();
}
[HttpGet]
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
public IActionResult FooCookie()
{
return Ok();
}
编辑:使用基本控制器进行身份验证继承(属性可以继承(:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class MyJwtBaseController : ApiController
{
}
如果您想取消授权特定操作:
public class MyController : MyJwtBaseController
{
public IActionResult Foo() //Inherits base controller auth
{
return Ok();
}
[AllowAnonymous]
public IActionResult FooUnauthorize() //No auth
{
return Ok();
}
}