Example #1
0
        /// <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);
        }
Example #5
0
        /// <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);
        }
Example #6
0
        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);
        }