带服务的WebApi Authorize属性。AddIdentity返回404 Not Found

时间:2018-07-10 11:20:49

标签: c# .net-core asp.net-identity identityserver4 asp.net-core-webapi

我有一个简单的WebApi项目,该项目使用IdentityServer4.AccessTokenValidation来验证开发地址为IdentityServer4的{​​{1}}服务器发出的令牌。

我通过将以下数据发送到Identityserver获得令牌:

https://localhost:44347

响应为:

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

并将令牌发送到WebAPi

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

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

代码是:

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

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

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();
    }
}

我使用自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 }); } } } 继承的自定义User类,自定义IIdentityRole,已实现UserRole的自定义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 中有些东西,我终于将属性更改为我的founded here

authorization system

,并且有效。但是如何以及为什么呢?我现在还没有

此外,如提到的答案所示,将[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

1 个答案:

答案 0 :(得分:4)

让我尝试解释一下,以便其他一些可怜的人有一些容易理解的时间:)

如上添加验证时

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

这意味着放置在方法或控制器类顶部的每个属性[Authorize]都将尝试根据默认的身份验证架构(在本例中为JwtBearer)进行身份验证并且不会进行级联< / strong>尝试使用可能已声明的其他架构(例如Cookie架构)进行身份验证。为了使AuthorizeAttribute针对cookie模式进行身份验证,必须像上面的代码中一样指定

[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]

反之亦然,也就是说,如果cookie模式是默认模式,则必须声明JwtBearer模式以授权那些需要JwtBearer令牌认证的方法或控制器

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]