diff options
author | crupest <crupest@outlook.com> | 2021-04-23 19:06:11 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-04-23 19:06:11 +0800 |
commit | 4b6460e7d564eebff7a79df475a702dbd3f009b9 (patch) | |
tree | 0c4cbc09b95713edcbae9858d709d71a2043e60e /BackEnd/Timeline/Auth/MyAuthenticationHandler.cs | |
parent | 15eb51e4b5014e1969677819ced1892c9e41944a (diff) | |
download | timeline-4b6460e7d564eebff7a79df475a702dbd3f009b9.tar.gz timeline-4b6460e7d564eebff7a79df475a702dbd3f009b9.tar.bz2 timeline-4b6460e7d564eebff7a79df475a702dbd3f009b9.zip |
feat: Fix #51.
Diffstat (limited to 'BackEnd/Timeline/Auth/MyAuthenticationHandler.cs')
-rw-r--r-- | BackEnd/Timeline/Auth/MyAuthenticationHandler.cs | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs b/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs index e4122c65..f1f71b20 100644 --- a/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs +++ b/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs @@ -1,13 +1,18 @@ using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Claims;
using System.Text.Encodings.Web;
+using System.Text.Json;
using System.Threading.Tasks;
+using Timeline.Models;
+using Timeline.Models.Http;
using Timeline.Services;
using static Timeline.Resources.Authentication.AuthHandler;
@@ -30,16 +35,33 @@ namespace Timeline.Auth public class MyAuthenticationHandler : AuthenticationHandler<MyAuthenticationOptions>
{
+ private const string TokenErrorCodeKey = "TokenErrorCode";
+
+ private static CommonResponse CreateChallengeResponseBody(int errorCode)
+ {
+ return new CommonResponse(errorCode, errorCode switch
+ {
+ ErrorCodes.Common.Token.TimeExpired => "The token is out of date and expired. Please create a new one.",
+ ErrorCodes.Common.Token.VersionExpired => "The token is of old version and expired. Please create a new one.",
+ ErrorCodes.Common.Token.BadFormat => "The token is of bad format. It might not be created by this server.",
+ ErrorCodes.Common.Token.UserNotExist => "The owner of the token does not exist. It might have been deleted.",
+ _ => "Unknown error."
+ });
+ }
+
private readonly ILogger<MyAuthenticationHandler> _logger;
private readonly IUserTokenManager _userTokenManager;
private readonly IUserPermissionService _userPermissionService;
- public MyAuthenticationHandler(IOptionsMonitor<MyAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IUserTokenManager userTokenManager, IUserPermissionService userPermissionService)
+ private readonly IOptionsMonitor<JsonOptions> _jsonOptions;
+
+ public MyAuthenticationHandler(IOptionsMonitor<MyAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IUserTokenManager userTokenManager, IUserPermissionService userPermissionService, IOptionsMonitor<JsonOptions> jsonOptions)
: base(options, logger, encoder, clock)
{
_logger = logger.CreateLogger<MyAuthenticationHandler>();
_userTokenManager = userTokenManager;
_userPermissionService = userPermissionService;
+ _jsonOptions = jsonOptions;
}
// return null if no token is found
@@ -49,7 +71,7 @@ namespace Timeline.Auth string header = Request.Headers[HeaderNames.Authorization];
if (!string.IsNullOrEmpty(header) && header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
{
- var token = header.Substring("Bearer ".Length).Trim();
+ var token = header["Bearer ".Length..].Trim();
_logger.LogInformation(LogTokenFoundInHeader, token);
return token;
}
@@ -98,8 +120,43 @@ namespace Timeline.Auth catch (Exception e) when (!(e is ArgumentException))
{
_logger.LogInformation(e, LogTokenValidationFail);
- return AuthenticateResult.Fail(e);
+ return AuthenticateResult.Fail(e, new AuthenticationProperties(new Dictionary<string, string?>()
+ {
+ [TokenErrorCodeKey] = (e switch
+ {
+ UserTokenTimeExpiredException => ErrorCodes.Common.Token.TimeExpired,
+ UserTokenVersionExpiredException => ErrorCodes.Common.Token.VersionExpired,
+ UserTokenBadFormatException => ErrorCodes.Common.Token.BadFormat,
+ UserTokenUserNotExistException => ErrorCodes.Common.Token.UserNotExist,
+ _ => ErrorCodes.Common.Token.Unknown
+ }).ToString(CultureInfo.InvariantCulture)
+ }));
}
}
+
+ protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
+ {
+ Response.StatusCode = 401;
+
+ CommonResponse body;
+
+ if (properties.Items.TryGetValue(TokenErrorCodeKey, out var tokenErrorCode))
+ {
+ if (!int.TryParse(tokenErrorCode, out var errorCode))
+ errorCode = ErrorCodes.Common.Token.Unknown;
+ body = CreateChallengeResponseBody(errorCode);
+ }
+ else
+ {
+ body = new CommonResponse(ErrorCodes.Common.Unauthorized, "You must use a token to authenticate.");
+ }
+
+
+ var bodyData = JsonSerializer.SerializeToUtf8Bytes(body, typeof(CommonResponse), _jsonOptions.CurrentValue.JsonSerializerOptions);
+
+ Response.ContentType = MimeTypes.ApplicationJson;
+ Response.ContentLength = bodyData.Length;
+ await Response.Body.WriteAsync(bodyData);
+ }
}
}
|