/// <summary> /// Adds the <see cref="JwtAuthorizationManager"/> to a <see cref="ServiceHost"/> /// </summary> /// <param name="serviceHost">Your service to be secured with JWT Auth</param> /// <param name="configuration">Your application configuration, including VCAP_SERVICES</param> /// <param name="httpClient">Provide your own http client for interacting with the security server</param> /// <param name="loggerFactory">For logging within the library</param> /// <returns>Your service</returns> public static ServiceHost AddJwtAuthorization(this ServiceHost serviceHost, IConfiguration configuration, HttpClient httpClient = null, LoggerFactory loggerFactory = null) { if (serviceHost == null) { throw new ArgumentNullException(nameof(serviceHost)); } if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } // get options with defaults var cloudFoundryOptions = new CloudFoundryOptions(loggerFactory); // get and apply config from application var securitySection = configuration.GetSection(CloudFoundryDefaults.SECURITY_CLIENT_SECTION_PREFIX); securitySection.Bind(cloudFoundryOptions); // get and apply service binding info SsoServiceInfo info = configuration.GetSingletonServiceInfo <SsoServiceInfo>(); CloudFoundryOptionsConfigurer.Configure(info, cloudFoundryOptions); var authManager = new JwtAuthorizationManager(cloudFoundryOptions); serviceHost.Authorization.ServiceAuthorizationManager = authManager; return(serviceHost); }
public void Configure_WithServiceInfo_ReturnsExpected() { // arrange var authURL = "https://domain"; var oidcOptions = new OpenIdConnectOptions(); var info = new SsoServiceInfo("foobar", "clientId", "secret", authURL); // act CloudFoundryOpenIdConnectConfigurer.Configure(info, oidcOptions, new CloudFoundryOpenIdConnectOptions()); // assert Assert.Equal(CloudFoundryDefaults.AuthenticationScheme, oidcOptions.ClaimsIssuer); Assert.Equal(authURL, oidcOptions.Authority); Assert.Equal("clientId", oidcOptions.ClientId); Assert.Equal("secret", oidcOptions.ClientSecret); Assert.Equal(new PathString(CloudFoundryDefaults.CallbackPath), oidcOptions.CallbackPath); Assert.Null(oidcOptions.BackchannelHttpHandler); #if NETCOREAPP3_0 Assert.Equal(19, oidcOptions.ClaimActions.Count()); #else Assert.Equal(21, oidcOptions.ClaimActions.Count()); #endif Assert.Equal(CookieAuthenticationDefaults.AuthenticationScheme, oidcOptions.SignInScheme); Assert.False(oidcOptions.SaveTokens); Assert.Null(oidcOptions.BackchannelHttpHandler); }
/// <summary> /// Configures and adds <see cref="OpenIdConnectAuthenticationMiddleware" /> to the OWIN request pipeline <para /> /// Also adds a middleware to make use of X-Forwarded-Proto to maintain HTTPS redirects when operating behind a reverse proxy /// </summary> /// <param name="appBuilder">Your OWIN AppBuilder</param> /// <param name="configuration">Your application configuration</param> /// <param name="authenticationType">The identifier for this authentication type. MUST match the value used in your authentication challenge.</param> /// <param name="loggerFactory">For logging with SSO interactions</param> /// <returns>Your <see cref="IAppBuilder"/></returns> public static IAppBuilder UseCloudFoundryOpenIdConnect(this IAppBuilder appBuilder, IConfiguration configuration, string authenticationType = CloudFoundryDefaults.AuthenticationScheme, LoggerFactory loggerFactory = null) { if (appBuilder == null) { throw new ArgumentNullException(nameof(appBuilder)); } if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } // get options with defaults var cloudFoundryOptions = new OpenIdConnectOptions(authenticationType, loggerFactory); // get and apply config from application var securitySection = configuration.GetSection(CloudFoundryDefaults.SECURITY_CLIENT_SECTION_PREFIX); securitySection.Bind(cloudFoundryOptions); // get and apply service binding info SsoServiceInfo info = configuration.GetSingletonServiceInfo <SsoServiceInfo>(); OpenIdConnectConfigurer.Configure(info, cloudFoundryOptions); appBuilder.Use <ForwardedProtocolMiddleware>(); return(appBuilder.Use(typeof(OpenIdConnectAuthenticationMiddleware), appBuilder, cloudFoundryOptions)); }
internal IOptions <OAuthServiceOptions> Configure(SsoServiceInfo si, OAuthConnectorOptions configuration) { var ssoOptions = new OAuthServiceOptions(); UpdateOptions(configuration, ssoOptions); UpdateOptions(si, ssoOptions); return(new ConnectorIOptions <OAuthServiceOptions>(ssoOptions)); }
/// <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; }
private static string GetSSo(IConfiguration config, string serviceName = null) { SsoServiceInfo info = string.IsNullOrEmpty(serviceName) ? config.GetSingletonServiceInfo <SsoServiceInfo>() : config.GetRequiredServiceInfo <SsoServiceInfo>(serviceName); return(info.ToString()); }
public void Configure_NoOptions_ReturnsExpected() { // arrange SsoServiceInfo info = new SsoServiceInfo("foobar", "clientId", "secret", "http://domain"); // act CloudFoundryJwtOwinConfigurer.Configure(info, null); // nothing to assert Assert.True(true, "If we got here, we didn't attempt to set properties on a null object"); }
/// <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 void Constructor_CreatesExpected() { var clientId = "clientId"; var clientSecret = "clientSecret"; var authDomain = "https://p-spring-cloud-services.uaa.my-cf.com/oauth/token"; var r1 = new SsoServiceInfo("myId", clientId, clientSecret, authDomain); Assert.Equal("myId", r1.Id); Assert.Equal("clientId", r1.ClientId); Assert.Equal("clientSecret", r1.ClientSecret); Assert.Equal("https://p-spring-cloud-services.uaa.my-cf.com/oauth/token", r1.AuthDomain); }
public static AuthenticationBuilder AddCloudFoundryOAuth(this AuthenticationBuilder builder, string authenticationScheme, string displayName, IConfiguration config) { builder.AddOAuth <CloudFoundryOAuthOptions, CloudFoundryOAuthHandler>(authenticationScheme, displayName, (options) => { var securitySection = config.GetSection(CloudFoundryDefaults.SECURITY_CLIENT_SECTION_PREFIX); securitySection.Bind(options); SsoServiceInfo info = config.GetSingletonServiceInfo <SsoServiceInfo>(); CloudFoundryOAuthConfigurer.Configure(info, options); }); return(builder); }
/// <summary> /// Adds OpenID Connect middleware and configuration for using UAA or Pivotal SSO for user authentication /// </summary> /// <param name="builder">Your <see cref="AuthenticationBuilder"/></param> /// <param name="authenticationScheme">An identifier for this authentication mechanism. Default value is <see cref="CloudFoundryDefaults.DisplayName"/></param> /// <param name="displayName">Sets a display name for this auth scheme. Defaults to <see cref="CloudFoundryDefaults.DisplayName"/></param> /// <param name="config">Your application configuration. Be sure to include the <see cref="CloudFoundryConfigurationProvider"/></param> /// <returns><see cref="AuthenticationBuilder"/> configured to use OpenID Connect with UAA or Pivotal SSO</returns> public static AuthenticationBuilder AddCloudFoundryOpenIdConnect(this AuthenticationBuilder builder, string authenticationScheme, string displayName, IConfiguration config) { builder.AddOpenIdConnect(authenticationScheme, displayName, options => { var cloudFoundryOptions = new CloudFoundryOpenIdConnectOptions(); var securitySection = config.GetSection(CloudFoundryDefaults.SECURITY_CLIENT_SECTION_PREFIX); securitySection.Bind(cloudFoundryOptions); SsoServiceInfo info = config.GetSingletonServiceInfo <SsoServiceInfo>(); CloudFoundryOpenIdConnectConfigurer.Configure(info, options, cloudFoundryOptions); }); return(builder); }
public void Configure_WithServiceInfo_ReturnsExpected() { CloudFoundryJwtBearerOptions opts = new CloudFoundryJwtBearerOptions(); SsoServiceInfo info = new SsoServiceInfo("foobar", "clientId", "secret", "http://domain"); JwtBearerOptions jwtOpts = new JwtBearerOptions(); CloudFoundryJwtBearerConfigurer.Configure(info, jwtOpts, opts); Assert.Equal("http://domain" + CloudFoundryDefaults.JwtTokenKey, opts.JwtKeyUrl); Assert.True(opts.ValidateCertificates); Assert.Equal(opts.ClaimsIssuer, jwtOpts.ClaimsIssuer); Assert.Null(jwtOpts.BackchannelHttpHandler); Assert.NotNull(jwtOpts.TokenValidationParameters); Assert.Equal(opts.SaveToken, jwtOpts.SaveToken); }
internal void UpdateOptions(SsoServiceInfo si, OAuthServiceOptions options) { if (si == null) { return; } options.ClientId = si.ClientId; options.ClientSecret = si.ClientSecret; options.AccessTokenUrl = si.AuthDomain + OAuthConnectorDefaults.Default_AccessTokenUri; options.UserAuthorizationUrl = si.AuthDomain + OAuthConnectorDefaults.Default_AuthorizationUri; options.TokenInfoUrl = si.AuthDomain + OAuthConnectorDefaults.Default_CheckTokenUri; options.UserInfoUrl = si.AuthDomain + OAuthConnectorDefaults.Default_UserInfoUri; options.JwtKeyUrl = si.AuthDomain + OAuthConnectorDefaults.Default_JwtTokenKey; }
/// <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); }
public void Configure_WithServiceInfo_ReturnsExpected() { // arrange CloudFoundryJwtBearerAuthenticationOptions opts = new CloudFoundryJwtBearerAuthenticationOptions(); Assert.Null(opts.TokenValidationParameters); SsoServiceInfo info = new SsoServiceInfo("foobar", "clientId", "secret", "http://domain"); // act CloudFoundryJwtOwinConfigurer.Configure(info, opts); // assert Assert.Equal("http://domain" + CloudFoundryDefaults.JwtTokenUri, opts.JwtKeyUrl); Assert.True(opts.ValidateCertificates); // <- default value Assert.NotNull(opts.TokenValidationParameters); }
/// <summary> /// Apply service binding info to an <see cref="OpenIdConnectOptions"/> instance /// </summary> /// <param name="si">Service binding information</param> /// <param name="options">OpenID options to be updated</param> internal static void Configure(SsoServiceInfo si, OpenIdConnectOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (si == null) { return; } options.AuthDomain = si.AuthDomain; options.ClientId = si.ClientId; options.ClientSecret = si.ClientSecret; }
public void Configure_WithServiceInfo_ReturnsExpected() { // arrange string authURL = "http://domain"; var opts = new CloudFoundryOptions(); SsoServiceInfo info = new SsoServiceInfo("foobar", "clientId", "secret", "http://domain"); // act CloudFoundryOptionsConfigurer.Configure(info, opts); // assert Assert.Equal("clientId", opts.ClientId); Assert.Equal("secret", opts.ClientSecret); Assert.Equal(authURL + CloudFoundryDefaults.CheckTokenUri, opts.TokenInfoUrl); Assert.True(opts.ValidateCertificates); }
public CloudFoundryOptions(IConfiguration config) { // CloudFoundryDefaults.SECURITY_CLIENT_SECTION_PREFIX var securitySection = config.GetSection("security:oauth2:client"); securitySection.Bind(this); SsoServiceInfo info = config.GetSingletonServiceInfo <SsoServiceInfo>(); OAuthServiceUrl = info.AuthDomain; ClientId = info.ClientId; ClientSecret = info.ClientSecret; TokenKeyResolver = TokenKeyResolver ?? new CloudFoundryTokenKeyResolver(this); TokenValidator = TokenValidator ?? new CloudFoundryTokenValidator(this); TokenValidationParameters = TokenValidationParameters ?? GetTokenValidationParameters(this); }
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; }
public void Configure_WithServiceInfo_ReturnsExpected() { // arrange string authURL = "http://domain"; var opts = new OpenIdConnectOptions(); SsoServiceInfo info = new SsoServiceInfo("foobar", "clientId", "secret", "http://domain"); // act OpenIdConnectConfigurer.Configure(info, opts); // assert Assert.Equal(CloudFoundryDefaults.DisplayName, opts.AuthenticationType); Assert.Equal("clientId", opts.ClientId); Assert.Equal("secret", opts.ClientSecret); Assert.Equal(new PathString(CloudFoundryDefaults.CallbackPath), opts.CallbackPath); Assert.Equal(authURL + CloudFoundryDefaults.CheckTokenUri, opts.TokenInfoUrl); Assert.True(opts.ValidateCertificates); }
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 IServiceCollection AddOAuthServiceOptions(this IServiceCollection services, IConfiguration config) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } OAuthConnectorOptions oauthConfig = new OAuthConnectorOptions(config); SsoServiceInfo info = config.GetSingletonServiceInfo <SsoServiceInfo>(); OAuthConnectorFactory factory = new OAuthConnectorFactory(info, oauthConfig);; services.AddSingleton(typeof(IOptions <OAuthServiceOptions>), factory.Create); return(services); }
/// <summary> /// Apply service binding info to an <see cref="CloudFoundryOptions"/> instance /// </summary> /// <param name="si">Service binding information</param> /// <param name="options">CloudFoundryOptions options to be updated</param> internal static void Configure(SsoServiceInfo si, CloudFoundryOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (si == null) { return; } options.AuthorizationUrl = si.AuthDomain; options.ClientId = si.ClientId; options.ClientSecret = si.ClientSecret; var backchannelHttpHandler = CloudFoundryHelper.GetBackChannelHandler(options.ValidateCertificates); options.TokenValidationParameters = CloudFoundryHelper.GetTokenValidationParameters(options.TokenValidationParameters, options.AuthorizationUrl + CloudFoundryDefaults.JwtTokenUri, backchannelHttpHandler, options.ValidateCertificates, options); }
public void Update_WithServiceInfo_UpdatesOAuthOptions_AsExpected() { var opts = new OAuthServiceOptions(); var si = new SsoServiceInfo("myId", "myClientId", "myClientSecret", "https://foo.bar"); var configurer = new OAuthConfigurer(); configurer.UpdateOptions(si, opts); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_AccessTokenUri, opts.AccessTokenUrl); Assert.Equal("myClientId", opts.ClientId); Assert.Equal("myClientSecret", opts.ClientSecret); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_JwtTokenKey, opts.JwtKeyUrl); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_CheckTokenUri, opts.TokenInfoUrl); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_AuthorizationUri, opts.UserAuthorizationUrl); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_UserInfoUri, opts.UserInfoUrl); Assert.True(opts.ValidateCertificates); Assert.NotNull(opts.Scope); Assert.Equal(0, opts.Scope.Count); }
/// <summary> /// Adds SsoServiceInfo (as IOptions of type OAuthServiceOptions) to your Autofac Container /// </summary> /// <param name="container">Your Autofac Container Builder</param> /// <param name="config">Application configuration</param> /// <param name="serviceName">Cloud Foundry service name binding</param> /// <returns>the RegistrationBuilder for (optional) additional configuration</returns> public static IRegistrationBuilder <object, SimpleActivatorData, SingleRegistrationStyle> RegisterOAuthServiceOptions(this ContainerBuilder container, IConfiguration config, string serviceName = null) { if (container == null) { throw new ArgumentNullException(nameof(container)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } SsoServiceInfo info = serviceName == null ? config.GetSingletonServiceInfo <SsoServiceInfo>() : config.GetRequiredServiceInfo <SsoServiceInfo>(serviceName); var oauthConfig = new OAuthConnectorOptions(config); var factory = new OAuthConnectorFactory(info, oauthConfig); return(container.Register(c => factory.Create(null)).As <IOptions <OAuthServiceOptions> >()); }
public void Configure_ServiceInfoOveridesConfig_ReturnsExpected() { var si = new SsoServiceInfo("myId", "myClientId", "myClientSecret", "https://foo.bar"); var config = new OAuthConnectorOptions(); var configurer = new OAuthConfigurer(); var result = configurer.Configure(si, config); Assert.NotNull(result); var opts = result.Value; Assert.NotNull(opts); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_AccessTokenUri, opts.AccessTokenUrl); Assert.Equal("myClientId", opts.ClientId); Assert.Equal("myClientSecret", opts.ClientSecret); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_JwtTokenKey, opts.JwtKeyUrl); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_CheckTokenUri, opts.TokenInfoUrl); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_AuthorizationUri, opts.UserAuthorizationUrl); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_UserInfoUri, opts.UserInfoUrl); Assert.True(opts.ValidateCertificates); Assert.NotNull(opts.Scope); Assert.Equal(0, opts.Scope.Count); }
public void Create_ReturnsOAuthOptions() { var si = new SsoServiceInfo("myId", "myClientId", "myClientSecret", "https://foo.bar"); var config = new OAuthConnectorOptions(); var factory = new OAuthConnectorFactory(si, config); var result = factory.Create(null); Assert.NotNull(result); var opts = result.Value; Assert.NotNull(opts); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_AccessTokenUri, opts.AccessTokenUrl); Assert.Equal("myClientId", opts.ClientId); Assert.Equal("myClientSecret", opts.ClientSecret); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_JwtTokenKey, opts.JwtKeyUrl); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_CheckTokenUri, opts.TokenInfoUrl); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_AuthorizationUri, opts.UserAuthorizationUrl); Assert.Equal("https://foo.bar" + OAuthConnectorDefaults.Default_UserInfoUri, opts.UserInfoUrl); Assert.NotNull(opts.Scope); Assert.Equal(0, opts.Scope.Count); }
public void Configure_WithServiceInfo_ReturnsExpected() { var opts = new CloudFoundryOAuthOptions(); var info = new SsoServiceInfo("foobar", "clientId", "secret", "http://domain"); CloudFoundryOAuthConfigurer.Configure(info, opts); var authURL = "http://domain"; Assert.Equal(CloudFoundryDefaults.AuthenticationScheme, opts.ClaimsIssuer); Assert.Equal("clientId", opts.ClientId); Assert.Equal("secret", opts.ClientSecret); Assert.Equal(new PathString("/signin-cloudfoundry"), opts.CallbackPath); Assert.Equal(authURL + CloudFoundryDefaults.AuthorizationUri, opts.AuthorizationEndpoint); Assert.Equal(authURL + CloudFoundryDefaults.AccessTokenUri, opts.TokenEndpoint); Assert.Equal(authURL + CloudFoundryDefaults.UserInfoUri, opts.UserInformationEndpoint); Assert.Equal(authURL + CloudFoundryDefaults.CheckTokenUri, opts.TokenInfoUrl); Assert.True(opts.ValidateCertificates); Assert.Equal(6, opts.ClaimActions.Count()); Assert.Equal(CookieAuthenticationDefaults.AuthenticationScheme, opts.SignInScheme); Assert.True(opts.SaveTokens); Assert.Null(opts.BackchannelHttpHandler); }
/// <summary> /// Configures and adds JWT bearer token middleware to the OWIN request pipeline /// </summary> /// <param name="appBuilder">Your OWIN AppBuilder</param> /// <param name="configuration">Your application configuration</param> /// <param name="logger">Include for diagnostic logging during app start</param> /// <returns>Your <see cref="IAppBuilder"/></returns> public static IAppBuilder UseCloudFoundryJwtBearerAuthentication(this IAppBuilder appBuilder, IConfiguration configuration, ILogger logger = null) { if (appBuilder == null) { throw new ArgumentNullException(nameof(appBuilder)); } if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } // get options with defaults var cloudFoundryOptions = new CloudFoundryJwtBearerAuthenticationOptions(); // get and apply config from application var securitySection = configuration.GetSection(CloudFoundryDefaults.SECURITY_CLIENT_SECTION_PREFIX); securitySection.Bind(cloudFoundryOptions); // get and apply service binding info SsoServiceInfo si = configuration.GetSingletonServiceInfo <SsoServiceInfo>(); CloudFoundryJwtOwinConfigurer.Configure(si, cloudFoundryOptions); // REVIEW: return without adding auth middleware if no service binding was found... !? // - presumably written this way to support local development, but seems like a bad idea // - added option to disable, but leaving behavior to default this way, for now, to avoid a breaking change if (si == null && cloudFoundryOptions.SkipAuthIfNoBoundSSOService) { logger?.LogWarning("SSO Service binding not detected, JWT Bearer middleware has not been added!"); logger?.LogInformation("To include JWT Bearer middleware when bindings aren't found, set security:oauth2:client:SkipAuthIfNoBoundSSOService=false"); return(appBuilder); } return(appBuilder.UseJwtBearerAuthentication(cloudFoundryOptions)); }
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, })); }