private static Lazy<OAuthBearerAuthenticationOptions> ConfigureEndpointValidation(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            return new Lazy<OAuthBearerAuthenticationOptions>(() =>
            {
                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;

            }, true);
        }
        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>;
                });
            });
        }
        public virtual IdentityServerBearerTokenAuthenticationOptions BuildIdentityServerBearerTokenAuthenticationOptions()
        {
            AppEnvironment activeAppEnvironment = _appEnvironmentProvider.GetActiveAppEnvironment();

            IdentityServerBearerTokenAuthenticationOptions authOptions = new IdentityServerBearerTokenAuthenticationOptions
            {
                ClientId                      = activeAppEnvironment.Security.ClientId,
                Authority                     = activeAppEnvironment.GetSsoUrl(),
                DelayLoadMetadata             = true,
                RequiredScopes                = activeAppEnvironment.Security.Scopes,
                ClientSecret                  = activeAppEnvironment.Security.ClientSecret,
                EnableValidationResultCache   = true,
                ValidationResultCacheDuration = TimeSpan.FromMinutes(15),
                // ValidationMode = ValidationMode.ValidationEndpoint,
                ValidationMode           = ValidationMode.Local,
                PreserveAccessToken      = true,
                SigningCertificate       = _certificateProvider.GetSingleSignOnCertificate(),
                BackchannelHttpHandler   = GetHttpClientHandler(nameof(IdentityServerBearerTokenAuthenticationOptions.BackchannelHttpHandler)),
                IntrospectionHttpHandler = GetHttpClientHandler(nameof(IdentityServerBearerTokenAuthenticationOptions.IntrospectionHttpHandler)),
                IssuerName = activeAppEnvironment.GetSsoIssuerName()
            };

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

            new InMemoryValidationResultCache(options);
        }
Beispiel #5
0
        /// <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);
            }

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

            return(app);
        }
 /// <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())
 {
 }
Beispiel #7
0
        public void Configuration(IAppBuilder app)
        {
            var config = System.Web.Http.GlobalConfiguration.Configuration;

            config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling =
                Newtonsoft.Json.NullValueHandling.Ignore;
            config.CacheOutputConfiguration().RegisterCacheOutputProvider(() => new CustomCacheProvider());
            config.CacheOutputConfiguration().RegisterDefaultCacheKeyGeneratorProvider(() => new CustomCacheKeyGenerator());
            ConfigureServices(app, config);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            System.Web.Http.GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.NullValueHandling =
                Newtonsoft.Json.NullValueHandling.Ignore;
            app.CreatePerOwinContext(MiniSessionManager.Create);
            app.CreatePerOwinContext <UserManager>(UserManager.Create);
            app.CreatePerOwinContext(() =>
            {
                var signInManager = new SignInManager <IdentityUser, string>(
                    HttpContext.Current.GetOwinContext().GetUserManager <UserManager>(),
                    HttpContext.Current.GetOwinContext().Authentication
                    );
                return(signInManager);
            });
            System.Web.Http.GlobalConfiguration.Configure(ThrottleConfig.Register);
            System.Web.Http.GlobalConfiguration.Configure(APIRegistryConfig.Register);
            int cookieValidationIntervalInSeconds = 1;

            try
            {
                cookieValidationIntervalInSeconds = int.Parse(ConfigurationManager.AppSettings["AuthenticationCookieValidationIntervalInSeconds"]);
            }
            catch (Exception e)
            {
                log4net.LogManager.GetLogger("CookieValidationInterval").Error("Could not parse Cookie Validation Interval Setting! Using default...", e);
            }
            // Retrieve Session Storage cache settings, to sync with authentication cookie
            var authenticationCookineExpirationTimeout = TimeSpan.FromMinutes(20);

            //var authenticationCookineSlidingExpiration = true;
            try
            {
                var cacheConfig        = CacheFactory.FromConfiguration <object>(CacheManager.Core.ConfigurationBuilder.LoadConfiguration("SessionStateStorage"));
                var sessionCacheHandle = cacheConfig.CacheHandles.FirstOrDefault();
                authenticationCookineExpirationTimeout = sessionCacheHandle.Configuration.ExpirationTimeout;
                //authenticationCookineSlidingExpiration = sessionCacheHandle.Configuration.ExpirationMode == ExpirationMode.Sliding;
            }
            catch (Exception e)
            {
                log4net.LogManager.GetLogger("SessionStateStorage").Error("Could not retrieve cache configuration for Session Storage!", e);
            }
            log4net.LogManager.GetLogger("AuthenticationCookie").Info($"Authentication Cookie Timeout: {authenticationCookineExpirationTimeout.Minutes} minute(s)");
            //log4net.LogManager.GetLogger("AuthenticationCookie").Info($"Authentication Cookie Sliding Expiration Enabled: {authenticationCookineSlidingExpiration}");
            app.UseCookieAuthentication(
                new CookieAuthenticationOptions
            {
                CookieName         = ConfigurationManager.AppSettings["AuthenticationCookieName"],
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                ExpireTimeSpan     = authenticationCookineExpirationTimeout,
                //SlidingExpiration = authenticationCookineSlidingExpiration,  // Sliding expiration is always what happens despite this setting

                LoginPath = new PathString("/SignInPage/Load"),

                ReturnUrlParameter = "returnUrl",

                Provider = new CookieAuthenticationProvider
                {
                    OnApplyRedirect = context =>
                    {
                        log4net.LogManager.GetLogger("CookieAuthenticationProvider").Error("REDIRECTING!!!");
                    },
                    OnValidateIdentity = ApplicationCookieIdentityValidator.OnValidateIdentity(validateInterval: TimeSpan.FromSeconds(cookieValidationIntervalInSeconds)),
                    OnException        = context => log4net.LogManager.GetLogger("IdentityLogger").DebugFormat("CookieAuthenticationProvider Error for req: {0}", context.Request.Path)
                },
            });
            app.UseBasicAuthentication(new BasicAuthenticationOptions("", (id, secret) =>
            {
                try
                {
                    if (!IdentityHelper.ValidateUser(id, secret))
                    {
                        return(Task.FromResult <IEnumerable <Claim> >(null));
                    }
                    var user = IdentityHelper.GetUserManager().FindByName(id);
                    if (user == null)
                    {
                        return(Task.FromResult <IEnumerable <Claim> >(new List <Claim>()));
                    }
                    var claims = user.User.Permissions.Select(p => new Claim(ClaimTypes.Permission, p.Name)).ToList();
                    claims.Add(new Claim(System.Security.Claims.ClaimTypes.Name, user.UserName));
                    if (!string.IsNullOrWhiteSpace(user.User.Email))
                    {
                        claims.Add(new Claim(System.Security.Claims.ClaimTypes.Email, user.User.Email));
                    }
                    var userRoles = user.User.Roles.Select(r => new Claim(System.Security.Claims.ClaimTypes.Role, r.Name));
                    claims.AddRange(userRoles);
                    return(Task.FromResult <IEnumerable <Claim> >(claims));
                }
                catch (Exception e)
                {
                    log4net.LogManager.GetLogger("BasicAuthentication.CredentialValidationFunction").Error("Error validating identity!", e);
                    return(Task.FromResult <IEnumerable <Claim> >(null));
                }
            }));
            if (!string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["idsrv:authority"]))
            {
                var options = new IdentityServerBearerTokenAuthenticationOptions
                {
                    Authority = ConfigurationManager.AppSettings["idsrv:authority"]
                };
                if (!string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["idsrv:scopes"]))
                {
                    options.RequiredScopes = ConfigurationManager.AppSettings["idsrv:scopes"].Split(' ');
                }
                if (!string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["idsrv:clientid"]) &&
                    !string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["idsrv:clientsecret"]))
                {
                    options.ClientId     = ConfigurationManager.AppSettings["idsrv:clientid"];
                    options.ClientSecret = ConfigurationManager.AppSettings["idsrv:clientsecret"];
                }
                app.UseIdentityServerBearerTokenAuthentication(options);
            }
            else
            {
                // Configure the application for OAuth based flow
                var PublicClientId = "self";
                var OAuthOptions   = new OAuthAuthorizationServerOptions
                {
                    TokenEndpointPath         = new PathString("/OAuth/Token"),
                    Provider                  = new zAppDev.DotNet.Framework.Identity.AppOAuthProvider(PublicClientId),
                    AuthorizeEndpointPath     = new PathString("/OAuth/Account/ExternalLogin"),
                    AccessTokenExpireTimeSpan = TimeSpan.FromHours(4),
                    AllowInsecureHttp         = true // Don't do this in production ONLY FOR DEVELOPING: ALLOW INSECURE HTTP!
                };
                // Enable the application to use bearer tokens to authenticate users
                app.UseOAuthBearerTokens(OAuthOptions);
            }
            Microsoft.AspNet.SignalR.GlobalHost.DependencyResolver.Register(typeof(Newtonsoft.Json.JsonSerializer), () =>
            {
                return(Newtonsoft.Json.JsonSerializer.Create(new Newtonsoft.Json.JsonSerializerSettings
                {
                    NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
                    ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore,
                    ContractResolver = new zAppDev.DotNet.Framework.Utilities.NHibernateContractResolver()
                }));
            });
            app.MapSignalR();
            zAppDev.DotNet.Framework.Identity.IdentityHelper.AllowMultipleSessionsPerUser = true;
            zAppDev.DotNet.Framework.Identity.IdentityHelper.AdminCanResetPassword        = false;
            DSS3_LogisticsPoolingForUrbanDistribution.DatabaseSeeder databaseSeeder = new DSS3_LogisticsPoolingForUrbanDistribution.DatabaseSeeder();
            databaseSeeder.UpdateAuthorizationTables();
            ConfigeAuditTrailManager();
            ServiceLocator.Current.GetInstance <zAppDev.DotNet.Framework.Workflow.ScheduleManager>();
            ServiceLocator.Current.GetInstance <zAppDev.DotNet.Framework.Workflow.WorkflowManager>()
            .Init(typeof(DSS3_LogisticsPoolingForUrbanDistribution.DAL.Repository).Assembly);
            DSS3_LogisticsPoolingForUrbanDistribution.Hubs.EventsHub.RaiseApplicationStart();
            zAppDev.DotNet.Framework.Mvc.FileHelper.ClearTempData();
        }
        internal static Lazy <OAuthBearerAuthenticationOptions> ConfigureLocalValidation(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            return(new Lazy <OAuthBearerAuthenticationOptions>(() =>
            {
                JwtFormat tokenFormat = null;

                // use static configuration
                if (!string.IsNullOrWhiteSpace(options.IssuerName) &&
                    options.SigningCertificate != null)
                {
                    // IdSrv3 hard-codes the value when issuing a token using the pattern below
                    var audience = options.IssuerName.EnsureTrailingSlash() + "resources";

                    // Use the configured values if present, otherwise fallback to the defaulted value
                    List <string> validAudiences;
                    if (options.ValidAudiences != null && options.ValidAudiences.Count() > 0)
                    {
                        validAudiences = new List <string>(options.ValidAudiences);
                    }
                    else
                    {
                        validAudiences = new List <string>()
                        {
                            audience
                        }
                    };

                    var valParams = new TokenValidationParameters
                    {
                        ValidIssuer = options.IssuerName,
                        ValidAudiences = validAudiences,
                        ValidateAudience = true,
                        IssuerSigningKey = new X509SecurityKey(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);

                    // Use the configured values if present, otherwise fallback to the discovery document's value
                    // (which is actually hard-coded to _issuer + "/resources")
                    List <string> validAudiences;
                    if (options.ValidAudiences != null && options.ValidAudiences.Count() > 0)
                    {
                        validAudiences = new List <string>(options.ValidAudiences);
                    }
                    else
                    {
                        validAudiences = new List <string>()
                        {
                            issuerProvider.Audience
                        }
                    };

                    var valParams = new TokenValidationParameters
                    {
                        ValidAudiences = validAudiences,
                        ValidateAudience = true,
                        NameClaimType = options.NameClaimType,
                        RoleClaimType = options.RoleClaimType
                    };

                    if (options.IssuerSigningKeyResolver != null)
                    {
                        valParams.IssuerSigningKeyResolver = options.IssuerSigningKeyResolver;
                    }
                    else
                    {
                        valParams.IssuerSigningKeyResolver = IssuerSigningKeyResolver;
                    }

                    tokenFormat = new JwtFormat(valParams, issuerProvider);
                }


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

                return bearerOptions;
            }, LazyThreadSafetyMode.PublicationOnly));
        }
        internal static Lazy <OAuthBearerAuthenticationOptions> ConfigureLocalValidation(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            return(new Lazy <OAuthBearerAuthenticationOptions>(() =>
            {
                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,
                        IssuerSigningKey = new X509SecurityKey(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
                    };

                    if (options.IssuerSigningKeyResolver != null)
                    {
                        valParams.IssuerSigningKeyResolver = options.IssuerSigningKeyResolver;
                    }
                    else
                    {
                        valParams.IssuerSigningKeyResolver = ResolveRsaKeys;
                    }

                    tokenFormat = new JwtFormat(valParams, issuerProvider);
                }


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

                return bearerOptions;
            }, LazyThreadSafetyMode.PublicationOnly));
        }
Beispiel #10
0
        public static IAppBuilder UseIdentityServerBearerTokenAuthentication(this IAppBuilder app, IdentityServerBearerTokenAuthenticationOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            if (options.ValidationMode == ValidationMode.Local)
            {
                app.UseLocalValidation(options);
            }
            else if (options.ValidationMode == ValidationMode.ValidationEndpoint)
            {
                app.UseValidationEndpoint(options);
            }

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

            return(app);
        }
Beispiel #11
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.Framework.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>);
                });
            });
        }
Beispiel #12
0
        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;
            }

//            _configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(discoveryEndpoint, new HttpClient(handler))
            _configurationManager = new ConfigurationManager <OpenIdConnectConfiguration>(discoveryEndpoint, new OpenIdConnectConfigurationRetriever(), new HttpClient(handler))
            {
                AutomaticRefreshInterval = options.AutomaticRefreshInterval
            };

            if (!options.DelayLoadMetadata)
            {
                RetrieveMetadata();
            }
        }
        internal static Lazy <OAuthBearerAuthenticationOptions> ConfigureLocalValidation(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            return(new Lazy <OAuthBearerAuthenticationOptions>(() =>
            {
                JwtFormat tokenFormat = null;

                // use static configuration
                if (!string.IsNullOrWhiteSpace(options.IssuerName) &&
                    options.SigningCertificate != null)
                {
                    string audience = null;
                    bool validateAudience = true;

                    // if API name is set, do a strict audience check for
                    //https://github.com/IdentityServer/IdentityServer4.AccessTokenValidation/blob/677bf6863a27c851270436faf9dfac437f46d90d/src/IdentityServerAuthenticationOptions.cs#L192
                    if (!string.IsNullOrWhiteSpace(options.ApiName) && !options.LegacyAudienceValidation)
                    {
                        audience = options.ApiName;
                    }
                    else if (options.LegacyAudienceValidation)
                    {
                        audience = options.IssuerName.EnsureTrailingSlash() + "resources";
                    }
                    else
                    {
                        // no audience validation, rely on scope checks only
                        validateAudience = false;
                    }

                    var valParams = new TokenValidationParameters
                    {
                        ValidIssuer = options.IssuerName,
                        ValidAudience = audience,
                        ValidateAudience = validateAudience,
                        IssuerSigningKey = new X509SecurityKey(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);


                    string audience = issuerProvider.Audience;
                    bool validateAudience = true;

                    // if API name is set, do a strict audience check for
                    //https://github.com/IdentityServer/IdentityServer4.AccessTokenValidation/blob/677bf6863a27c851270436faf9dfac437f46d90d/src/IdentityServerAuthenticationOptions.cs#L192
                    if (string.IsNullOrWhiteSpace(audience) && !options.LegacyAudienceValidation)
                    {
                        // no audience validation, rely on scope checks only
                        validateAudience = false;
                    }


                    var valParams = new TokenValidationParameters
                    {
                        ValidAudience = audience,
                        ValidateAudience = validateAudience,
                        NameClaimType = options.NameClaimType,
                        RoleClaimType = options.RoleClaimType
                    };

                    if (options.IssuerSigningKeyResolver != null)
                    {
                        valParams.IssuerSigningKeyResolver = options.IssuerSigningKeyResolver;
                    }
                    else
                    {
                        valParams.IssuerSigningKeyResolver = IssuerSigningKeyResolver;
                    }

                    tokenFormat = new JwtFormat(valParams, issuerProvider);
                }


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

                return bearerOptions;
            }, LazyThreadSafetyMode.PublicationOnly));
        }
    public void Configuration(IAppBuilder app)
    {
        AntiForgeryConfig.UniqueClaimTypeIdentifier = Thinktecture.IdentityServer.Core.Constants.ClaimTypes.Subject;
        JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary <string, string>();
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "Cookies"
        });
        var openIdConfig = new OpenIdConnectAuthenticationOptions
        {
            Authority    = "https://localhost:44301/identity",
            ClientId     = "baseballStats",
            Scope        = "openid profile roles baseballStatsApi",
            RedirectUri  = "https://localhost:44300/",
            ResponseType = "id_token token",
            SignInAsAuthenticationType = "Cookies",
            UseTokenLifetime           = false,
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                SecurityTokenValidated = async n =>
                {
                    var userInfoClient = new UserInfoClient(
                        new Uri(n.Options.Authority + "/connect/userinfo"),
                        n.ProtocolMessage.AccessToken);
                    var userInfo = await userInfoClient.GetAsync();

                    // create new identity and set name and role claim type
                    var nid = new ClaimsIdentity(
                        n.AuthenticationTicket.Identity.AuthenticationType,
                        Thinktecture.IdentityServer.Core.Constants.ClaimTypes.GivenName,
                        Thinktecture.IdentityServer.Core.Constants.ClaimTypes.Role);
                    userInfo.Claims.ToList().ForEach(c => nid.AddClaim(new Claim(c.Item1, c.Item2)));
                    // keep the id_token for logout
                    nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
                    // add access token for sample API
                    nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken));
                    // keep track of access token expiration
                    nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString()));
                    // add some other app specific claim
                    nid.AddClaim(new Claim("app_specific", "some data"));
                    n.AuthenticationTicket = new AuthenticationTicket(
                        nid,
                        n.AuthenticationTicket.Properties);
                    n.Request.Headers.SetValues("Authorization ", new string[] { "Bearer ", n.ProtocolMessage.AccessToken });
                }
            }
        };

        app.UseOpenIdConnectAuthentication(openIdConfig);
        app.UseResourceAuthorization(new AuthorizationManager());
        app.Map("/api", inner =>
        {
            var bearerTokenOptions = new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority      = "https://localhost:44301/identity",
                RequiredScopes = new[] { "baseballStatsApi" }
            };
            inner.UseIdentityServerBearerTokenAuthentication(bearerTokenOptions);
            var config = new HttpConfiguration();
            config.MapHttpAttributeRoutes();
            inner.UseWebApi(config);
        });
    }
        public void InvokingConstructor_WithNullIClock_ShouldError()
        {
            var options = new IdentityServerBearerTokenAuthenticationOptions();

            Assert.Throws <ArgumentNullException>(() => new InMemoryValidationResultCache(options, null, 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);
 }
        internal static Lazy<OAuthBearerAuthenticationOptions> ConfigureLocalValidation(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            return new Lazy<OAuthBearerAuthenticationOptions>(() =>
            {
                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(options.TokenProvider)
                };

                return bearerOptions;

            }, true);
        }
        private static Lazy <OAuthBearerAuthenticationOptions> ConfigureEndpointValidation(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            return(new Lazy <OAuthBearerAuthenticationOptions>(() =>
            {
                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;
            }, true));
        }
        /// <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 IApplicationBuilder UseIdentityServerBearerTokenAuthentication(this IApplicationBuilder 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.DelayLoadMetadata)
            {
                // evaluate the lazy members so that they can do their job

                if (middlewareOptions.LocalValidationOptions != null)
                {
                    var ignore = middlewareOptions.LocalValidationOptions.Value;
                }

                if (middlewareOptions.EndpointValidationOptions != null)
                {
                    var ignore = middlewareOptions.EndpointValidationOptions.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;
        }
        /// <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.DelayLoadMetadata)
            {
                // evaluate the lazy members so that they can do their job

                if (middlewareOptions.LocalValidationOptions != null)
                {
                    var ignore = middlewareOptions.LocalValidationOptions.Value;
                }

                if (middlewareOptions.EndpointValidationOptions != null)
                {
                    var ignore = middlewareOptions.EndpointValidationOptions.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>();
            }

            app.UseStageMarker(PipelineStage.Authenticate);

            return(app);
        }
        private static Lazy <OAuthBearerAuthenticationOptions> ConfigureEndpointValidation(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
        {
            return(new Lazy <OAuthBearerAuthenticationOptions>(() =>
            {
                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);
                }
                //I'm not sure Realm is the correct way to use this enforcement, but it's available for now. If needing realm for anything else
                //expand options with Issuer Enforcement.
                bearerOptions.Realm = options.AllowOnlyTokenFromIssuer;;
                return bearerOptions;
            }, true));
        }