gpt4 book ai didi

c# - 具有 services.AddIdentity 的 WebApi 授权属性返回 404 Not Found

转载 作者:行者123 更新时间:2023-11-30 20:16:02 25 4
gpt4 key购买 nike

我有一个简单的 WebApi 项目,它使用 IdentityServer4.AccessTokenValidation验证 IdentityServer4 发出的 token 服务器在开发地址:https://localhost:44347

我通过向身份服务器发送以下数据来获取 token :

POST
https://localhost:44347/connect/token
client_id:x.api.client
client_secret:secret
response_type:code id_token
scope:X.api
grant_type:client_credentials

响应是:

{
"access_token": "THETOKEN",
"expires_in": 1209600,
"token_type": "Bearer"
}

并将 token 发送到 WebAPI

POST
http://localhost:59062/identity
Authorization:Bearer THETOKEN

我得到了想要的结果,但是,添加以下代码的注释部分导致 404 Not Found。

代码是:

public class Startup {

private const string API_NAME = "X.api";

public Startup(IConfiguration configuration) {
Configuration = configuration;
}

public IConfiguration Configuration { get; }


public void ConfigureServices(IServiceCollection services) {

string connectionString = Configuration.GetConnectionString("DefaultConnection");

services.AddLogging(configure => configure.AddConsole());

services.AddDbContext<MyDataContext>(options => options.UseSqlServer(connectionString));

services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

services.AddTransient<IUserStore<MyUser>, MyUserStore>();
services.AddTransient<IRoleStore<MyRole>, RoleStore>();
services.AddTransient<IPasswordHasher<MyUser>, MyHasher>();


services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options => {
options.Authority = "https://localhost:44347";
options.RequireHttpsMetadata = false;
options.ApiName = API_NAME;
});


////This commented part brokes API
//services.AddIdentity<MyUser, MyRole>(options => {
// options.Password.RequireDigit = true;
// options.Password.RequiredLength = 6;
// options.Password.RequireNonAlphanumeric = false;
// options.Password.RequireUppercase = false;
// options.Password.RequireLowercase = false;
// options.SignIn.RequireConfirmedEmail = false;
//})
//Bekaz we are not using IdentityUser as base
//.AddUserStore<MyUserStore>()
//.AddRoleStore<RoleStore>()
//.AddDefaultTokenProviders();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}

app.UseAuthentication();
app.UseMvc();
}
}

API 就像下面的一段代码一样简单(身份服务器的示例之一)

using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;

namespace Api.Controllers {
[Route("[controller]")]
[Authorize]
public class IdentityController : ControllerBase {
[HttpGet]
public IActionResult Get() {
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
}
}

我使用继承自 IIdentity 的自定义用户类, 定制 RoleUserRole , 定制 RoleStore已实现 IRoleStore<MyRole> , 和自定义 UserStore已实现 IUserStore<MyUser>, IUserPasswordStore<MyUser> .

编辑,更多信息

这是我在控制台上得到的:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5000/identity
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Route matched with {action = "Get", controller = "Identity"}. Executing action Api.Controllers.IdentityController.Get ()
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed.
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 ().
[16:48:20 Information] Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler
AuthenticationScheme: Identity.Application was challenged.

info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[12]
AuthenticationScheme: Identity.Application was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action Api.Controllers.IdentityController.Get () in 30.1049ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 103.2969ms 302
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5000/Account/Login?ReturnUrl=%2Fidentity
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 0.468ms 404

临时解决方案

authorization system 有问题,我终于将属性更改为我 founded here

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

并且有效。但如何以及为什么?我现在还不知道。

此外,更改 AddAuthentication下面的部分,如提到的答案建议, 工作并且需要 (AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)将传递给 [Authorize]

        services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddIdentityServerAuthentication(options => {
options.Authority = "https://localhost:44347";
options.RequireHttpsMetadata = false;

options.ApiName = API_NAME;
});

改变顺序,终于成功了。(首先是 AddIdentity 然后是 AddAuthentication )

        services.AddIdentity<MyUser, MyRole>(options => {
options.Password.RequireDigit = true;
options.Password.RequiredLength = 6;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequireLowercase = false;
options.SignIn.RequireConfirmedEmail = false;
})
.AddUserStore<MyUserStore>()
.AddRoleStore<RoleStore>();


services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddIdentityServerAuthentication(options => {
options.Authority = "https://localhost:44347";
options.RequireHttpsMetadata = false;

options.ApiName = API_NAME;
});

最佳答案

让我试着解释一下,让其他可怜的人更容易理解 :)

像上面一样添加身份验证时

  services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
....

这意味着放置在方法或 Controller 类之上的每个属性 [Authorize] 将尝试根据默认身份验证模式(在本例中为 JwtBearer)进行身份验证并且它不会向下级联 尝试使用可能声明的其他模式(如 Cookie 模式)进行身份验证。为了使 AuthorizeAttribute 根据 cookie 模式进行身份验证,必须像上面的代码一样指定它

[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]

这也适用于其他方式,即如果 cookie 模式是默认的,则必须声明 JwtBearer 模式以授权那些需要 JwtBearer token 身份验证的方法或 Controller

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

关于c# - 具有 services.AddIdentity 的 WebApi 授权属性返回 404 Not Found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51263883/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com