Я искал несколько похожих вопросов, но никто не помог мне.У меня следующая ситуация:
Базовая аутентификация JWT в .NET Core 2.2, Startup.cs имеет следующие настройки:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
var signingConfigurations = new SigningConfigurations();
services.AddSingleton(signingConfigurations);
var tokenConfigurations = new TokenConfigurations();
new ConfigureFromConfigurationOptions<TokenConfigurations>(
Configuration.GetSection("TokenConfigurations"))
.Configure(tokenConfigurations);
services.AddSingleton(tokenConfigurations);
services.AddAuthentication(authOptions =>
{
authOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
authOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(bearerOptions =>
{
var paramsValidation = bearerOptions.TokenValidationParameters;
paramsValidation.IssuerSigningKey = signingConfigurations.Key;
paramsValidation.ValidAudience = tokenConfigurations.Audience;
paramsValidation.ValidIssuer = tokenConfigurations.Issuer;
// Validates a received token signature
paramsValidation.ValidateIssuerSigningKey = true;
// Verifies if a received token is still valid
paramsValidation.ValidateLifetime = true;
// Tolerance time for token expiration (used if there are timezone differences)
paramsValidation.ClockSkew = TimeSpan.Zero;
});
// Activates token usage on this project
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
Затем для создания токена:
LoginController.cs
if (validCredentials)
{
ClaimsIdentity declarations = new ClaimsIdentity(
new GenericIdentity(userInDB.UserName, "Login"),
new[] {
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString("N")),
new Claim(JwtRegisteredClaimNames.UniqueName, userInDB.UserName),
new Claim("userid", userInDB.Id, ClaimValueTypes.String),
new Claim("username", userInDB.UserName, ClaimValueTypes.String),
}
);
DateTime creationDate = DateTime.Now;
DateTime expirationDate = creationDate +
TimeSpan.FromSeconds(tokenConfigurations.Seconds);
var handler = new JwtSecurityTokenHandler();
var securityToken = handler.CreateToken(new SecurityTokenDescriptor
{
Issuer = tokenConfigurations.Issuer,
Audience = tokenConfigurations.Audience,
SigningCredentials = signingConfigurations.SigningCredentials,
Subject = declarations,
NotBefore = creationDate,
Expires = expirationDate
});
var token = handler.WriteToken(securityToken);
return new
{
authenticated = true,
created = creationDate.ToString("yyyy-MM-dd HH:mm:ss"),
expiration = expirationDate.ToString("yyyy-MM-dd HH:mm:ss"),
accessToken = token,
message = "OK"
};
}
Все, что я до сих пор делал, основано на этом пошаговом руководстве.
Пока все хорошо.Если я добавлю [Authorize("Bearer")]
на контроллере, к нему можно будет получить доступ, только если у меня есть носитель в заголовке запроса.
Но так как я реализовывал структуру UserSession, для перехвата любого запроса, пройдите черезHttpContext и заполнить объект UserSession, он просто не работает.Ответственный метод таков:
ApplicationBuilderExtensions.cs
public static IApplicationBuilder UseSessionConfiguration(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<SessionConfigurationMiddleware>();
}
public class SessionConfigurationMiddleware
{
private readonly RequestDelegate _next;
public SessionConfigurationMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context, IUserSession sessao)
{
if (context.User.Identities.Any(id => id.IsAuthenticated))
{
sessao.UserId = context.User.Claims.FirstOrDefault(x => x.Type == "userid").Value;
sessao.Roles = context.User.Claims.Where(x => x.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role").Select(x => x.Value).ToList();
sessao.UserName = context.User.Claims.FirstOrDefault(x => x.Type == "username").Value;
}
// Call the next delegate/middleware in the pipeline
await _next.Invoke(context);
}
}
Но, когда я отлаживаю эту часть кода (который правильно вызывается после любого запроса)свойство IsAuthenticated
в HttpContext всегда ложно, на самом деле в context.User
все равно нулю или пусто, и я понятия не имею, почему.
Я неправильно настраиваю jwt?
промежуточное программное обеспечение неверно?
Правильно ли я заполняю заявки на jwt?
Почему [Authorize("Bearer")]
работает правильно, если HttpContext
заполнен неправильно?
Мы одни во вселенной?
Заранее спасибо.