繁体   English   中英

JWT 令牌生成但不验证 (401)

[英]JWT Token generates but does not Authenticate (401)

我正在尝试按照此指南链接将 JWT 身份验证添加到我的应用程序

令牌生成正确(在 JWT.io 上测试)但是当调用 API 中的方法时,我只得到 401。

我正在使用 Swagger 拨打电话(我也尝试过 postman)

启动.cs

private void AddSwagger(IServiceCollection services)
        {
            services.AddSwaggerGen(x => {
                x.SwaggerDoc("v1", new Info { Title = ApiDescription, Version = "v1" });
                var xmlDocFile = Path.Combine(AppContext.BaseDirectory, $"{_hostingEnvironment.ApplicationName}.xml");
                if (File.Exists(xmlDocFile))
                {
                    var comments = new XPathDocument(xmlDocFile);
                    x.OperationFilter<XmlCommentsOperationFilter>(comments);
                    x.SchemaFilter<XmlCommentsSchemaFilter>(comments);
                }
                x.AddSecurityDefinition("Bearer", new ApiKeyScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                    Name = "Authorization",
                    In = "header",
                    Type = "apiKey"
                });

                x.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
                {
                    { "Bearer", new string[] { } }
                });

                x.OperationFilter<SecurityRequirementsOperationFilter>();
            });
        }

        private void AddJWT(IServiceCollection services)
        {
            var key = Encoding.ASCII.GetBytes(ConfigurationRoot["AppSettings:Secret"]);
            services.AddAuthentication(x =>
                {
                    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(x =>
                {
                    x.RequireHttpsMetadata = false;
                    x.SaveToken = true;
                    x.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = new SymmetricSecurityKey(key),
                        ValidateIssuer = false,
                        ValidateAudience = false
                    };
                });
        }

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
            //app.UseHttpsRedirection();
            app.UseCors("Fintrans");
            app.UseAuthentication();
            app.UseMvc();
            app.UseSwagger();
            app.UseSwaggerUI(x => { x.SwaggerEndpoint(ConfigurationRoot["Swagger:Path"], ApiDescription); });
            applicationLifetime.ApplicationStopped.Register(() => Container.Dispose());
        }


AuthController.cs

    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        private readonly IAuthService _authService;

        public AuthController(IAuthService authService)
        {
            _authService = authService;
        }

        [AllowAnonymous]
        [HttpPost]
        public LoginResponse Login(LoginRequest request)
        {
            return _authService.Login(request) as LoginResponse;
        }
        [HttpGet]
        public IActionResult GetAll()
        {
            return Ok();
        }
    }

身份验证服务.cs

    public class AuthService : IAuthService
    {
        private readonly AppSettings _appSettings;

        public AuthService(AppSettings appSettings)
        {
            _appSettings = appSettings;
        }

        public ILoginResponse Login(ILoginRequest request)
        {
            try
            {
                User user = InMemoryData.Users.Find(o =>
                    o.UserName == request.UserName && o.Password == request.Password);
                if (user == null)
                {
                    throw new SystemException("User or Password is Incorrect");
                }

                JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
                SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
                {
                    Subject = new ClaimsIdentity(new[]
                    {
                        new Claim(ClaimTypes.Name, user.UserName)
                       //Add roles or something here, idk
                    }),
                    Expires = DateTime.UtcNow.AddMinutes(150),
                    IssuedAt = DateTime.UtcNow,
                    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(_appSettings.Secret), SecurityAlgorithms.HmacSha256Signature)
                };
                SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);

                return new LoginResponse()
                {
                    Exception = null,
                    Token = tokenHandler.WriteToken(token),
                    ResponseDateTime = DateTime.Now,
                    IsSuccessful = true
                };
            }
            catch (Exception exception)
            {
                return new LoginResponse()
                {
                    Exception = exception,
                    IsSuccessful = false,
                    ResponseDateTime = DateTime.Now,
                    Token = null
                };
            }
        }

    }

编辑 1 09:20 2019/11/22

任何帮助或参考都会令人惊叹,并得到我永远的钦佩,我可能会也可能不会以你的名字命名我的长子。

编辑 2 09:52 2019/11/22

在PostMan试了一下,还是401,检查了实际创建token和bearer认证时使用的key是同一个字节arrays。

Output 来自请求

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/Auth  
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with {action = "GetAll", controller = "Auth"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult GetAll() on controller Sybrin.InstantPayments.Service.Auth.Controllers.AuthController (Sybrin.InstantPayments.Service.Auth).
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes (Bearer).
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AuthenticationScheme: Bearer was challenged.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action Sybrin.InstantPayments.Service.Auth.Controllers.AuthController.GetAll (Sybrin.InstantPayments.Service.Auth) in 27.8828ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 37.4312ms 401 
Failed to load resource: the server responded with a status of 401 (Unauthorized) [http://localhost:5000/api/Auth]

所以它确实在 Postman 中工作,不知道为什么它不能更早工作,电脑很奇怪。

应将问题标记为删除,因为它在技术上不能帮助任何人解决未来的问题

我在 Swagger 身份验证方面也遇到了一些问题。 请务必在 Bearer 和 token 之间输入一个空格。

承载 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbm

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM