У меня есть WebAPI, предназначенный для использования в качестве сервера аутентификации, который имеет конечную точку для регистрации пользователей, еще один для входа в систему пользователей и еще один для получения профиля пользователя.
Регистрация работает правильно, и вход в систему работает хорошо также очевидно.
Моя проблема заключается в следующем: конечной точке профиля пользователя требуется авторизация, поэтому я использую токен, который возвращает конечная точка входа в систему, и добавляю его в запрос в качестве токена-носителя. Запросы всегда возвращают 401: неавторизовано, хотя я использую токен, который вернул логин.
Я тестирую сервисы с почтальоном, и он не возвращает никаких ошибок с токеном, только говорит, что я не уполномочен делать этот запрос.
Это ответы в Почтальоне:
Запрос на вход:
Запрос UserProfile:
Вот код:
Запуск .cs:
public void ConfigureServices(IServiceCollection services)
{
//Inject AppSettings
services.Configure<ApplicationSettings>(Configuration.GetSection("ApplicationSettings"));
services.AddMvc(option => option.EnableEndpointRouting = false).SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddDbContext<AuthenticationContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("IdentityConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<AuthenticationContext>();
services.AddCors();
// JWT Authentication
var key = Encoding.UTF8.GetBytes(Configuration["ApplicationSettings:JWT_Secret"].ToString());
var signingKey = new SymmetricSecurityKey(key);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x => {
x.RequireHttpsMetadata = false;
x.SaveToken = false;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(builder =>
builder.WithOrigins(Configuration["ApplicationSettings:Client_URL"].ToString())
.AllowAnyHeader()
.AllowAnyMethod()
);
app.UseMvc();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
ApplicationUserController (конечные точки регистрации и входа в систему):
{
[Route("api/[controller]")]
[ApiController]
public class ApplicationUserController : ControllerBase
{
private UserManager<ApplicationUser> _userManager;
private SignInManager<ApplicationUser> _signInManager;
private readonly ApplicationSettings _appSettings;
public ApplicationUserController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, IOptions<ApplicationSettings> appSettings)
{
_userManager = userManager;
_signInManager = signInManager;
_appSettings = appSettings.Value;
}
[HttpPost]
[Route("Register")]
// POST: /api/ApplicationUser/Register
public async Task<object> PostApplicationUser(ApplicationUserModel model)
{
var applicationUser = new ApplicationUser()
{
UserName = model.UserName,
Email = model.Email,
FullName = model.FullName
};
try
{
var result = await _userManager.CreateAsync(applicationUser, model.Password);
return Ok(result);
}
catch(Exception ex)
{
throw ex;
}
}
[HttpPost]
[Route("Login")]
// POST: /api/ApplicationUser/Login
public async Task<IActionResult> Login(LoginModel model)
{
var user = await _userManager.FindByNameAsync(model.UserName);
if (user != null && await _userManager.CheckPasswordAsync(user, model.Password))
{
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim("UserId", user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.JWT_Secret)), SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(securityToken);
return Ok(new { token });
}
else
{
return BadRequest(new { message = "Username or password is incorrect" });
}
}
}
}
UserProfileController (конечная точка getUserProfile):
{
[Route("api/[controller]")]
[ApiController]
public class UserProfileController : ControllerBase
{
private UserManager<ApplicationUser> _userManager;
public UserProfileController(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
[HttpGet]
[Authorize]
//GET : /api/UserProfile
public async Task<Object> GetUserProfile()
{
string userId = User.Claims.First(c => c.Type == "UserID").Value;
var user = await _userManager.FindByIdAsync(userId);
return new
{
user.FullName,
user.Email,
user.UserName
};
}
}
Спасибо за вашу помощь, и если вам нужна дополнительная информация, просто скажите мне