-
Notifications
You must be signed in to change notification settings - Fork 28
Make JwtBearerService public #192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1203a9a
a6e42b8
11332d3
8deef46
cac6f2e
00680ec
711c23f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,27 +6,40 @@ | |||||||||||||||||
|
|
||||||||||||||||||
| namespace SimpleAuthentication.JwtBearer; | ||||||||||||||||||
|
|
||||||||||||||||||
| internal class JwtBearerService(IOptions<JwtBearerSettings> jwtBearerSettingsOptions) : IJwtBearerService | ||||||||||||||||||
| /// <summary> | ||||||||||||||||||
| /// Default implementation of <see cref="IJwtBearerService"/> that provides JWT Bearer token generation and validation. | ||||||||||||||||||
| /// </summary> | ||||||||||||||||||
| /// <param name="jwtBearerSettingsOptions">The JWT Bearer settings.</param> | ||||||||||||||||||
| public class JwtBearerService(IOptions<JwtBearerSettings> jwtBearerSettingsOptions) : IJwtBearerService | ||||||||||||||||||
| { | ||||||||||||||||||
| private readonly JwtBearerSettings jwtBearerSettings = jwtBearerSettingsOptions.Value; | ||||||||||||||||||
| /// <summary> | ||||||||||||||||||
| /// Gets the JWT Bearer settings used by this service. | ||||||||||||||||||
| /// </summary> | ||||||||||||||||||
| protected JwtBearerSettings JwtBearerSettings { get; } = jwtBearerSettingsOptions?.Value ?? throw new ArgumentNullException(nameof(jwtBearerSettingsOptions)); | ||||||||||||||||||
|
|
||||||||||||||||||
| public Task<string> CreateTokenAsync(string userName, IList<Claim>? claims = null, string? issuer = null, string? audience = null, DateTime? absoluteExpiration = null) | ||||||||||||||||||
| /// <inheritdoc /> | ||||||||||||||||||
| public virtual Task<string> CreateTokenAsync(string userName, IList<Claim>? claims = null, string? issuer = null, string? audience = null, DateTime? absoluteExpiration = null) | ||||||||||||||||||
| { | ||||||||||||||||||
| var now = DateTime.UtcNow; | ||||||||||||||||||
|
|
||||||||||||||||||
| if (absoluteExpiration.HasValue && absoluteExpiration.Value < now) | ||||||||||||||||||
| { | ||||||||||||||||||
| throw new ArgumentException("The expiration date must be greater than or equal to the current date and time.", nameof(absoluteExpiration)); | ||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+23
to
+28
|
||||||||||||||||||
|
|
||||||||||||||||||
| claims ??= []; | ||||||||||||||||||
|
||||||||||||||||||
| claims ??= []; | |
| claims = claims switch | |
| { | |
| null => new global::System.Collections.Generic.List<Claim>(), | |
| { IsReadOnly: true } => new global::System.Collections.Generic.List<Claim>(claims), | |
| _ => claims | |
| }; |
Copilot
AI
Apr 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RefreshTokenAsync assumes the validated token always contains a claim with Type == JwtBearerSettings.NameClaimType and uses First(...), which will throw InvalidOperationException if the claim is missing. Since ValidateTokenAsync can succeed even when that claim isn't present, consider handling the missing-claim case explicitly and throwing a more appropriate exception (e.g., SecurityTokenException/ArgumentException) with a clear message.
| var userName = claims.First(c => c.Type == JwtBearerSettings.NameClaimType).Value; | |
| var nameClaim = claims.FirstOrDefault(c => c.Type == JwtBearerSettings.NameClaimType); | |
| if (string.IsNullOrEmpty(nameClaim?.Value)) | |
| { | |
| throw new SecurityTokenException($"Token does not contain the required '{JwtBearerSettings.NameClaimType}' claim."); | |
| } | |
| var userName = nameClaim.Value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JwtBearerSettingsinitialization usesjwtBearerSettingsOptions?.Value ?? throw new ArgumentNullException(nameof(jwtBearerSettingsOptions)), which throws anArgumentNullExceptionfor the options parameter even whenjwtBearerSettingsOptionsis non-null but.Valueis null. Consider validatingjwtBearerSettingsOptionsexplicitly (per project style) and failing with a more accurate exception if the bound settings instance is null.