/// <summary> /// Configure Auth to trust the access token /// </summary> /// <param name="app"></param> private static void ConfigureAuth(IAppBuilder app) { string[] audiences = { ConfigurationHelper.Audience, ConfigurationHelper.ConsumerAudience }; string[] issuer = { ConfigurationHelper.Issuer, ConfigurationHelper.ConsumerIssuer }; var additionalTokenValidationParameters = new List <IReadOnlyDictionary <string, string> > { // Validate Client ID claim new Dictionary <string, string> { [Constants.AudienceTokenValidationParameter] = audiences[0], [Constants.IssuerTokenValidationParameter] = issuer[0] }, new Dictionary <string, string> { [Constants.AudienceTokenValidationParameter] = audiences[1], [Constants.IssuerTokenValidationParameter] = issuer[1] } }; var securityTokenProvider = new OpenIdConnectCachingSecurityTokenProvider($"{issuer[0]}{ConfigurationHelper.IssuerMetadataEndpoint}"); var consumerSecurityTokenProvider = new OpenIdConnectCachingSecurityTokenProvider($"{issuer[1]}{ConfigurationHelper.IssuerMetadataEndpoint}"); IEnumerable <OpenIdConnectCachingSecurityTokenProvider> tokenProviders = new List <OpenIdConnectCachingSecurityTokenProvider> { securityTokenProvider, consumerSecurityTokenProvider }; var jwtFormat = new AuthJwtFormat(audiences, additionalTokenValidationParameters, tokenProviders); app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions { AccessTokenFormat = jwtFormat, AuthenticationMode = AuthenticationMode.Active }); }
/* * Configure the authorization OWIN middleware */ public void Configure(IAppBuilder app) { // Retrieve settings from web.settings (actually, web.settings.appSettings.exclude): // We want the ClientId / CallbackUri relevent to this API service _ib2COidcConfidentialClientSettingsConfiguration = this._keyVaultService .GetObject <AuthBearerTokenSettingsConfiguration>("bearerTokenAuth:"); // Configuring with an B2C url similar to: // https://login.microsoftonline.com/{authorityTenantName}/v2.0/.well-known/openid-configuration var openIdConnectCachingSecurityTokenProvider = new OpenIdConnectCachingSecurityTokenProvider( _ib2COidcConfidentialClientSettingsConfiguration.AuthorityUri, _ib2COidcConfidentialClientSettingsConfiguration.PolicyIdB2C); // TokenValidationParameters: parameters used by System.IdentityModel.Tokens.SecurityTokenHandler validating System.IdentityModel.Tokens.SecurityToken. var tvps = new TokenValidationParameters() { // Accept only those tokens where the audience of the token is equal to the client ID of this app ValidAudiences = GetValidAudiences(), // ensure that issuers are only what we deem are necessary, maybe dont want this in the future ValidIssuers = GetValidIssuers(openIdConnectCachingSecurityTokenProvider.Issuer), }; var accessTokenFormat = new JwtFormat(tvps, openIdConnectCachingSecurityTokenProvider); // We're using OIDC, but that's really just a formal extension to OAuth, so tell the OWIN // pipeline that we're adding an auth handler. app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions { // This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint AccessTokenFormat = accessTokenFormat, Provider = new OAuthBearerUserAuthenticationProvider(_oidcNotificationHandlerService) }); }
private static JwtSecurityToken ValidateIdTokenHint(string idTokenHintString) { JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); JwtSecurityToken parsedIdTokenHint = jwtSecurityTokenHandler.ReadJwtToken(idTokenHintString); if (parsedIdTokenHint == null) { throw new InvalidDataException("IdToken is not JwtToken."); } if (parsedIdTokenHint.Claims == null || !parsedIdTokenHint.Claims.Any()) { throw new Exception("Empty claims found in id token hint"); } string tenantId = parsedIdTokenHint.Claims.First(c => c.Type == "tid").Value; if (string.IsNullOrWhiteSpace(tenantId)) { throw new InvalidDataException("Missing tenantId claim."); } if (!Settings.Default.AllowedTenantIds.Contains(tenantId)) { throw new InvalidDataException("Invalid tenant id."); } string azureADTenantMetadataUri = string.Format(AzureADMetadataUriFormat, tenantId); OpenIdConnectCachingSecurityTokenProvider oidcTokenProvider = new OpenIdConnectCachingSecurityTokenProvider(azureADTenantMetadataUri); if (!oidcTokenProvider.SecurityKeys.Any()) { throw new Exception("Couldn't retrieve security keys from OIDC metadata endpoint."); } TokenValidationParameters validationParameters = new TokenValidationParameters(); validationParameters.ValidAudience = Settings.Default.AzureADExtensionClientId; validationParameters.ValidIssuer = oidcTokenProvider.Issuer; validationParameters.ClockSkew = TimeSpan.FromMinutes(5); validationParameters.IssuerSigningKeyResolver = (token, securityToken, kid, parameters) => { return(oidcTokenProvider.SecurityKeys.Where(k => k.KeyId == kid)); }; SecurityToken validatedSecurityToken; ClaimsPrincipal claimsPrincipal = jwtSecurityTokenHandler.ValidateToken( idTokenHintString, validationParameters, out validatedSecurityToken); JwtSecurityToken validatedIdTokenHint = validatedSecurityToken as JwtSecurityToken; if (validatedIdTokenHint == null) { throw new Exception("IdToken is not a JwtSecurityToken."); } return(validatedIdTokenHint); }