繁体   English   中英

.NET 6.0 API + jwt-auth | API 返回“invalid_token”错误

[英].NET 6.0 API + jwt-auth | API returns "invalid_token" error

我正在尝试将 jwt 实施到我的项目中。 在我更改代码之前它正在工作。 此更改不会影响授权,但不知何故令牌不再起作用。

当我从 jwt.io 检查令牌时,它显示“签名无效”。 当我尝试使用 Swagger 执行请求时,回复说

content-length: 0
date: Fri,02 Sep 2022 10:09:12 GMT
server: Kestrel
www-authenticate: Bearer error="invalid_token"
x-firefox-spdy: h2 

秘密:tx9mcA4gnbigtP7ZRECnfhk9tWsHM9ZtXqbuFYWM23D3PMdRKwh74e24swqvrTh5

API/程序.cs

using System.Text;
using BlogProject.Business.MapperProfile;
using BlogProject.Business.Services.AuthenticationService;
using BlogProject.Business.Services.CommentService;
using BlogProject.Business.Services.PostService;
using BlogProject.Business.Services.TagService;
using BlogProject.Business.Services.UserService;
using BlogProject.DataAccess.Data;
using BlogProject.DataAccess.Repositories.Base;
using BlogProject.DataAccess.Repositories.Base.Interfaces;
using BlogProject.DataAccess.Repositories.Relations;
using BlogProject.DataAccess.Repositories.Relations.Interfaces;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;

var builder = WebApplication.CreateBuilder(args);

var isDevelopment = builder.Environment.IsDevelopment();

builder.Services.AddControllers();
builder.Services.AddCors();

builder.Services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        var key = builder.Configuration["JsonWebTokenKeys:IssuerSigningKey"];
        var encodedKey = Encoding.UTF8.GetBytes(key);
        var signingKey = new SymmetricSecurityKey(encodedKey);

        options.RequireHttpsMetadata = false;
        options.SaveToken = true;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = signingKey,
            ValidateIssuer = false,
            ValidateAudience = false,
        };
    });
builder.Services.AddScoped<IJwtAuthenticationManager, JwtAuthenticationManager>();


builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    var openApiSecurityScheme = new OpenApiSecurityScheme
    {
        Description = "Standard Authorization header using the Bearer scheme (\"bearer {token}\")",
        In = ParameterLocation.Header,
        Name = "Authorization",
        Type = SecuritySchemeType.ApiKey
    };

    options.AddSecurityDefinition("oauth2", openApiSecurityScheme);
    options.OperationFilter<SecurityRequirementsOperationFilter>();
});

builder.Services.AddAutoMapper(typeof(MapProfile));

builder.Services.AddDbContext<BlogProjectDbContext>(
    optionsBuilder =>
    {
        var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
        optionsBuilder.UseNpgsql(connectionString);

        optionsBuilder.EnableDetailedErrors(isDevelopment);
        optionsBuilder.EnableSensitiveDataLogging(isDevelopment);
    });


builder.Services.AddScoped<IPostRepository, EFPostRepository>();
builder.Services.AddScoped<ICommentRepository, EFCommentRepository>();
builder.Services.AddScoped<IUserRepository, EFUserRepository>();
builder.Services.AddScoped<ITagRepository, EFTagRepository>();
builder.Services.AddScoped<ICategoryRepository, EFCategoryRepository>();

builder.Services.AddScoped<IPostsEditorsRepository, EFPostsEditorsRepository>();
builder.Services.AddScoped<IPostsTagsRepository, EFPostsTagsRepository>();
builder.Services.AddScoped<IUsersCommentReactionsRepository, EFUsersCommentReactionsRepository>();
builder.Services.AddScoped<IUsersPostReactionsRepository, EFUsersPostReactionsRepository>();


builder.Services.AddScoped<IPostService, PostService>();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<ICommentService, CommentService>();
builder.Services.AddScoped<ITagService, TagService>();
builder.Services.AddScoped<ITagService, TagService>();

var app = builder.Build();

if (isDevelopment)
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseCors(policyBuilder => policyBuilder.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:3000"));

app.UseHttpsRedirection();

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

app.MapControllers();

app.Run();

业务/服务/AuthenticationService/JwtAuthenticationManager.cs

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using BlogProject.DataAccess.Repositories.Base.Interfaces;
using BlogProject.Entities.Base;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using JwtRegisteredClaimNames = Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames;

namespace BlogProject.Business.Services.AuthenticationService;

public class JwtAuthenticationManager : IJwtAuthenticationManager
{
    private readonly IUserRepository _userRepository;
    private readonly string _jwtTokenSecret;
    private readonly string _jwtTokenSubject;

    public JwtAuthenticationManager(
        IConfiguration configuration,
        IUserRepository userRepository)
    {
        _jwtTokenSecret = configuration["JsonWebTokenKeys:IssuerSigningKey"];
        _jwtTokenSubject = configuration["JsonWebTokenKeys:Subject"];
        _userRepository = userRepository;
    }

    public async Task<string?> GetJwtTokenAsync(string username)
    {
        var user = await _userRepository.ValidateUserAsync(username);
        if(user == null) return null;

        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtTokenSecret));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
        var expireTime = DateTime.UtcNow.AddDays(1);

        var token = new JwtSecurityToken(
            claims : GetClaim(user),
            expires : new DateTimeOffset(expireTime).DateTime,
            signingCredentials : credentials);

        var tokenHandler = new JwtSecurityTokenHandler();

        var jwtString = tokenHandler.WriteToken(token);

        return jwtString;
    }

    private IEnumerable<Claim> GetClaim(User user)
    {
        return new Claim[] 
        {
            new Claim(JwtRegisteredClaimNames.Sub, _jwtTokenSubject),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
            new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()),
            new Claim("Id", user.Id.ToString()),
            new Claim("UserName", user.Username),
            new Claim("Email", user.Email),
            new Claim("Role", user.Role)
        };
    }
}

API/Controller/UserController.cs:登录

[HttpGet("Login")]
public async Task<IActionResult> Login(string username, string password)
{
    var response = await _userService.ValidateUserAsync(username, password);

    if (response == null) return NotFound();

    var tokenResponse = await _jwtAuthenticationManager.GetJwtTokenAsync(response.UserName);

    if (tokenResponse == null) throw new Exception("Token is null");

    response.Token = tokenResponse;

     Ok(response);
}

这很尴尬。 最近我从 API 中删除了一些包。 看起来像删除“System.IdentityModel.Tokens.Jwt”以某种方式破坏了代码。 但是有一点我不明白。 它仍然在 jwt.io 处显示“无效签名”,但令牌有效。

是的,我将秘密粘贴到该领域。

暂无
暂无

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

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