/// <summary> /// Maps service info credentials and 'security:oauth2:client' info onto OpenIdConnectOptions /// </summary> /// <param name="si">Service info credentials parsed from VCAP_SERVICES</param> /// <param name="oidcOptions">OpenId Connect options to be configured</param> /// <param name="cfOptions">Cloud Foundry-related OpenId Connect configuration options</param> internal static void Configure(SsoServiceInfo si, OpenIdConnectOptions oidcOptions, CloudFoundryOpenIdConnectOptions cfOptions) { if (oidcOptions == null || cfOptions == null) { return; } if (si != null) { oidcOptions.Authority = si.AuthDomain; oidcOptions.ClientId = si.ClientId; oidcOptions.ClientSecret = si.ClientSecret; } else { oidcOptions.Authority = cfOptions.Authority; oidcOptions.ClientId = cfOptions.ClientId; oidcOptions.ClientSecret = cfOptions.ClientSecret; } oidcOptions.AuthenticationMethod = cfOptions.AuthenticationMethod; oidcOptions.BackchannelHttpHandler = CloudFoundryHelper.GetBackChannelHandler(cfOptions.ValidateCertificates); oidcOptions.CallbackPath = cfOptions.CallbackPath; oidcOptions.ClaimsIssuer = cfOptions.ClaimsIssuer; oidcOptions.ResponseType = cfOptions.ResponseType; oidcOptions.SaveTokens = cfOptions.SaveTokens; oidcOptions.SignInScheme = cfOptions.SignInScheme; // remove profile scope oidcOptions.Scope.Clear(); oidcOptions.Scope.Add("openid"); // add other scopes if (!string.IsNullOrEmpty(cfOptions.AdditionalScopes)) { foreach (var s in cfOptions.AdditionalScopes.Split(' ')) { if (!oidcOptions.Scope.Contains(s)) { oidcOptions.Scope.Add(s); } } } // http://irisclasson.com/2018/09/18/asp-net-core-openidconnect-why-is-the-claimsprincipal-name-null/ oidcOptions.TokenValidationParameters.NameClaimType = cfOptions.TokenValidationParameters.NameClaimType; // main objective here is to set the IssuerSigningKeyResolver to work around an issue parsing the N value of the signing key in FullFramework oidcOptions.TokenValidationParameters = CloudFoundryHelper.GetTokenValidationParameters(oidcOptions.TokenValidationParameters, oidcOptions.Authority + CloudFoundryDefaults.JwtTokenUri, oidcOptions.BackchannelHttpHandler, cfOptions.ValidateCertificates, cfOptions.BaseOptions(oidcOptions.ClientId)); oidcOptions.TokenValidationParameters.ValidateAudience = cfOptions.TokenValidationParameters.ValidateAudience; oidcOptions.TokenValidationParameters.ValidateLifetime = cfOptions.TokenValidationParameters.ValidateLifetime; // the ClaimsIdentity is built off the id_token, but scopes are returned in the access_token. Copy them as claims oidcOptions.Events.OnTokenValidated = MapScopesToClaims; }
/// <summary> /// Maps service info credentials and 'security:oauth2:client' info onto OpenIdConnectOptions /// </summary> /// <param name="si">Service info credentials parsed from VCAP_SERVICES</param> /// <param name="oidcOptions">OpenId Connect options to be configured</param> /// <param name="cfOptions">Cloud Foundry-related OpenId Connect configuration options</param> internal static void Configure(SsoServiceInfo si, OpenIdConnectOptions oidcOptions, CloudFoundryOpenIdConnectOptions cfOptions) { if (oidcOptions == null || cfOptions == null) { return; } if (si != null) { oidcOptions.Authority = si.AuthDomain; oidcOptions.ClientId = si.ClientId; oidcOptions.ClientSecret = si.ClientSecret; } else { oidcOptions.Authority = cfOptions.Authority; oidcOptions.ClientId = cfOptions.ClientId; oidcOptions.ClientSecret = cfOptions.ClientSecret; } oidcOptions.AuthenticationMethod = cfOptions.AuthenticationMethod; oidcOptions.BackchannelHttpHandler = CloudFoundryHelper.GetBackChannelHandler(cfOptions.ValidateCertificates); oidcOptions.CallbackPath = cfOptions.CallbackPath; oidcOptions.ClaimsIssuer = cfOptions.ClaimsIssuer; oidcOptions.ResponseType = cfOptions.ResponseType; oidcOptions.SaveTokens = cfOptions.SaveTokens; oidcOptions.SignInScheme = cfOptions.SignInScheme; // remove profile scope oidcOptions.Scope.Clear(); oidcOptions.Scope.Add("openid"); // add other scopes if (!string.IsNullOrEmpty(cfOptions.AdditionalScopes)) { foreach (var s in cfOptions.AdditionalScopes.Split(' ')) { if (!oidcOptions.Scope.Contains(s)) { oidcOptions.Scope.Add(s); } } } oidcOptions.TokenValidationParameters = CloudFoundryHelper.GetTokenValidationParameters( cfOptions.TokenValidationParameters, oidcOptions.Authority + CloudFoundryDefaults.JwtTokenUri, oidcOptions.BackchannelHttpHandler, cfOptions.ValidateCertificates, cfOptions.BaseOptions(oidcOptions.ClientId)); // the ClaimsIdentity is built off the id_token, but scopes are returned in the access_token. Copy them as claims oidcOptions.Events.OnTokenValidated = MapScopesToClaims; }
public override void Run(JsonElement userData, ClaimsIdentity identity, string issuer) { var scopes = CloudFoundryHelper.GetScopes(userData); if (scopes != null) { foreach (var s in scopes) { identity.AddClaim(new Claim(ClaimType, s, ValueType, issuer)); } } }
protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { _logger?.LogDebug("CreateTicketAsync()"); HttpRequestMessage request = GetTokenInfoRequestMessage(tokens); HttpClient client = GetHttpClient(); HttpClientHelper.ConfigureCertificateValidation( Options.ValidateCertificates, out SecurityProtocolType prevProtocols, out RemoteCertificateValidationCallback prevValidator); HttpResponseMessage response = null; try { response = await client.SendAsync(request, Context.RequestAborted).ConfigureAwait(false); } finally { HttpClientHelper.RestoreCertificateValidation(Options.ValidateCertificates, prevProtocols, prevValidator); } if (!response.IsSuccessStatusCode) { _logger?.LogDebug("CreateTicketAsync() failure getting token info from {requesturi}", request.RequestUri); throw new HttpRequestException($"An error occurred when retrieving token information ({response.StatusCode})."); } var resp = await response.Content.ReadAsStringAsync().ConfigureAwait(false); _logger?.LogDebug("CreateTicketAsync() received json: {json}", resp); var payload = JObject.Parse(resp); var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload); context.RunClaimActions(); await Events.CreatingTicket(context).ConfigureAwait(false); if (Options.UseTokenLifetime) { properties.IssuedUtc = CloudFoundryHelper.GetIssueTime(payload); properties.ExpiresUtc = CloudFoundryHelper.GetExpTime(payload); } await Events.CreatingTicket(context).ConfigureAwait(false); var ticket = new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name); return(ticket); }
/// <summary> /// Apply service binding info to JWT options /// </summary> /// <param name="si">Info for bound SSO Service</param> /// <param name="options">Options to be updated</param> internal static void Configure(SsoServiceInfo si, CloudFoundryJwtBearerAuthenticationOptions options) { if (options == null) { return; } if (si != null) { options.JwtKeyUrl = si.AuthDomain + CloudFoundryDefaults.JwtTokenUri; } var backchannelHttpHandler = CloudFoundryHelper.GetBackChannelHandler(options.ValidateCertificates); options.TokenValidationParameters = CloudFoundryHelper.GetTokenValidationParameters(options.TokenValidationParameters, options.JwtKeyUrl, backchannelHttpHandler, options.ValidateCertificates); }
internal static void Configure(SsoServiceInfo si, JwtBearerOptions jwtOptions, CloudFoundryJwtBearerOptions options) { if (jwtOptions == null || options == null) { return; } if (si != null) { options.JwtKeyUrl = si.AuthDomain + CloudFoundryDefaults.JwtTokenUri; } jwtOptions.ClaimsIssuer = options.ClaimsIssuer; jwtOptions.BackchannelHttpHandler = CloudFoundryHelper.GetBackChannelHandler(options.ValidateCertificates); jwtOptions.TokenValidationParameters = CloudFoundryHelper.GetTokenValidationParameters(options.TokenValidationParameters, options.JwtKeyUrl, jwtOptions.BackchannelHttpHandler, options.ValidateCertificates); jwtOptions.SaveToken = options.SaveToken; }
internal static void Configure(SsoServiceInfo si, CloudFoundryOAuthOptions options) { if (options == null) { return; } if (si != null) { options.ClientId = si.ClientId; options.ClientSecret = si.ClientSecret; options.AuthorizationEndpoint = si.AuthDomain + CloudFoundryDefaults.AuthorizationUri; options.TokenEndpoint = si.AuthDomain + CloudFoundryDefaults.AccessTokenUri; options.UserInformationEndpoint = si.AuthDomain + CloudFoundryDefaults.UserInfoUri; options.TokenInfoUrl = si.AuthDomain + CloudFoundryDefaults.CheckTokenUri; } options.BackchannelHttpHandler = CloudFoundryHelper.GetBackChannelHandler(options.ValidateCertificates); }
public static IAppBuilder UseCloudFoundryJwtBearerAuthentication(this IAppBuilder app, IConfiguration config) { var cloudFoundryOptions = new CloudFoundryJwtBearerAuthenticationOptions(); var securitySection = config.GetSection(CloudFoundryDefaults.SECURITY_CLIENT_SECTION_PREFIX); securitySection.Bind(cloudFoundryOptions); SsoServiceInfo si = config.GetSingletonServiceInfo <SsoServiceInfo>(); if (si == null) { return(app); } var jwtTokenUrl = si.AuthDomain + CloudFoundryDefaults.JwtTokenKey; var httpMessageHandler = CloudFoundryHelper.GetBackChannelHandler(cloudFoundryOptions.ValidateCertificates); var tokenValidationParameters = GetTokenValidationParameters(jwtTokenUrl, httpMessageHandler, cloudFoundryOptions.ValidateCertificates); return(app.UseJwtBearerAuthentication( new JwtBearerAuthenticationOptions { TokenValidationParameters = tokenValidationParameters, })); }
protected override async Task <AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { HttpRequestMessage request = GetTokenInfoRequestMessage(tokens); HttpClient client = GetHttpClient(); #if NET452 RemoteCertificateValidationCallback prevValidator = null; if (!Options.ValidateCertificates) { prevValidator = ServicePointManager.ServerCertificateValidationCallback; ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; } #endif HttpResponseMessage response = null; try { response = await client.SendAsync(request, Context.RequestAborted); } finally { #if NET452 ServicePointManager.ServerCertificateValidationCallback = prevValidator; #endif } response.EnsureSuccessStatusCode(); var resp = await response.Content.ReadAsStringAsync(); var payload = JObject.Parse(resp); var identifier = CloudFoundryHelper.GetId(payload); if (!string.IsNullOrEmpty(identifier)) { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer)); } var givenName = CloudFoundryHelper.GetGivenName(payload); if (!string.IsNullOrEmpty(givenName)) { identity.AddClaim(new Claim(ClaimTypes.GivenName, givenName, ClaimValueTypes.String, Options.ClaimsIssuer)); } var familyName = CloudFoundryHelper.GetFamilyName(payload); if (!string.IsNullOrEmpty(familyName)) { identity.AddClaim(new Claim(ClaimTypes.Surname, familyName, ClaimValueTypes.String, Options.ClaimsIssuer)); } var name = CloudFoundryHelper.GetName(payload); if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, Options.ClaimsIssuer)); } var email = CloudFoundryHelper.GetEmail(payload); if (!string.IsNullOrEmpty(email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String, Options.ClaimsIssuer)); } var scopes = CloudFoundryHelper.GetScopes(payload); if (scopes != null) { foreach (var s in scopes) { identity.AddClaim(new Claim("scope", s, ClaimValueTypes.String, Options.ClaimsIssuer)); } } var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Options.AuthenticationScheme); var context = new OAuthCreatingTicketContext(ticket, Context, Options, Backchannel, tokens, payload); await Options.Events.CreatingTicket(context); return(context.Ticket); }