Browse Source
- add [TokenWildcardIssuerValidator](https://github.com/maliming/Owl.TokenWildcardIssuerValidator) - The microservice module adds jwt `IssuerValidator`pull/1235/head
23 changed files with 115 additions and 263 deletions
@ -1,112 +0,0 @@ |
|||
|
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LY.MicroService.Applications.Single; |
|||
|
|||
[Dependency(ServiceLifetime.Singleton, ReplaceServices = true)] |
|||
public class AbpDynamicFeatureDefinitionStoreInMemoryCache : IDynamicFeatureDefinitionStoreInMemoryCache |
|||
{ |
|||
public string CacheStamp { get; set; } |
|||
|
|||
protected IDictionary<string, FeatureGroupDefinition> FeatureGroupDefinitions { get; } |
|||
protected IDictionary<string, FeatureDefinition> FeatureDefinitions { get; } |
|||
protected StringValueTypeSerializer StateCheckerSerializer { get; } |
|||
protected ILocalizableStringSerializer LocalizableStringSerializer { get; } |
|||
|
|||
public SemaphoreSlim SyncSemaphore { get; } = new(1, 1); |
|||
|
|||
public DateTime? LastCheckTime { get; set; } |
|||
|
|||
public AbpDynamicFeatureDefinitionStoreInMemoryCache( |
|||
StringValueTypeSerializer stateCheckerSerializer, |
|||
ILocalizableStringSerializer localizableStringSerializer) |
|||
{ |
|||
StateCheckerSerializer = stateCheckerSerializer; |
|||
LocalizableStringSerializer = localizableStringSerializer; |
|||
|
|||
FeatureGroupDefinitions = new Dictionary<string, FeatureGroupDefinition>(); |
|||
FeatureDefinitions = new Dictionary<string, FeatureDefinition>(); |
|||
} |
|||
|
|||
public Task FillAsync( |
|||
List<FeatureGroupDefinitionRecord> featureGroupRecords, |
|||
List<FeatureDefinitionRecord> featureRecords) |
|||
{ |
|||
FeatureGroupDefinitions.Clear(); |
|||
FeatureDefinitions.Clear(); |
|||
|
|||
var context = new FeatureDefinitionContext(); |
|||
|
|||
foreach (var featureGroupRecord in featureGroupRecords) |
|||
{ |
|||
var featureGroup = context.AddGroup( |
|||
featureGroupRecord.Name, |
|||
featureGroupRecord.DisplayName != null ? LocalizableStringSerializer.Deserialize(featureGroupRecord.DisplayName) : null |
|||
); |
|||
|
|||
FeatureGroupDefinitions[featureGroup.Name] = featureGroup; |
|||
|
|||
foreach (var property in featureGroupRecord.ExtraProperties) |
|||
{ |
|||
featureGroup[property.Key] = property.Value; |
|||
} |
|||
|
|||
var featureRecordsInThisGroup = featureRecords |
|||
.Where(p => p.GroupName == featureGroup.Name); |
|||
|
|||
foreach (var featureRecord in featureRecordsInThisGroup.Where(x => x.ParentName == null)) |
|||
{ |
|||
AddFeatureRecursively(featureGroup, featureRecord, featureRecords); |
|||
} |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
public FeatureDefinition GetFeatureOrNull(string name) |
|||
{ |
|||
return FeatureDefinitions.GetOrDefault(name); |
|||
} |
|||
|
|||
public IReadOnlyList<FeatureDefinition> GetFeatures() |
|||
{ |
|||
return FeatureDefinitions.Values.ToList(); |
|||
} |
|||
|
|||
public IReadOnlyList<FeatureGroupDefinition> GetGroups() |
|||
{ |
|||
return FeatureGroupDefinitions.Values.ToList(); |
|||
} |
|||
|
|||
private void AddFeatureRecursively(ICanCreateChildFeature featureContainer, |
|||
FeatureDefinitionRecord featureRecord, |
|||
List<FeatureDefinitionRecord> allFeatureRecords) |
|||
{ |
|||
var feature = featureContainer.CreateChildFeature( |
|||
featureRecord.Name, |
|||
featureRecord.DefaultValue, |
|||
featureRecord.DisplayName != null ? LocalizableStringSerializer.Deserialize(featureRecord.DisplayName) : null, |
|||
featureRecord.Description != null ? LocalizableStringSerializer.Deserialize(featureRecord.Description) : null, |
|||
StateCheckerSerializer.Deserialize(featureRecord.ValueType), |
|||
featureRecord.IsVisibleToClients, |
|||
featureRecord.IsAvailableToHost |
|||
); |
|||
|
|||
FeatureDefinitions[feature.Name] = feature; |
|||
|
|||
if (!featureRecord.AllowedProviders.IsNullOrWhiteSpace()) |
|||
{ |
|||
feature.AllowedProviders.AddRange(featureRecord.AllowedProviders.Split(',')); |
|||
} |
|||
|
|||
foreach (var property in featureRecord.ExtraProperties) |
|||
{ |
|||
feature[property.Key] = property.Value; |
|||
} |
|||
|
|||
foreach (var subFeature in allFeatureRecords.Where(p => p.ParentName == featureRecord.Name)) |
|||
{ |
|||
AddFeatureRecursively(feature, subFeature, allFeatureRecords); |
|||
} |
|||
} |
|||
} |
|||
@ -1,127 +0,0 @@ |
|||
using Microsoft.IdentityModel.Tokens; |
|||
using System.Globalization; |
|||
using System.Text; |
|||
using Volo.Abp.Text.Formatting; |
|||
|
|||
namespace LY.MicroService.Applications.Single; |
|||
|
|||
/// <summary>
|
|||
/// https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/dev/src/Microsoft.IdentityModel.Tokens/Validators.cs#L207
|
|||
/// </summary>
|
|||
public static class TokenWildcardIssuerValidator |
|||
{ |
|||
private const string IDX10204 = "IDX10204: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace AND validationParameters.ValidIssuers is null."; |
|||
private const string IDX10205 = "IDX10205: Issuer validation failed. Issuer: '{0}'. Did not match: validationParameters.ValidIssuer: '{1}' or validationParameters.ValidIssuers: '{2}'."; |
|||
private const string IDX10211 = "IDX10211: Unable to validate issuer. The 'issuer' parameter is null or whitespace"; |
|||
private const string IDX10235 = "IDX10235: ValidateIssuer property on ValidationParameters is set to false. Exiting without validating the issuer."; |
|||
private const string IDX10236 = "IDX10236: Issuer Validated.Issuer: '{0}'"; |
|||
|
|||
public static readonly IssuerValidator IssuerValidator = (issuer, token, validationParameters) => |
|||
{ |
|||
if (validationParameters == null) |
|||
{ |
|||
throw LogHelper.LogArgumentNullException(nameof(validationParameters)); |
|||
} |
|||
|
|||
if (!validationParameters.ValidateIssuer) |
|||
{ |
|||
LogHelper.LogInformation(IDX10235); |
|||
return issuer; |
|||
} |
|||
|
|||
if (string.IsNullOrWhiteSpace(issuer)) |
|||
{ |
|||
throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(IDX10211) |
|||
{ |
|||
InvalidIssuer = issuer |
|||
}); |
|||
} |
|||
|
|||
// Throw if all possible places to validate against are null or empty
|
|||
if (string.IsNullOrWhiteSpace(validationParameters.ValidIssuer) && |
|||
validationParameters.ValidIssuers == null) |
|||
{ |
|||
throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(IDX10204) |
|||
{ |
|||
InvalidIssuer = issuer |
|||
}); |
|||
} |
|||
|
|||
if (string.Equals(validationParameters.ValidIssuer, issuer, StringComparison.Ordinal)) |
|||
{ |
|||
LogHelper.LogInformation(IDX10236, issuer); |
|||
return issuer; |
|||
} |
|||
|
|||
if (!string.IsNullOrWhiteSpace(validationParameters.ValidIssuer)) |
|||
{ |
|||
var extractResult = FormattedStringValueExtracter.Extract(issuer, validationParameters.ValidIssuer, ignoreCase: true); |
|||
if (extractResult.IsMatch && |
|||
extractResult.Matches.Aggregate(validationParameters.ValidIssuer, (current, nameValue) => current.Replace($"{{{nameValue.Name}}}", nameValue.Value)) |
|||
.IndexOf(issuer, StringComparison.OrdinalIgnoreCase) >= 0) |
|||
{ |
|||
return issuer; |
|||
} |
|||
} |
|||
|
|||
if (null != validationParameters.ValidIssuers) |
|||
{ |
|||
foreach (var str in validationParameters.ValidIssuers) |
|||
{ |
|||
if (string.IsNullOrEmpty(str)) |
|||
{ |
|||
LogHelper.LogInformation(IDX10235); |
|||
continue; |
|||
} |
|||
|
|||
if (string.Equals(str, issuer, StringComparison.Ordinal)) |
|||
{ |
|||
LogHelper.LogInformation(IDX10236, issuer); |
|||
return issuer; |
|||
} |
|||
|
|||
var extractResult = FormattedStringValueExtracter.Extract(issuer, str, ignoreCase: true); |
|||
if (extractResult.IsMatch && |
|||
extractResult.Matches.Aggregate(str, (current, nameValue) => current.Replace($"{{{nameValue.Name}}}", nameValue.Value)) |
|||
.IndexOf(issuer, StringComparison.OrdinalIgnoreCase) >= 0) |
|||
{ |
|||
return issuer; |
|||
} |
|||
} |
|||
} |
|||
|
|||
throw LogHelper.LogExceptionMessage( |
|||
new SecurityTokenInvalidIssuerException(LogHelper.FormatInvariant(IDX10205, issuer, |
|||
(validationParameters.ValidIssuer ?? "null"), |
|||
SerializeAsSingleCommaDelimitedString(validationParameters.ValidIssuers))) |
|||
{ |
|||
InvalidIssuer = issuer |
|||
}); |
|||
}; |
|||
|
|||
private static string SerializeAsSingleCommaDelimitedString(IEnumerable<string> strings) |
|||
{ |
|||
if (strings == null) |
|||
{ |
|||
return Utility.Null; |
|||
} |
|||
|
|||
var sb = new StringBuilder(); |
|||
var first = true; |
|||
foreach (var str in strings) |
|||
{ |
|||
if (first) |
|||
{ |
|||
sb.AppendFormat(CultureInfo.InvariantCulture, "{0}", str ?? Utility.Null); |
|||
first = false; |
|||
} |
|||
else |
|||
{ |
|||
sb.AppendFormat(CultureInfo.InvariantCulture, ", {0}", str ?? Utility.Null); |
|||
} |
|||
} |
|||
|
|||
return first ? Utility.Empty : sb.ToString(); |
|||
} |
|||
} |
|||
|
|||
@ -1,9 +1,9 @@ |
|||
{ |
|||
"version": "9.1.3", |
|||
"version": "9.2.0", |
|||
"name": "my-app-authserver", |
|||
"private": true, |
|||
"dependencies": { |
|||
"@abp/aspnetcore.mvc.ui.theme.leptonxlite": "4.1.3", |
|||
"@abp/qrcode": "9.1.3" |
|||
"@abp/aspnetcore.mvc.ui.theme.leptonxlite": "4.2.0", |
|||
"@abp/qrcode": "9.2.0" |
|||
} |
|||
} |
|||
Loading…
Reference in new issue