简体   繁体   English

Asp.Net Web Api JWT 授权始终获得 401

[英]Asp.Net Web Api JWT Authorization With Identity Always Getting 401

I'm using Asp.Net Core 5, and Asp.Net Identity with EFcore.我正在使用 Asp.Net Core 5,以及带有 EFcore 的 Asp.Net Identity。 I've followed parts of many video tutorials, advice posted here on SO and this very helpful article to get my project to the point where I'm at least getting 401's.我已经关注了许多视频教程的部分内容,在 SO 上发布的建议以及这篇非常有用的文章,以使我的项目达到我至少获得 401 的程度。 My problem is now that I can't understand why I am getting 401's.我现在的问题是我不明白为什么我会得到 401。 I've validated my token with my secret on jwt.io and everything tells me that it should be working, but it is not.我已经用我在 jwt.io 上的秘密验证了我的令牌,一切都告诉我它应该可以工作,但事实并非如此。 I am at a complete loss.我完全不知所措。 Enough fluff, down to business.废话不多说,说正事。

My Startup Class.我的启动 Class。 Note: in the OnMessageReceived event context.Token is null until I set it with the authorization header.注意:在 OnMessageReceived 事件上下文中。令牌是 null,直到我使用授权 header 设置它。

//imports

namespace auto_highlighter_iam
{
    public class Startup
    {

        private readonly IConfiguration _config;
        private readonly IWebHostEnvironment _env;
        public Startup(IConfiguration config, IWebHostEnvironment env)
        {
            _config = config;
            _env = env;
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            services.AddDbContext<DataContext>(options =>
            {
                options.UseNpgsql(_config.GetConnectionString("AutoHighlighterIAMDev"));
            });

            IdentityBuilder iBuilder = services.AddIdentityCore<IdentityUser>(options =>
            {
                options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._ ";
                options.Password.RequiredLength = 12;
                options.Password.RequireDigit = false;
                options.Password.RequireLowercase = false;
                options.Password.RequireUppercase = false;
                options.Password.RequireNonAlphanumeric = false;
                options.User.RequireUniqueEmail = true;
                //options.SignIn.RequireConfirmedEmail = true;
            });
            iBuilder = new IdentityBuilder(iBuilder.UserType, typeof(IdentityRole), iBuilder.Services)
                .AddEntityFrameworkStores<DataContext>()
                .AddRoleManager<RoleManager<IdentityRole>>()
                .AddSignInManager<SignInManager<IdentityUser>>();


            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(config =>
           {
               config.Events = new JwtBearerEvents()
               {
                   OnMessageReceived = context =>
                   {
                       // Interesting note here. before this next line context.Token is null, but the authorization header has the jwt
                       context.Token = context.Request.Headers[HeaderNames.Authorization];
                       // Although the previous line successfully set context.Token to the jwt still getting 401's

                       return Task.CompletedTask;
                   }
               };
               config.RequireHttpsMetadata = !_env.IsDevelopment();
               config.TokenValidationParameters = new TokenValidationParameters
               {
                   ValidateIssuerSigningKey = true, //tried as false
                   IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JWT:Secret"])),
                   ValidateIssuer = true, //tried as false
                   ValidIssuer = _config["JWT:Iss"],
                   ValidateAudience = true, //tried as false
                   ValidAudience = _config["JWT:Aud"]
               };
           });

            services.AddAuthorization();

            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "auto_highlighter_iam", Version = "v1" });

                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    In = ParameterLocation.Header,
                    Description = "Insert JWT with Bearer into field",
                    Name = "Authorization",
                    Type = SecuritySchemeType.ApiKey
                });

                c.AddSecurityRequirement(new OpenApiSecurityRequirement {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer"
                            }
                        },
                        Array.Empty<string>()
                    }
                });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext dataContext)
        {
            dataContext.Database.Migrate();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "auto_highlighter_iam v1"));
            }

            app.UseExceptionHandler("/exception");

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseAuthentication();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

My AuthorizationController.我的授权控制器。 There are three endpoints.有三个端点。 Two to test the roles I have and one that should test for any valid jwt.两个用来测试我的角色,一个用来测试任何有效的 jwt。 All of them return a 401.它们都返回 401。

// imports

namespace auto_highlighter_iam.Controllers
{
    [ApiController]
    [Route("/api-v1/[controller]")]
    public class AuthorizationController : ControllerBase
    {
        [HttpGet("[action]")]
        [Authorize(Roles = "SUPERADMIN")]
        public IActionResult TestSuperAdmin()
        {
            return Ok();
        }

        [HttpGet("[action]")]
        [Authorize(Roles = "DEFAULT")]
        public IActionResult TestDefault()
        {
            return Ok();
        }

        [HttpGet("[action]")]
        [Authorize]
        public IActionResult TestAny()
        {
            return Ok();
        }
    }
}

The JWT I am testing with (pretend the token isn't expired, I've been making sure it's valid)我正在测试的 JWT (假设令牌未过期,我一直在确保它有效)

eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJWSUVXIjoiRmFsc2UiLCJFRElUIjoiRmFsc2UiLCJERUxFVEUiOiJGYWxzZSIsIkNSRUFURSI6IkZhbHNlIiwicm9sZXMiOiJERUZBVUxUIiwibmJmIjoxNjExMTIxNTI1LCJleHAiOjE2MTExMjUxMjUsImlzcyI6ImF1dG8taGlnaGxpZ2h0ZXItaWFtIiwiYXVkIjoiYXV0by1oaWdobGlnaHRlci1mcm9udC1lbmQifQ.jnbW552pr7kylc82-4FmJJMmaeu7LQ7L48M5cdnSzuMsA1yRuts9sXUQ2_ok41SqX8mFpi7yreJJXGlE6qC1vA

The request I am sending我发送的请求

curl --location --request GET 'http://localhost:5000/api-v1/Authorization/TestAny' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJWSUVXIjoiRmFsc2UiLCJFRElUIjoiRmFsc2UiLCJERUxFVEUiOiJGYWxzZSIsIkNSRUFURSI6IkZhbHNlIiwicm9sZXMiOiJERUZBVUxUIiwibmJmIjoxNjExMTIwMDkzLCJleHAiOjE2MTExMjM2OTMsImlzcyI6ImF1dG8taGlnaGxpZ2h0ZXItaWFtIiwiYXVkIjoiYXV0by1oaWdobGlnaHRlci1mcm9udC1lbmQifQ.zOsNADvKGx1FYkzKLX4K53Y185dHFiM408aAjinQUQrVWQ_spXClozOAvp2glgiQkM0IwkDneB4Q_JCpQfet1g'

I'll be quick to provide any more info if I missed anything.如果我错过了什么,我会尽快提供更多信息。

You need to put your middleware:你需要把你的中间件:

app.UseAuthentication();

before your app.UseAuthorization();在你的app.UseAuthorization();

Like this:像这样:

app.UseAuthentication();
app.UseAuthorization();

Update:更新:

And you need to change your request to(delete Bearer ):您需要将您的请求更改为(删除Bearer ):

curl --location --request GET 'http://localhost:5000/api-v1/Authorization/TestAny' \
--header 'Authorization: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJWSUVXIjoiRmFsc2UiLCJFRElUIjoiRmFsc2UiLCJERUxFVEUiOiJGYWxzZSIsIkNSRUFURSI6IkZhbHNlIiwicm9sZXMiOiJERUZBVUxUIiwibmJmIjoxNjExMTIwMDkzLCJleHAiOjE2MTExMjM2OTMsImlzcyI6ImF1dG8taGlnaGxpZ2h0ZXItaWFtIiwiYXVkIjoiYXV0by1oaWdobGlnaHRlci1mcm9udC1lbmQifQ.zOsNADvKGx1FYkzKLX4K53Y185dHFiM408aAjinQUQrVWQ_spXClozOAvp2glgiQkM0IwkDneB4Q_JCpQfet1g'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ASP.NET 核心 - JWT 授权总是抛出 401 - ASP.NET Core - JWT authorization always throws 401 通过使用JWT令牌在Web API上声明角色授权-Asp.net核心标识 - Authorization by a Claim of a Role on Web API using JWT Token- Asp.net Core Identity ASP.NET Web API JWT间歇性401错误 - ASP.NET Web API JWT intermittent 401 errors 勾选IP和JWT 在ASP.NET核中授权Web Api - Check IP with JWT Authorization in ASP.NET Core Web Api ASP.NET Core 3.1 Web API 中的“授权失败。AuthenticationScheme:AzureADJwtBearer 受到挑战” - 401 Unauthorized - "Authorization failed. AuthenticationScheme: AzureADJwtBearer was challenged" in ASP.NET Core 3.1 Web API - 401 Unauthorized 如何使ASP.Net Core Web API Identity在未经授权的情况下返回401 - How to make ASP.Net Core Web API Identity return a 401 on unauthorized ASP.NET Web API 的 JWT 身份验证 - JWT authentication for ASP.NET Web API 如何从 asp.net web api 中的身份声明获取 JWT 身份验证的登录用户 - How to get JWT authenticated sign-in user from identity claims in asp.net web api ASP.NET Core Web API 使用客户端证书调用其他 Web API 获取 401 - ASP.NET Core Web API calling other Web API using Client Certificate getting 401 IdentityServer4 基于角色的 Web API 授权与 ASP.NET Core 标识 - IdentityServer4 Role Based Authorization for Web API with ASP.NET Core Identity
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM