Created
June 5, 2019 09:35
-
-
Save PawelHaracz/9c04ae3517ca739c378dce94eb400c98 to your computer and use it in GitHub Desktop.
the validator checks whitelist and decodes token and compare this with appId claim;
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class AsyncHelper | |
{ | |
private static readonly TaskFactory _myTaskFactory = new TaskFactory(CancellationToken.None, | |
TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default); | |
public static TResult RunSync<TResult>(Func<Task<TResult>> func) | |
{ | |
var cultureUi = CultureInfo.CurrentUICulture; | |
var culture = CultureInfo.CurrentCulture; | |
return _myTaskFactory.StartNew(() => | |
{ | |
Thread.CurrentThread.CurrentCulture = culture; | |
Thread.CurrentThread.CurrentUICulture = cultureUi; | |
return func(); | |
}).Unwrap().GetAwaiter().GetResult(); | |
} | |
public static void RunSync(Func<Task> func) | |
{ | |
var cultureUi = CultureInfo.CurrentUICulture; | |
var culture = CultureInfo.CurrentCulture; | |
_myTaskFactory.StartNew(() => | |
{ | |
Thread.CurrentThread.CurrentCulture = culture; | |
Thread.CurrentThread.CurrentUICulture = cultureUi; | |
return func(); | |
}).Unwrap().GetAwaiter().GetResult(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class WhitelistAppTokenValidation : ISecurityTokenValidator | |
{ | |
private readonly string _tenatId; | |
private readonly string _authority; | |
private readonly Guid[] _whitelist; | |
public WhitelistAppTokenValidation(string authority, string tenatId, params Guid[] whiteList) | |
{ | |
_tenatId = string.IsNullOrWhiteSpace(tenatId) == false ? tenatId : throw new ArgumentException(nameof(tenatId)); | |
_authority = string.IsNullOrWhiteSpace(authority) == false ? authority : throw new ArgumentException(nameof(authority)); | |
_whitelist = whiteList != null && whiteList.Any() ? whiteList : throw new ArgumentException(nameof(ArgumentException)); | |
} | |
public bool CanReadToken(string securityToken) => true; | |
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken) | |
{ | |
string stsDiscoveryEndpoint = $"{_authority}/{_tenatId}/v2.0/.well-known/openid-configuration"; | |
var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever()); | |
var config = AsyncHelper.RunSync(configManager.GetConfigurationAsync); | |
validationParameters.IssuerSigningKeys = config.SigningKeys; | |
var validationIssuerOldValue = validationParameters.ValidateIssuer; | |
var validateAudiencedOldValue = validationParameters.ValidateAudience; | |
validationParameters.ValidateIssuer = false; | |
validationParameters.ValidateAudience = false; | |
var tokenHandler = new JwtSecurityTokenHandler(); | |
var result = tokenHandler.ValidateToken(securityToken, validationParameters, out validatedToken); | |
var claimValue = result.Claims.GetEnumerator(); | |
var appId = Guid.Empty; | |
if (claimValue != null) | |
{ | |
while (claimValue.MoveNext()) | |
{ | |
if (claimValue.Current.Type == "appid") | |
{ | |
var aId = claimValue.Current.Value; | |
if (Guid.TryParse(aId, out appId) == false) | |
{ | |
throw new InvalidCastException($"Cannot cast string {aId} to guid"); | |
} | |
break; | |
} | |
} | |
} | |
if (appId == Guid.Empty) | |
{ | |
throw new UnauthorizedException($"Token doesn't have application Id"); | |
} | |
if (_whitelist.Contains(appId) == false) | |
{ | |
throw new UnauthorizedException($"An application Id {appId} isn't being in whitelist"); | |
} | |
validationParameters.ValidateIssuer = validationIssuerOldValue; | |
validationParameters.ValidateAudience = validateAudiencedOldValue; | |
return result; | |
} | |
public bool CanValidateToken { get; } = true; | |
public int MaximumTokenSizeInBytes { get; set; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment