.net - 登录在使用 .net 核心身份的身份验证中不起作用
问题描述
我一直在尝试在我的项目中实现登录和注册。注册用户工作得很好,但登录没有。我尝试了很多方法,但我只是不明白为什么这不起作用。
它不断返回错误 401(未经授权),我认为这是因为控制器中的登录方法。
这是我的帐户控制器:
using Powerpc.Models;
using Powerpc.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
using System.Threading.Tasks;
using Powerpc.DTOs;
namespace Powerpc.Controllers
{
[AllowAnonymous]
[Route("api/[controller]")]
[ApiController]
public class AccountController : ControllerBase
{
private readonly UserManager<AppUser> _userManager;
private readonly SignInManager<AppUser> _signInManager;
private readonly TokenService _tokenService;
public AccountController(UserManager<AppUser> userManager,
SignInManager<AppUser> signInManager, TokenService tokenService)
{
_tokenService = tokenService;
_signInManager = signInManager;
_userManager = userManager;
}
[AllowAnonymous]
[HttpPost("login")]
public async Task<ActionResult<UserDto>> Login(LoginDto loginDto)
{
var user = await _userManager.FindByEmailAsync(loginDto.Email);
if (user == null) return Unauthorized();
var result = await _signInManager.CheckPasswordSignInAsync(user, loginDto.Password, false);
if (result.Succeeded)
{
return CreateUserObject(user);
}
return Unauthorized();
}
[AllowAnonymous]
[HttpPost("register")]
public async Task<ActionResult<UserDto>> Register(RegisterDto registerDto)
{
if (await _userManager.Users.AnyAsync(x => x.Email == registerDto.Email))
{
return BadRequest("Email Taken");
}
if (await _userManager.Users.AnyAsync(x => x.UserName == registerDto.Username))
{
return BadRequest("Username Taken");
}
var user = new AppUser
{
DisplayName = registerDto.DisplayName,
Email = registerDto.Email,
UserName = registerDto.Username
};
var result = await _userManager.CreateAsync(user, registerDto.Password);
if (result.Succeeded)
{
return CreateUserObject(user);
}
return BadRequest("Problem registering user");
}
[Authorize]
[HttpGet]
public async Task<ActionResult<UserDto>> GetCurrentUser()
{
var user = await _userManager.FindByEmailAsync(User.FindFirstValue(ClaimTypes.Email));
return CreateUserObject(user);
}
private UserDto CreateUserObject(AppUser user)
{
return new UserDto
{
DisplayName = user.DisplayName,
Token = _tokenService.CreateToken(user),
Username = user.UserName
};
}
}
}
这是我在 Startup 类中包含的 IdentityServiceExtension:
using Powerpc.Models;
using Powerpc.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Powerpc.Extensions
{
public static class IdentityServiceExtension
{
public static IServiceCollection AddIdentityServices(this IServiceCollection services,
IConfiguration config)
{
services.AddIdentityCore<AppUser>(opt =>
{
opt.Password.RequireNonAlphanumeric = false;
opt.SignIn.RequireConfirmedEmail = true;
})
.AddEntityFrameworkStores<DataContext>()
.AddSignInManager<SignInManager<AppUser>>();
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["TokenKey"]));
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = key,
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddScoped<TokenService>();
return services;
}
}
}
这是上面类中包含的我的 TokenService 类:
using Powerpc.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace Powerpc.Services
{
public class TokenService
{
private readonly IConfiguration _config;
public TokenService(IConfiguration config)
{
_config = config;
}
public string CreateToken(AppUser user)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.NameIdentifier, user.Id),
new Claim(ClaimTypes.Email, user.Email),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["TokenKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = creds
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
}
我的 appsettings.json 中还有一个令牌密钥。
我不确定这里还包括什么。如果有更多信息需要你们弄清楚,我会把它放在这里。
十分感谢!