![](/img/trans.png)
[英]How can my ASP.NET Core App Service Web API support both AAD Bearer Token and Client Certificate Auth?
[英]How can I use both Bearer and Cookie authentication in my ASP.net Core application?
我正在使用ASP.net Core 2.0應用程序,該應用程序使用IdentityServer4令牌服務器進行身份驗證。 我的應用程序具有Razor Pages,我想與它一起使用Cookie身份驗證,它也具有一個API,我想與它一起使用Bearer令牌。
這是我在Startup.cs
擁有的設置:
public void ConfigureServices(IServiceCollection services) {
//...
services.AddAuthentication(options => { options.DefaultChallengeScheme = "oidc"; })
.AddIdentityServerAuthentication(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.Authority = Configuration["OpenIDConnect:Authority"];
options.ApiName = Configuration["OpenIDConnect:ApiName"];
options.JwtBearerEvents.OnChallenge += async context =>
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
context.HandleResponse();
};
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = Configuration["OpenIdConnect:Authority"];
options.RequireHttpsMetadata = false;
options.ClientId = Configuration["OpenIdConnect:ClientId"];
options.SaveTokens = true;
options.Scope.Add("role");
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
});
services.AddAuthorization(options =>
{
options.AddPolicy(Constants.Policies.ApiUserWithBearerToken,
policy =>
{
policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
policy.AuthenticationSchemes.Remove(CookieAuthenticationDefaults.AuthenticationScheme);
policy.AuthenticationSchemes.Remove("oidc");
policy.RequireClaim("MobileClient", "true");
policy.RequireClaim("ApiUser", "true");
});
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
//…
//…
app.UseAuthentication();
}
這是我嘗試使用Bearer令牌保護的API端點:
[Route("api/[controller]"), Authorize(Policy = "ApiUserWithBearerToken", AuthenticationSchemes = "Bearer"), MobileAppController]
public class CatalogController : Controller
{
// …
[HttpGet("current")]
public async Task<IActionResult> Current()
{
// …
}
}
我的問題是ASP.net似乎完全忽略了我的Bearer身份驗證方案設置。 如果我使用有效的承載令牌請求current
端點,它將返回到IdentityServer的重定向,要求我登錄。
這是來自Kestrel的消息日志:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5001/api/Catalog/current
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed for user: (null).
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
Executing ChallengeResult with authentication schemes ().
info: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[12]
AuthenticationScheme: oidc was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action Pinball.Web.Controllers.CatalogController.Current (Catalog.Web) in 1185.1356ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 1871.9771ms 302
如果刪除默認的挑戰方案,則ASP.net只會引發一個異常,指出它是必需的。
我在這里想念什么?
我遇到了同樣的問題,自從解決了問題,我很高興提供解決方案。 通過調用services.AddIdentityServer()
添加Identity Server時,默認情況下會默認添加cookie身份驗證,如您在此處所見, https://github.com/IdentityServer/IdentityServer4/blob/75b1a660c3cab2580112e6e0288f3f6bed8189f9/src/Configuration/DependencyInjection/IdentityServerServiceCollectionExtensions.cs。
builder
.AddRequiredPlatformServices()
.AddCookieAuthentication() // <-- Cookie auth added
.AddCoreServices()
.AddDefaultEndpoints()
.AddPluggableServices()
.AddValidators()
.AddResponseGenerators()
.AddDefaultSecretParsers()
.AddDefaultSecretValidators();
之后,您可以使用services.AddAuthentication()
添加身份驗證,因此此時您無需再添加cookie身份驗證,因為它已經被添加了。 您只需要通過添加以下代碼來添加IS身份驗證:
services.AddAuthentication()
.AddIdentityServerAuthentication(options =>
{
options.Authority = Configuration["Settings:Authentication:Authority"];
options.RequireHttpsMetadata = !CurrentEnvironment.IsDevelopment();
options.ApiName = Configuration["Settings:Authentication:ApiName"];
options.ApiSecret = Configuration["Settings:Authentication:ApiSecret"];
});
您也不需要.AddOpenIdConnect()
方法。
現在,請記住,完成此操作后,您聲明了兩種用於服務身份驗證請求的身份驗證方法。 第一個是cookie(由IS添加),另一個是通過調用.AddIdentityServerAuthentication()
添加的JWT承載。 由於cookie是首先添加的,因此在需要驗證任何請求時也將首先調用它,因此,您需要指定要在授權時使用的方法,可以通過使用以下方法正確完成:
[Route("api/[controller]"), Authorize(Policy = "ApiUserWithBearerToken", AuthenticationSchemes = "Bearer"), MobileAppController]
我個人使用IS默認值,但結果是相同的:
[Route("api/[controller]"), Authorize(Policy = "ApiUserWithBearerToken", AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme), MobileAppController]
有了這個,您應該有一個可以同時處理API請求和Razor頁面的應用程序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.