public ValidationEndpointTokenProvider(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.Create("ValidationEndpointTokenProvider");

            var baseAddress = options.Authority.EnsureTrailingSlash();
            baseAddress += "connect/accesstokenvalidation";
            _tokenValidationEndpoint = baseAddress;

            var handler = options.BackchannelHttpHandler ?? new WebRequestHandler();

            if (options.BackchannelCertificateValidator != null)
            {
                // Set the cert validate callback
                var webRequestHandler = handler as WebRequestHandler;
                if (webRequestHandler == null)
                {
                    throw new InvalidOperationException("Invalid certificate validator");
                }

                webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate;
            }

            _client = new HttpClient(handler);
            _options = options;
        }
        public ValidationEndpointTokenProvider(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.Create(this.GetType().FullName);

            if (string.IsNullOrWhiteSpace(options.Authority))
            {
                throw new Exception("Authority must be set to use validation endpoint.");
            }

            var baseAddress = options.Authority.EnsureTrailingSlash();
            baseAddress += "connect/accesstokenvalidation";
            _tokenValidationEndpoint = baseAddress;

            var handler = options.BackchannelHttpHandler ?? new WebRequestHandler();

            if (options.BackchannelCertificateValidator != null)
            {
                // Set the cert validate callback
                var webRequestHandler = handler as WebRequestHandler;
                if (webRequestHandler == null)
                {
					throw new InvalidOperationException("The back channel handler must derive from WebRequestHandler in order to use a certificate validator");
                }

                webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate;
            }

            _client = new HttpClient(handler);
            _options = options;
        }
        private static OAuthBearerAuthenticationOptions ConfigureEndpointValidation(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            if (options.EnableValidationResultCache)
            {
                if (options.ValidationResultCache == null)
                {
                    options.ValidationResultCache = new InMemoryValidationResultCache(options);
                }
            }

            var bearerOptions = new OAuthBearerAuthenticationOptions
            {
                AuthenticationMode = options.AuthenticationMode,
                AuthenticationType = options.AuthenticationType,
                AccessTokenProvider = new ValidationEndpointTokenProvider(options, loggerFactory),
                Provider = new ContextTokenProvider(),
            };

            if (options.TokenProvider != null)
            {
                bearerOptions.Provider = options.TokenProvider;
            }

            return bearerOptions;
        }
        public static IAppBuilder Create(IdentityServerBearerTokenAuthenticationOptions options)
        {
            IAppBuilder app = new AppBuilder();
            app.SetLoggerFactory(new DiagnosticsLoggerFactory());

            app.UseIdentityServerBearerTokenAuthentication(options);
            
            app.Use((context, next) =>
            {
                var user = context.Authentication.User;

                if (user == null ||
                    user.Identity == null ||
                    !user.Identity.IsAuthenticated)
                {
                    context.Response.StatusCode = 401;
                }
                else
                {
                    context.Response.StatusCode = 200;
                }

                return Task.FromResult(0);
            });


            return app;
        }
        /// <summary>
        /// Add identity server token authentication to the pipeline.
        /// </summary>
        /// <param name="app">The application.</param>
        /// <param name="options">The options.</param>
        /// <returns></returns>
        public static IAppBuilder UseIdentityServerBearerTokenAuthentication(this IAppBuilder app, IdentityServerBearerTokenAuthenticationOptions options)
        {
            if (app == null) throw new ArgumentNullException("app");
            if (options == null) throw new ArgumentNullException("options");
            if (string.IsNullOrEmpty(options.Authority)) throw new ArgumentException("Authority must be set", "authority");

            var loggerFactory = app.GetLoggerFactory();
            var middlewareOptions = new IdentityServerOAuthBearerAuthenticationOptions();

            if (options.ValidationMode == ValidationMode.Both ||
                options.ValidationMode == ValidationMode.Local)
            {
                middlewareOptions.LocalValidationOptions = ConfigureLocalValidation(options, loggerFactory);
            }
            
            if (options.ValidationMode == ValidationMode.Both ||
                options.ValidationMode == ValidationMode.ValidationEndpoint)
            {
                middlewareOptions.EndpointValidationOptions = ConfigureEndpointValidation(options, loggerFactory);
            }

            if (options.TokenProvider != null)
            {
                middlewareOptions.TokenProvider = options.TokenProvider;
            }

            app.Use<IdentityServerBearerTokenValidationMiddleware>(middlewareOptions);

            if (options.RequiredScopes.Any())
            {
                app.Use<ScopeRequirementMiddleware>(options.RequiredScopes);
            }

            return app;
        }
Example #6
0
        public static void UseIdentityServerBearerTokenAuthentication(this IApplicationBuilder app, IdentityServerBearerTokenAuthenticationOptions options)
        {
            app.UseOwin(addToPipeline =>
            {
                addToPipeline(next =>
                {
                    var builder = new Microsoft.Owin.Builder.AppBuilder();
                    var loggerFactory = app.ApplicationServices.GetService<Microsoft.Extensions.Logging.ILoggerFactory>();
                    var lifetime = app.ApplicationServices.GetService<IApplicationLifetime>();
                    var owinLoggerFactory = new OwinLoggerFactory(loggerFactory);
                    var provider = app.ApplicationServices.GetService(typeof(Microsoft.AspNet.DataProtection.IDataProtectionProvider)) as Microsoft.AspNet.DataProtection.IDataProtectionProvider;

                    var properties = new AppProperties(builder.Properties);
                    properties.OnAppDisposing = lifetime.ApplicationStopping;
                    properties.DefaultApp = next;

                    builder.SetLoggerFactory(owinLoggerFactory);
                    builder.Properties["security.DataProtectionProvider"] = new DataProtectionProviderDelegate(purposes =>
                    {
                        var dataProtection = provider.CreateProtector(string.Join(",", purposes));
                        return new DataProtectionTuple(dataProtection.Protect, dataProtection.Unprotect);
                    });

                    builder.UseIdentityServerBearerTokenAuthentication(options);
                    return builder.Build(typeof(Func<IDictionary<string, object>, Task>)) as Func<IDictionary<string, object>, Task>;
                });
            });
        }
        private static OAuthBearerAuthenticationOptions ConfigureEndpointValidation(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            if (options.EnableValidationResultCache)
            {
                if (options.ValidationResultCache == null)
                {
                    options.ValidationResultCache = new InMemoryValidationResultCache(options);
                }
            }

            var bearerOptions = new OAuthBearerAuthenticationOptions
            {
                AuthenticationMode = options.AuthenticationMode,
                AuthenticationType = options.AuthenticationType,
                Provider = new ContextTokenProvider(options.TokenProvider),
            };

            if (!string.IsNullOrEmpty(options.ClientId) || options.IntrospectionHttpHandler != null)
            {
                bearerOptions.AccessTokenProvider = new IntrospectionEndpointTokenProvider(options, loggerFactory);
            }
            else
            {
                bearerOptions.AccessTokenProvider = new ValidationEndpointTokenProvider(options, loggerFactory);
            }

            return bearerOptions;
        }
        public static HttpClient CreateHttpClient(IdentityServerBearerTokenAuthenticationOptions options)
        {
            var app = PipelineFactory.Create(options);
            var handler = new OwinHttpMessageHandler(app.Build());
            var client = new HttpClient(handler);

            return client;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="InMemoryValidationResultCache"/> class.
        /// </summary>
        /// <param name="options">The options.</param>
        /// <param name="clock">The clock.</param>
        /// <param name="cache">The cache.</param>
        /// <exception cref="System.ArgumentNullException">
        /// clock
        /// or
        /// options
        /// or
        /// cache
        /// </exception>
        public InMemoryValidationResultCache(IdentityServerBearerTokenAuthenticationOptions options, IClock clock, ICache cache)
        {
            if (clock == null) { throw new ArgumentNullException("clock"); }
            if (options == null) { throw new ArgumentNullException("options"); }
            if (cache == null) { throw new ArgumentNullException("cache"); }

            _options = options;
            _cache = cache;
            _clock = clock;
        }
        /// <summary>
        /// Add identity server token authentication to the pipeline.
        /// </summary>
        /// <param name="app">The application.</param>
        /// <param name="options">The options.</param>
        /// <returns></returns>
        public static IAppBuilder UseIdentityServerBearerTokenAuthentication(this IAppBuilder app, IdentityServerBearerTokenAuthenticationOptions options)
        {
            if (app == null) throw new ArgumentNullException("app");
            if (options == null) throw new ArgumentNullException("options");

            var loggerFactory = app.GetLoggerFactory();
            var middlewareOptions = new IdentityServerOAuthBearerAuthenticationOptions();

            switch (options.ValidationMode)
            {
                case ValidationMode.Local:
                    middlewareOptions.LocalValidationOptions = ConfigureLocalValidation(options, loggerFactory);
                    break;
                case ValidationMode.ValidationEndpoint:
                    middlewareOptions.EndpointValidationOptions = ConfigureEndpointValidation(options, loggerFactory);
                    break;
                case ValidationMode.Both:
                    middlewareOptions.LocalValidationOptions = ConfigureLocalValidation(options, loggerFactory);
                    middlewareOptions.EndpointValidationOptions = ConfigureEndpointValidation(options, loggerFactory);
                    break;
                default:
                    throw new Exception("ValidationMode has invalid value");
            }

            if (options.TokenProvider != null)
            {
                middlewareOptions.TokenProvider = options.TokenProvider;
            }

            app.Use<IdentityServerBearerTokenValidationMiddleware>(app, middlewareOptions, loggerFactory);

            if (options.RequiredScopes.Any())
            {
                var scopeOptions = new ScopeRequirementOptions
                {
                    AuthenticationType = options.AuthenticationType,
                    RequiredScopes = options.RequiredScopes
                };

                app.Use<ScopeRequirementMiddleware>(scopeOptions);
            }

            if (options.PreserveAccessToken)
            {
                app.Use<PreserveAccessTokenMiddleware>();
            }

            return app;
        }
		void Arrange(Action specifyExpectedCacheExpiry) {
			_cache = Mock.Of<ICache>();
			_clock = Mock.Of<IClock>(c => c.UtcNow == DateTimeOffset.Now);
			_options = new IdentityServerBearerTokenAuthenticationOptions
				{
					ValidationResultCacheDuration = TimeSpan.FromMinutes(CacheEvictsTokensAfterMinutes)
				};
			ExpiryClaimSaysTokenExpiresAt = _clock.UtcNow.AddMinutes(ExpiryClaimSaysTokenExpiresInMinutes);
			CacheExpiryEvictsTokenAt = _clock.UtcNow.Add(_options.ValidationResultCacheDuration);
			
			// setup claims to include expiry claim
			Claims = new[] {new Claim("bar","baz"), new Claim(ClaimTypes.Expiration,ExpiryClaimSaysTokenExpiresAt.ToEpochTime().ToString()) };

			specifyExpectedCacheExpiry();

			DebugToConsole(DateTime.Now, ExpiryClaimSaysTokenExpiresAt,  _options, CacheExpiryEvictsTokenAt, ExpectedCacheExpiry);
			Sut = new InMemoryValidationResultCache(_options, _clock, _cache);
		}
        public IntrospectionEndpointTokenProvider(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.Create(this.GetType().FullName);

            if (string.IsNullOrWhiteSpace(options.Authority))
            {
                throw new Exception("Authority must be set to use validation endpoint.");
            }

            var baseAddress = options.Authority.EnsureTrailingSlash();
            baseAddress += "connect/introspect";
            var introspectionEndpoint = baseAddress;

            var handler = options.IntrospectionHttpHandler ?? new WebRequestHandler();

            if (options.BackchannelCertificateValidator != null)
            {
                // Set the cert validate callback
                var webRequestHandler = handler as WebRequestHandler;
                if (webRequestHandler == null)
                {
                    throw new InvalidOperationException("Invalid certificate validator");
                }

                webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate;
            }

            if (!string.IsNullOrEmpty(options.ClientId))
            {
                _client = new IntrospectionClient(
                    introspectionEndpoint, 
                    options.ClientId, 
                    options.ClientSecret ?? "", 
                    handler);
            }
            else
            {
                _client = new IntrospectionClient(
                    introspectionEndpoint,
                    innerHttpMessageHandler: handler);
            }

            _options = options;
        }
        public DiscoveryDocumentIssuerSecurityTokenProvider(string discoveryEndpoint, IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.Create(this.GetType().FullName);

            var handler = options.BackchannelHttpHandler ?? new WebRequestHandler();

            if (options.BackchannelCertificateValidator != null)
            {
                // Set the cert validate callback
                var webRequestHandler = handler as WebRequestHandler;
                if (webRequestHandler == null)
                {
                    throw new InvalidOperationException("Invalid certificate validator");
                }
                webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate;
            }

            _configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(discoveryEndpoint, new HttpClient(handler));
            RetrieveMetadata();
        }
Example #14
0
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory, IApplicationLifetime lifetime, IBusManager busManager)
        {
            loggerfactory.AddSerilog();

            Log.Information("Configuring the Application");

            app.UseCors(_aureliaAppPolicyName);

            var options = new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = _appSettings.IdentityServerAuthority,
                RequiredScopes = new[] { _appSettings.IdentityServerSettings.ClientId },
                NameClaimType = "preferred_username"
            };

            app.UseAppBuilder(
                builder =>
                {
                    builder.SetLoggerFactory(LoggerFactory.Default);
                    builder.UseIdentityServerBearerTokenAuthentication(options);
                },
                _appSettings.ServiceSettings.ServiceName);

            app.UseMiddleware<ContextMiddleware>();
            app.UseMvc();

            Log.Information("Getting ready to start the bus manager");

            busManager.Start(
                new[] { typeof(StartApplication).Assembly, Assembly.GetExecutingAssembly() },
                config => config.RegisterComponents(r => r.ConfigureComponent<OutgoingAppContextMutator>(DependencyLifecycle.InstancePerUnitOfWork)));

            lifetime.ApplicationStopping.Register(busManager.Stop);

            _loggingLevelSwitch.MinimumLevel = LogEventLevel.Information;
        }
        public DiscoveryDocumentIssuerSecurityTokenProvider(string discoveryEndpoint, IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.Create(this.GetType().FullName);

            var handler = options.BackchannelHttpHandler ?? new WebRequestHandler();

            if (options.BackchannelCertificateValidator != null)
            {
                // Set the cert validate callback
                var webRequestHandler = handler as WebRequestHandler;
                if (webRequestHandler == null)
                {
                    throw new InvalidOperationException("The back channel handler must derive from WebRequestHandler in order to use a certificate validator");
                }
                webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate;
            }

            var adapteeConfigurationManager = new ConfigurationManager <OpenIdConnectConfiguration>(discoveryEndpoint, new OpenIdConnectConfigurationRetriever(), new HttpDocumentRetriever(new HttpClient(handler))
            {
                RequireHttps = options.RequireHttps
            })
            {
                AutomaticRefreshInterval = options.AutomaticRefreshInterval
            };

            _automaticRefreshInterval = adapteeConfigurationManager.AutomaticRefreshInterval;
            _configurationManager     = new ConfigurationManagerAdapter(adapteeConfigurationManager);

            if (!options.DelayLoadMetadata)
            {
                RetrieveMetadata();
            }
        }
        internal static OAuthBearerAuthenticationOptions ConfigureLocalValidation(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            var discoveryEndpoint = options.Authority.EnsureTrailingSlash();
            discoveryEndpoint += ".well-known/openid-configuration";

            var issuerProvider = new DiscoveryDocumentIssuerSecurityTokenProvider(
                discoveryEndpoint,
                options,
                loggerFactory);

            var valParams = new TokenValidationParameters
            {
                ValidAudience = issuerProvider.Audience,
                NameClaimType = options.NameClaimType,
                RoleClaimType = options.RoleClaimType
            };

            var tokenFormat = new JwtFormat(valParams, issuerProvider);

            var bearerOptions = new OAuthBearerAuthenticationOptions
            {
                AccessTokenFormat = tokenFormat,
                AuthenticationMode = options.AuthenticationMode,
                AuthenticationType = options.AuthenticationType,
                Provider = options.TokenProvider ?? new ContextTokenProvider(),
            };

            return bearerOptions;
        }
        public void InvokingConstructor_WithOptionsOnly_ShouldNotError() 
		{
			var options = new IdentityServerBearerTokenAuthenticationOptions();			

			new InMemoryValidationResultCache(options);
		}
        internal static OAuthBearerAuthenticationOptions ConfigureLocalValidation(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            JwtFormat tokenFormat = null;

            // use static configuration
            if (!string.IsNullOrWhiteSpace(options.IssuerName) &&
                options.SigningCertificate != null)
            {
                var audience = options.IssuerName.EnsureTrailingSlash();
                audience += "resources";

                var valParams = new TokenValidationParameters
                { 
                    ValidIssuer = options.IssuerName,
                    ValidAudience = audience,
                    IssuerSigningToken = new X509SecurityToken(options.SigningCertificate),

                    NameClaimType = options.NameClaimType,
                    RoleClaimType = options.RoleClaimType,
                };

                tokenFormat = new JwtFormat(valParams);
            }
            else
            {
                // use discovery endpoint
                if (string.IsNullOrWhiteSpace(options.Authority))
                {
                    throw new Exception("Either set IssuerName and SigningCertificate - or Authority");
                }

                var discoveryEndpoint = options.Authority.EnsureTrailingSlash();
                discoveryEndpoint += ".well-known/openid-configuration";

                var issuerProvider = new DiscoveryDocumentIssuerSecurityTokenProvider(
                    discoveryEndpoint,
                    options,
                    loggerFactory);

                var valParams = new TokenValidationParameters
                {
                    ValidAudience = issuerProvider.Audience,
                    NameClaimType = options.NameClaimType,
                    RoleClaimType = options.RoleClaimType
                };

                tokenFormat = new JwtFormat(valParams, issuerProvider);
            }
            

            var bearerOptions = new OAuthBearerAuthenticationOptions
            {
                AccessTokenFormat = tokenFormat,
                AuthenticationMode = options.AuthenticationMode,
                AuthenticationType = options.AuthenticationType,
                Provider = new ContextTokenProvider()
            };

            if (options.TokenProvider != null)
            {
                bearerOptions.Provider = options.TokenProvider;
            }

            return bearerOptions;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="InMemoryValidationResultCache"/> class.
 /// </summary>
 /// <param name="options">The options.</param>
 public InMemoryValidationResultCache(IdentityServerBearerTokenAuthenticationOptions options)
     : this(options, new Clock(), new Cache())
 { }
        public void InvokingConstructor_WithNullIClock_ShouldError() 
		{
			var options = new IdentityServerBearerTokenAuthenticationOptions();			

			Assert.Throws<ArgumentNullException>(() => new InMemoryValidationResultCache(options, null, new Cache()));
		}
 /// <summary>
 /// Initializes a new instance of the <see cref="InMemoryValidationResultCache"/> class.
 /// </summary>
 /// <param name="options">The options.</param>
 public InMemoryValidationResultCache(IdentityServerBearerTokenAuthenticationOptions options)
     : this(options, new Clock(), new Cache())
 {
 }
		static void DebugToConsole(DateTime now, DateTimeOffset expiryClaimSaysTokenExpiresAt, IdentityServerBearerTokenAuthenticationOptions options, DateTimeOffset cacheExpiryEvictsTokenAt, DateTimeOffset expectedCacheExpiry) {
			Console.WriteLine("now: {0}", now);
			Console.WriteLine("expiry claim says token expires at: {0}", expiryClaimSaysTokenExpiresAt);
			Console.WriteLine("claims cache duration: {0}", options.ValidationResultCacheDuration);
			Console.WriteLine("cache expiry evicts token at: {0}", cacheExpiryEvictsTokenAt);
			Console.WriteLine("expected cache expiry: {0}", expectedCacheExpiry);
		}
        public DiscoveryDocumentIssuerSecurityTokenProvider(string discoveryEndpoint, IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.Create("IdentityServer3.AccessTokenValidation.DiscoveryDocumentIssuerSecurityTokenProvider");

            var handler = options.BackchannelHttpHandler ?? new WebRequestHandler();

            if (options.BackchannelCertificateValidator != null)
            {
                // Set the cert validate callback
                var webRequestHandler = handler as WebRequestHandler;
                if (webRequestHandler == null)
                {
                    throw new InvalidOperationException("Invalid certificate validator");
                }
                webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate;
            }

            _configurationManager = new ConfigurationManager <OpenIdConnectConfiguration>(discoveryEndpoint, new HttpClient(handler));
            RetrieveMetadata();
        }