В настоящее время у меня возникают проблемы, при которых указанный клиент, имеющий действительное удостоверение претензии, указывающее, что клиент находится в данной роли, не авторизован для действий и контроллеров, которым требуется эта роль.
I 'Используя API для генерации токена, который клиент будет использовать для доступа как к API, так и к веб-сайту, токены генерируются как JWT.
Я просматривал другие публикации, в которых есть эта проблема, но почти всеиспользуются идентификаторы, которые не требуются для этого проекта, поскольку мы используем JWT.
Я использую HttpContext.Signin для входа в систему пользователя, передавая ему токен, полученный от API, который содержит роли пользователяи другие претензии.
Я включил код, который имеет дело с токенами, и токен, полученный от API - в самом конце -.Как ясно видно, у пользователя есть атрибут роли, но он не будет авторизован промежуточным ПО для аутентификации.
Создание токена
public async Task<string> CreateBearerTokenAsync(User user, string audience)
{
// Create identity for the client
var claims = await _clientManager.CreateUserClaimsIdentityAsync(user.Id);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = claims,
Expires = DateTime.UtcNow.AddHours(2),
IssuedAt = DateTime.UtcNow,
Issuer = "Bikefy Api",
Audience = audience,
SigningCredentials = _encryptionService.TokenSignKey
};
// Create the token
var token = new JwtSecurityTokenHandler().CreateJwtSecurityToken(tokenDescriptor);
// Write the token to string.
return new JwtSecurityTokenHandler().WriteToken(token);
}
Идентификация утверждений
public async Task<ClaimsIdentity> CreateUserClaimsIdentityAsync(Guid clientId)
{
if (clientId == null || Guid.Empty == clientId)
throw new ArgumentNullException($"{nameof(clientId)}");
var user = await GetClientByIdAsync(clientId);
var id = new ClaimsIdentity("ApiKey", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
var secKey = await GetSecurityStampAsync(clientId);
// Add default claims
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, clientId.ToString(), ClaimValueTypes.String));
if (user.FirstName != null)
id.AddClaim(new Claim(ClaimTypes.GivenName, user.FirstName, ClaimValueTypes.String));
if (user.LastName != null)
id.AddClaim(new Claim(ClaimTypes.Surname, user.LastName, ClaimValueTypes.String));
id.AddClaim(new Claim(IdentityProviderClaimType, "Bikey Identity", ClaimValueTypes.String));
id.AddClaim(new Claim(SecurityStampClaimType, secKey, ClaimValueTypes.String));
if (user.RoleName != null)
id.AddClaim(new Claim($"{nameof(User.RoleName)}", user.RoleName, ClaimValueTypes.String));
// Get roles
var roles = await GetRolesAsync(clientId);
foreach (var role in roles)
id.AddClaim(new Claim(ClaimTypes.Role, role));
// Add user claims
id.AddClaims(await GetClaimsAsync(clientId));
return id;
}
Конфигурация токена cookie
public static void ConfigureAuthentication(this IServiceCollection services, IConfiguration configuration)
{
var secretKeys = new SecretKeys();
configuration.GetSection("SecretKeys").Bind(secretKeys);
var encryptService = new EncryptionService("00E7EB8C24190E2187", secretKeys);
services.AddSingleton(encryptService);
services.AddSingleton(secretKeys);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
x.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(c =>
{
c.Cookie.Name = "CityCyles.Auth";
c.Cookie.HttpOnly = true;
c.Cookie.Expiration = TimeSpan.FromDays(1);
c.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always;
c.LoginPath = $"/Account/Login";
c.LogoutPath = $"/Account/Logout";
c.AccessDeniedPath = $"/Account/AccessDenied";
});
}
Логин пользователя
try
{
result = await _apiProvider.SendPostRequest(_apiProvider.BuildUrl("Auth", "Authenticate"), apiModel);
// Convert the string into a token
var token = new JwtSecurityTokenHandler().ReadJwtToken(result);
// Create cookie options
var authOptions = new AuthenticationProperties()
{
AllowRefresh = model.Remember,
ExpiresUtc = DateTime.UtcNow.AddHours(2),
IssuedUtc = DateTime.UtcNow,
IsPersistent = true
};
// Get the user claims from the user
var claimsIdentity = new ClaimsIdentity(token.Claims, CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
// Sign in the user
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authOptions);
// Redirect the user to the requested page or take them home
if (!string.IsNullOrEmpty(returnUrl))
return Redirect(returnUrl);
return RedirectToAction("Index", "Home");
}
catch (WebException ex)
{
_logger.LogWarning(LogEvents.HandlingLogin, ex, "Error authenticating user.");
//Display the error
ModelState.AddModelError("Custom-Error", ex.Message);
return View(model);
}
Действие контроллера
[HttpGet]
[Authorize(Roles = CityCyclesRoles.CityCyclesDocks)]
public async Task<IActionResult> OnBoard()
{
return View();
}
Токен
{
"nameid": "3e637f01-85a9-4437-a113-50d2953d014e",
"given_name": "Stephanie",
"family_name": "Lee",
"http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider": "Bikey Identity",
"Bikeyfy.Identity.SecurityStamp": "1b6228cf-945a-4503-a64e-1dcb7b649c22",
"role": "CityCycles.Staff.Docks",
"nbf": 1552586386,
"exp": 1552593586,
"iat": 1552586386,
"iss": "CityCycles Api",
"aud": "CityCycles.Web"
}