forked from gongxuegit/tiku-backend.net
feat(security): add distributed authorization foundation
This commit is contained in:
@@ -29,6 +29,15 @@ internal static class AuthenticationExtensions
|
||||
var jwtOptions = configuration
|
||||
.GetSection("Security:Jwt")
|
||||
.Get<JwtOptions>() ?? new JwtOptions();
|
||||
services.AddOptions<BrowserAuthOptions>()
|
||||
.Bind(configuration.GetSection(BrowserAuthOptions.SectionName))
|
||||
.Validate(
|
||||
options => options.AllowedOrigins.All(origin =>
|
||||
Uri.TryCreate(origin, UriKind.Absolute, out var uri) &&
|
||||
(uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) &&
|
||||
string.IsNullOrEmpty(uri.PathAndQuery.Trim('/'))),
|
||||
"BrowserAuth AllowedOrigins must contain only HTTP(S) origins without paths.")
|
||||
.ValidateOnStart();
|
||||
|
||||
services
|
||||
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
@@ -84,11 +93,41 @@ internal static class AuthenticationExtensions
|
||||
};
|
||||
options.Events = new JwtBearerEvents
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(context.Request.Headers.Authorization) &&
|
||||
IsSameOriginBrowserRequest(context.Request) &&
|
||||
context.Request.Cookies.TryGetValue(BrowserAuthOptions.AccessCookie, out var accessToken))
|
||||
{
|
||||
context.Token = accessToken;
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
OnTokenValidated = ValidateTokenAsync,
|
||||
OnChallenge = WriteTenantConflictChallengeAsync
|
||||
};
|
||||
}
|
||||
|
||||
private static bool IsSameOriginBrowserRequest(HttpRequest request)
|
||||
{
|
||||
var source = request.Headers.Origin.ToString();
|
||||
if (string.IsNullOrWhiteSpace(source))
|
||||
{
|
||||
source = request.Headers.Referer.ToString();
|
||||
}
|
||||
|
||||
if (Uri.TryCreate(source, UriKind.Absolute, out var uri))
|
||||
{
|
||||
return string.Equals(uri.Scheme, request.Scheme, StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(uri.Authority, request.Host.Value, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
return string.Equals(
|
||||
request.Headers["Sec-Fetch-Site"].ToString(),
|
||||
"same-origin",
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static async Task ValidateTokenAsync(TokenValidatedContext context)
|
||||
{
|
||||
var principal = context.Principal;
|
||||
|
||||
Reference in New Issue
Block a user