错误 401 未经授权。 ASP.NET 核心。使用 JWT 创建身份验证/授权

问题描述 投票:0回答:1

我正在使用 JWT 创建身份验证/授权。我得到了令牌: creating token,但是粘贴到swagger后还是报错401 invalid tokenresponse from server 这是 jwt 解码: decoding

是的,我也尝试过使用和不使用秘密 Base64 编码

github(如果需要):https://github.com/oleggl47l/BookStoreFullstackApp/tree/main/backend/Bookstore

这是我的 AuthService:

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using BookStore.Application.Security;
using Bookstore.Configurations;
using BookStore.DataAccess;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;

namespace BookStore.Application.Services;

public class AuthService {
    private readonly BookStoreDbContext _context;

    public AuthService(BookStoreDbContext context) {
        _context = context;
    }

    public async Task<string> AuthenticateAsync(string email, string password) {
        var user = await _context.Users.Include(user => user.Role).FirstOrDefaultAsync(u => u.Email == email);

        if (user == null) {
            return null; 
        }

        if (!PasswordHasher.VerifyPassword(password, user.PasswordHash)) {
            return null; 
        }

        var claims = new List<Claim> {
            new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString()),
            new Claim(ClaimTypes.GivenName, user.FirstName),
            new Claim(ClaimTypes.Surname, user.LastName),
            new Claim(ClaimTypes.Email, user.Email),
            new Claim(ClaimTypes.Role, user.Role.Name)
        };

        var jwt = new JwtSecurityToken(
            issuer: AuthConfig.ISSUER,
            audience: AuthConfig.AUDIENCE,
            claims: claims,
            expires: DateTime.UtcNow.Add(TimeSpan.FromMinutes(2)),
            signingCredentials: new SigningCredentials(AuthConfig.GetSymmetricSecurityKey(),
                SecurityAlgorithms.HmacSha256));

        return new JwtSecurityTokenHandler().WriteToken(jwt);
    }
}

验证配置:

using System.Text;
using Microsoft.IdentityModel.Tokens;

namespace Bookstore.Configurations;

public class AuthConfig {
    public const string ISSUER = "randomauthserver"; 
    public const string AUDIENCE = "randomauthclient.com"; 
    public const string KEY = "randomrandomradndomrandomrandom_randomsecret@123123!!!";   
    
    public static SymmetricSecurityKey GetSymmetricSecurityKey() => 
        new SymmetricSecurityKey(Encoding.UTF8.GetBytes(KEY));
}

AuthCintroller:

using BookStore.Application.Services;
using BookStore.Application.Utilities;
using Microsoft.AspNetCore.Mvc;

namespace Bookstore.Controllers;

[Route("api/[controller]")]
[ApiController]
public class AuthController : Controller {
    private readonly AuthService _authService;

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

    [HttpPost("login")]
    public async Task<IActionResult> LoginAsync([FromBody] LoginModel loginModel) {
        var token = await _authService.AuthenticateAsync(loginModel.Email, loginModel.Password);
        if (token == null) {
            return Unauthorized("Invalid email or password");
        }
        return Ok(new { Token = token });
    }
}

程序.cs:

using BookStore.Application.Interfaces;
using BookStore.Application.Services;
using Bookstore.Configurations;
using BookStore.DataAccess;
using BookStore.DataAccess.Interfaces;
using BookStore.DataAccess.Repositories;
using Bookstore.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddControllers();

string connection =
    builder.Configuration.GetConnectionString("StoreDbContext") ?? string.Empty;
builder.Services.AddDbContext<BookStoreDbContext>(options => options.UseNpgsql(connection));

builder.Services.AddScoped<ICRUDService<Book>, BookCRUDService>();
builder.Services.AddScoped<IRepository<Book>, BookRepository>();

builder.Services.AddScoped<ICRUDService<OrderItem>, OrderItemCRUDService>();
builder.Services.AddScoped<IRepository<OrderItem>, OrderItemRepository>();

builder.Services.AddScoped<ICRUDService<Order>, OrderCRUDService>();
builder.Services.AddScoped<IRepository<Order>, OrderRepository>();

builder.Services.AddScoped<ICRUDService<Role>, RoleCRUDService>();
builder.Services.AddScoped<IRepository<Role>, RoleRepository>();

builder.Services.AddScoped<ICRUDService<User>, UserCRUDService>();
builder.Services.AddScoped<IRepository<User>, UserRepository>();

builder.Services.AddScoped<RegistrationService>();
builder.Services.AddScoped<AuthService>();

builder.Services.AddScoped<OrderService>();

builder.Services.AddSwaggerGen(opt => {
    opt.SwaggerDoc("v1", new OpenApiInfo { Title = "BookStore", Version = "v1" });
    opt.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme {
        In = ParameterLocation.Header,
        Description = "Please enter token",
        Name = "Authorization",
        Type = SecuritySchemeType.Http,
        BearerFormat = "JWT",
        Scheme = "bearer"
    });
    opt.AddSecurityRequirement(new OpenApiSecurityRequirement {
        {
            new OpenApiSecurityScheme {
                Reference = new OpenApiReference {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            new string[] { }
        }
    });
});

builder.Services.AddAuthorization();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => {
        options.TokenValidationParameters = new TokenValidationParameters {
            ValidateIssuer = true,
            ValidIssuer = AuthConfig.ISSUER,
            ValidateAudience = true,
            ValidAudience = AuthConfig.AUDIENCE,
            ValidateLifetime = true,
            IssuerSigningKey = AuthConfig.GetSymmetricSecurityKey(),
            ValidateIssuerSigningKey = true,
        };
    });


var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

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

app.MapControllers();

app.Run();
c# asp.net-core asp.net-web-api jwt authorization
1个回答
0
投票

在您的 RoleCRUD 端点(或任何需要授权的端点)中,将 [Authorize] 替换为:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
© www.soinside.com 2019 - 2024. All rights reserved.