Skip to content

Commit bc008dc

Browse files
merge pull request #12 from https-richardy/feature/11-dynamic-issuer-validation-for-admin-resources
implements token validation and error handling for invalid issuer
2 parents 725d3af + 21162a2 commit bc008dc

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

Applications/Backend/Source/HttpsRichardy.Federation.Domain/Errors/AuthenticationErrors.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ public static class AuthenticationErrors
1717
Description: "The token signature is invalid."
1818
);
1919

20+
public static readonly Error InvalidIssuer = new(
21+
Code: "#ERROR-1A9C3",
22+
Description: "The token issuer is invalid."
23+
);
24+
2025
public static readonly Error InvalidRefreshToken = new(
2126
Code: "#ERROR-2C0D9",
2227
Description: "The provided refresh token is invalid, expired, or has already been used."

Applications/Backend/Source/HttpsRichardy.Federation.WebApi/Constants/Authentication.cs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,31 @@ public static class Authentication
2626
return context.Response.WriteAsync(JsonSerializer.Serialize(AuthenticationErrors.InvalidTokenFormat, _serializer));
2727
},
2828

29+
OnTokenValidated = context =>
30+
{
31+
var request = context.HttpContext.Request;
32+
if (context.SecurityToken is not Microsoft.IdentityModel.JsonWebTokens.JsonWebToken token)
33+
{
34+
context.HttpContext.Items["authentication.error"] = AuthenticationErrors.InvalidTokenFormat;
35+
context.Fail("The token format is invalid or the token is malformed.");
36+
37+
return Task.CompletedTask;
38+
}
39+
40+
var expectedIssuer = $"{request.Scheme}://{request.Host}".TrimEnd('/');
41+
var actualIssuer = token.Issuer?.TrimEnd('/');
42+
43+
if (!string.Equals(actualIssuer, expectedIssuer, StringComparison.OrdinalIgnoreCase))
44+
{
45+
context.HttpContext.Items["authentication.error"] = AuthenticationErrors.InvalidIssuer;
46+
context.Fail("The token issuer is invalid.");
47+
48+
return Task.CompletedTask;
49+
}
50+
51+
return Task.CompletedTask;
52+
},
53+
2954
OnChallenge = context =>
3055
{
3156
context.HandleResponse();
@@ -36,7 +61,11 @@ public static class Authentication
3661
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
3762
context.Response.ContentType = MediaTypeNames.Application.Json;
3863

39-
return context.Response.WriteAsync(JsonSerializer.Serialize(AuthenticationErrors.Unauthenticated, _serializer));
64+
var error = context.HttpContext.Items["authentication.error"] as Error
65+
?? AuthenticationErrors.Unauthenticated;
66+
67+
return context.Response.WriteAsync(JsonSerializer.Serialize(error, _serializer));
4068
}
4169
};
42-
}
70+
}
71+

0 commit comments

Comments
 (0)