Ich habe den folgenden API-Endpunkt, den ich mit dem Dekorator [Authorize] schützen möchte:
Code: Select all
[Authorize]
[Route("[controller]")]
public class FastaController : Controller
{
[HttpGet()]
public async Task Get(int page = 1, string search = "", int pageSize = 25)
{
// retrieve data here
}
}
Wenn dieser Endpunkt aufgerufen wird, wird ein Fehler „401 Unauthorized“ zurückgegeben, bevor der Code in die Methode eintritt.
Meine appsettings.json-Datei lauten wie folgt:
Code: Select all
"JwtTokenSettings": {
"Key": "fc746b61cde4f6665d3f9791446cd5395661860c0075a905ed9810b7391af467",
"Issuer": "Comply",
"Audience": "comply",
"ExpiryHours": 24
}
Ich habe auch eine Konfigurationseinstellungsklasse für JwtTokenSettings, die den gleichen Namen trägt, JwtTokenSettings (nicht gezeigt).
Ein JWT-Token wird durch den Aufruf von GenerateToken von einem JwtTokenService erstellt. Ich habe Folgendes geschrieben:
Code: Select all
public class JwtTokenService : IJwtTokenService
{
private readonly IOptions jwtTokenSettings;
public JwtTokenService(IOptions jwtTokenSettings)
{
this.jwtTokenSettings = jwtTokenSettings;
}
public string GenerateToken(Guid userId, string userEmail)
{
string secretKey = jwtTokenSettings.Value.Key;
string issuer = jwtTokenSettings.Value.Issuer;
string audience = jwtTokenSettings.Value.Audience;
var expiryHours = jwtTokenSettings.Value.ExpiryHours;
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()),
new Claim(JwtRegisteredClaimNames.Email, userEmail),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var token = new JwtSecurityToken(
issuer: issuer,
audience: audience,
claims: claims,
expires: DateTime.UtcNow.AddHours(expiryHours),
signingCredentials: credentials
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
Abschließend werden Microsoft JwtService, JwtTokenService und JwtTokenSettings wie folgt in Program.cs installiert:
Code: Select all
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure(
configuration.GetSection("JwtTokenSettings")
);
var jwtSettings = builder.Configuration.GetSection("JwtTokenSettings");
var key = Encoding.UTF8.GetBytes(jwtSettings["Key"]);
builder.Services.AddSingleton();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings["Issuer"],
ValidAudience = jwtSettings["Audience"],
IssuerSigningKey = new SymmetricSecurityKey(key)
};
});
Wenn ich den Dekorator [Authorize] vom Controller entferne, kann der Benutzer erfolgreich auf den API-Endpunkt zugreifen. Darüber hinaus kann der Benutzer mithilfe des folgenden Codes in der Get-Methode (Endpunkt) des Controllers korrekt identifiziert werden.
Code: Select all
var services = this.HttpContext.RequestServices;
var httpContextAccessor = (IHttpContextAccessor)services.GetService(typeof(IHttpContextAccessor));
var userId = httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
Auch wenn JWTService „weiß“, wer der Benutzer ist, wird es ihn nicht authentifizieren.
Ich hoffe, dass alle relevanten Teile vorliegen sind hier. Kann jemand helfen, das Problem zu erkennen? Ich weiß die Hilfe WIRKLICH zu schätzen!
Ich habe den folgenden API-Endpunkt, den ich mit dem Dekorator [Authorize] schützen möchte:
[code][Authorize]
[Route("[controller]")]
public class FastaController : Controller
{
[HttpGet()]
public async Task Get(int page = 1, string search = "", int pageSize = 25)
{
// retrieve data here
}
}
[/code]
Wenn dieser Endpunkt aufgerufen wird, wird ein Fehler „401 Unauthorized“ zurückgegeben, bevor der Code in die Methode eintritt.
Meine appsettings.json-Datei lauten wie folgt:
[code]"JwtTokenSettings": {
"Key": "fc746b61cde4f6665d3f9791446cd5395661860c0075a905ed9810b7391af467",
"Issuer": "Comply",
"Audience": "comply",
"ExpiryHours": 24
}
[/code]
Ich habe auch eine Konfigurationseinstellungsklasse für JwtTokenSettings, die den gleichen Namen trägt, JwtTokenSettings (nicht gezeigt).
Ein JWT-Token wird durch den Aufruf von GenerateToken von einem JwtTokenService erstellt. Ich habe Folgendes geschrieben:
[code]public class JwtTokenService : IJwtTokenService
{
private readonly IOptions jwtTokenSettings;
public JwtTokenService(IOptions jwtTokenSettings)
{
this.jwtTokenSettings = jwtTokenSettings;
}
public string GenerateToken(Guid userId, string userEmail)
{
string secretKey = jwtTokenSettings.Value.Key;
string issuer = jwtTokenSettings.Value.Issuer;
string audience = jwtTokenSettings.Value.Audience;
var expiryHours = jwtTokenSettings.Value.ExpiryHours;
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()),
new Claim(JwtRegisteredClaimNames.Email, userEmail),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var token = new JwtSecurityToken(
issuer: issuer,
audience: audience,
claims: claims,
expires: DateTime.UtcNow.AddHours(expiryHours),
signingCredentials: credentials
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
[/code]
Abschließend werden Microsoft JwtService, JwtTokenService und JwtTokenSettings wie folgt in Program.cs installiert:[code]var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure(
configuration.GetSection("JwtTokenSettings")
);
var jwtSettings = builder.Configuration.GetSection("JwtTokenSettings");
var key = Encoding.UTF8.GetBytes(jwtSettings["Key"]);
builder.Services.AddSingleton();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings["Issuer"],
ValidAudience = jwtSettings["Audience"],
IssuerSigningKey = new SymmetricSecurityKey(key)
};
});
[/code]
Wenn ich den Dekorator [Authorize] vom Controller entferne, kann der Benutzer erfolgreich auf den API-Endpunkt zugreifen. Darüber hinaus kann der Benutzer mithilfe des folgenden Codes in der Get-Methode (Endpunkt) des Controllers korrekt identifiziert werden.
[code]var services = this.HttpContext.RequestServices;
var httpContextAccessor = (IHttpContextAccessor)services.GetService(typeof(IHttpContextAccessor));
var userId = httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
[/code]
Auch wenn JWTService „weiß“, wer der Benutzer ist, wird es ihn nicht authentifizieren.
Ich hoffe, dass alle relevanten Teile vorliegen sind hier. Kann jemand helfen, das Problem zu erkennen? Ich weiß die Hilfe WIRKLICH zu schätzen!