我已经创建了一个简单的应用程序,并将使用asp.net核心标识注册和获取Access令牌。
我可以获得accesstoken,但当我尝试调用端点时,我会得到404错误代码。
程序.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var appConfiguration = builder.Configuration;
builder.Services.AddDependencies(appConfiguration);
//JWT Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
};
});
builder.Services.AddIdentity<IdentityUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = false)
.AddEntityFrameworkStores<PracticalTestWriteDbContext>()
.AddDefaultTokenProviders();
builder.Services.AddAuthorization();
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();
UserController.cs
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace PracticalTest.Endpoint.Controllers;
[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
//For admin Only
[HttpGet]
[Route("Admins")]
[Authorize(Roles = "Admin")]
public IActionResult AdminEndPoint()
{
var currentUser = GetCurrentUser();
return Ok($"Hi you are an {currentUser.Role}");
}
private UserModel GetCurrentUser()
{
var identity = HttpContext.User.Identity as ClaimsIdentity;
if (identity != null)
{
var userClaims = identity.Claims;
return new UserModel
{
UserName = userClaims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value,
Role = userClaims.FirstOrDefault(x => x.Type == ClaimTypes.Role)?.Value
};
}
return null;
}
}
public class UserModel
{
public string UserName { get; set; }
public string Role { get; set; }
}
如果我删除建设者。Services.AddIdentity<IdentityUser,IdentityRole>然后我的控制器将工作,但我需要从usermanager获取用户,然后生成令牌并在我的UserController中使用它。
这是获取访问令牌的过程:
[HttpPost]
[Route("AccessToken")]
public async Task<IActionResult> AccessToken([FromBody] LoginCredential? credential)
{
if (!ModelState.IsValid || credential == null)
{
return new BadRequestObjectResult(new { Message = "Login failed" });
}
var identityUser = await _userManager.FindByEmailAsync(credential.Email);
var roles = await _userManager.GetRolesAsync(identityUser);
if (identityUser == null)
{
return new BadRequestObjectResult(new { Message = "Login failed" });
}
var result =
_userManager.PasswordHasher.VerifyHashedPassword(identityUser, identityUser.PasswordHash,
credential.Password);
if (result == PasswordVerificationResult.Failed)
{
return new BadRequestObjectResult(new { Message = "Login failed" });
}
var accessToken = GenerateToken(credential, roles.ToList());
return Ok(new { AccessToken = accessToken });
}
private string GenerateToken(LoginCredential user,List<string> roles)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new List<Claim>()
{
new (ClaimTypes.Email,user.Email)
};
claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role)));
var token = new JwtSecurityToken(_config["Jwt:Issuer"],
_config["Jwt:Audience"],
claims,
expires: DateTime.Now.AddMinutes(15),
signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
我得到了同样的错误,并通过使用解决了这个问题;
[授权(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme(]
如果你不想使用这个,用这个来更改你的代码;
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
我用这个解决了我的问题。我希望这能有所帮助。