public async Task Valid_Reference_Token_with_required_Scope()
        {
            var store = new InMemoryTokenHandleStore();
            var validator = Factory.CreateTokenValidator(store);

            var token = TokenFactory.CreateAccessToken("roclient", "valid", 600, "read", "write");
            var handle = "123";

            await store.StoreAsync(handle, token);

            var result = await validator.ValidateAccessTokenAsync("123", "read");

            result.IsError.Should().BeFalse();
        }
        public async Task Valid_Reference_Token_with_missing_Scope()
        {
            var store = new InMemoryTokenHandleStore();
            var validator = Factory.CreateTokenValidator(store);

            var token = TokenFactory.CreateAccessToken("roclient", "valid", 600, "read", "write");
            var handle = "123";

            await store.StoreAsync(handle, token);

            var result = await validator.ValidateAccessTokenAsync("123", "missing");

            result.IsError.Should().BeTrue();
            result.Error.Should().Be(Constants.ProtectedResourceErrors.InsufficientScope);
        }
        public async Task Valid_Reference_Token()
        {
            var store = new InMemoryTokenHandleStore();
            var validator = Factory.CreateTokenValidator(store);

            var token = TokenFactory.CreateAccessToken("roclient", "valid", 600, "read", "write");
            var handle = "123";

            await store.StoreAsync(handle, token);

            var result = await validator.ValidateAccessTokenAsync("123");

            result.IsError.Should().BeFalse();
            result.Claims.Count().Should().Be(8);
            result.Claims.First(c => c.Type == Constants.ClaimTypes.ClientId).Value.Should().Be("roclient");
        }
        public static IdentityServerServiceFactory Create(
                    string issuerUri, string siteName, string publicHostAddress = "")
        {
            var settings = new LocalTestCoreSettings(issuerUri, siteName, publicHostAddress);
            
            var codeStore = new InMemoryAuthorizationCodeStore();
            var tokenStore = new InMemoryTokenHandleStore();
            var consent = new InMemoryConsentService();
            var scopes = new InMemoryScopeService(LocalTestScopes.Get());
            var clients = new InMemoryClientService(LocalTestClients.Get());
            var logger = new TraceLogger();

            var users = new InMemoryUser[]
            {
                new InMemoryUser{Subject = "alice", Username = "******", Password = "******", 
                    Claims = new Claim[]
                    {
                        new Claim(Constants.ClaimTypes.GivenName, "Alice"),
                        new Claim(Constants.ClaimTypes.FamilyName, "Smith"),
                        new Claim(Constants.ClaimTypes.Email, "*****@*****.**"),
                    }
                },
                new InMemoryUser{Subject = "bob", Username = "******", Password = "******", 
                    Claims = new Claim[]
                    {
                        new Claim(Constants.ClaimTypes.GivenName, "Bob"),
                        new Claim(Constants.ClaimTypes.FamilyName, "Smith"),
                        new Claim(Constants.ClaimTypes.Email, "*****@*****.**"),
                    }
                },
            };
            var userSvc = new InMemoryUserService(users);

            var fact = new IdentityServerServiceFactory
            {
                Logger = () => logger,
                UserService = () => userSvc,
                AuthorizationCodeStore = () => codeStore,
                TokenHandleStore = () => tokenStore,
                CoreSettings = () => settings,
                ConsentService = () => consent,
                ScopeService = () => scopes,
                ClientService = () => clients
            };

            return fact;
        }
        public async Task Unknown_Reference_Token()
        {
            var store = new InMemoryTokenHandleStore();
            var validator = Factory.CreateTokenValidator(store);

            var result = await validator.ValidateAccessTokenAsync("unknown");

            result.IsError.Should().BeTrue();
            result.Error.Should().Be(Constants.ProtectedResourceErrors.InvalidToken);
        }
        public async Task Valid_AccessToken_but_Client_not_active()
        {
            var store = new InMemoryTokenHandleStore();
            var validator = Factory.CreateTokenValidator(store);

            var token = TokenFactory.CreateAccessToken("unknown", "valid", 600, "read", "write");
            var handle = "123";

            await store.StoreAsync(handle, token);

            var result = await validator.ValidateAccessTokenAsync("123");

            result.IsError.Should().BeTrue();
        }
        public async Task Valid_AccessToken_but_User_not_active()
        {
            var mock = new Mock<IUserService>();
            mock.Setup(u => u.IsActiveAsync(It.IsAny<ClaimsPrincipal>())).Returns(Task.FromResult(false));                        

            var store = new InMemoryTokenHandleStore();
            var validator = Factory.CreateTokenValidator(tokenStore: store, users: mock.Object);

            var token = TokenFactory.CreateAccessToken("roclient", "invalid", 600, "read", "write");
            var handle = "123";

            await store.StoreAsync(handle, token);

            var result = await validator.ValidateAccessTokenAsync("123");

            result.IsError.Should().BeTrue();
        }
        public async Task Expired_Reference_Token()
        {
            var store = new InMemoryTokenHandleStore();
            var validator = Factory.CreateTokenValidator(store);

            var token = TokenFactory.CreateAccessToken("roclient", "valid", 2, "read", "write");
            var handle = "123";

            await store.StoreAsync(handle, token);
            await Task.Delay(2000);

            var result = await validator.ValidateAccessTokenAsync("123");

            result.IsError.Should().BeTrue();
            result.Error.Should().Be(Constants.ProtectedResourceErrors.ExpiredToken);
        }
        public static IContainer Configure(IdentityServerOptions options)
        {
            if (options == null) throw new ArgumentNullException("options");
            if (options.Factory == null) throw new InvalidOperationException("null factory");

            IdentityServerServiceFactory fact = options.Factory;
            fact.Validate();

            var builder = new ContainerBuilder();

            builder.RegisterInstance(options).AsSelf();

            // mandatory from factory
            builder.Register(fact.UserService, "inner");
            builder.RegisterDecorator<IUserService>((s, inner) =>
            {
                var filter = s.Resolve<IExternalClaimsFilter>();
                return new ExternalClaimsFilterUserService(filter, inner);
            }, "inner");

            builder.Register(fact.ScopeStore);
            builder.Register(fact.ClientStore);
            
            // optional from factory
            if (fact.AuthorizationCodeStore != null)
            {
                builder.Register(fact.AuthorizationCodeStore, "inner");
            }
            else
            {
                var inmemCodeStore = new InMemoryAuthorizationCodeStore();
                builder.RegisterInstance(inmemCodeStore).Named<IAuthorizationCodeStore>("inner");
            }
            builder.RegisterDecorator<IAuthorizationCodeStore>((s, inner) =>
            {
                return new KeyHashingAuthorizationCodeStore(inner);
            }, "inner");

            if (fact.TokenHandleStore != null)
            {
                builder.Register(fact.TokenHandleStore, "inner");
            }
            else
            {
                var inmemTokenHandleStore = new InMemoryTokenHandleStore();
                builder.RegisterInstance(inmemTokenHandleStore).Named<ITokenHandleStore>("inner");
            }
            builder.RegisterDecorator<ITokenHandleStore>((s, inner) =>
            {
                return new KeyHashingTokenHandleStore(inner);
            }, "inner");

            if (fact.RefreshTokenStore != null)
            {
                builder.Register(fact.RefreshTokenStore, "inner");
            }
            else
            {
                var inmemRefreshTokenStore = new InMemoryRefreshTokenStore();
                builder.RegisterInstance(inmemRefreshTokenStore).Named<IRefreshTokenStore>("inner");
            }
            builder.RegisterDecorator<IRefreshTokenStore>((s, inner) =>
            {
                return new KeyHashingRefreshTokenStore(inner);
            }, "inner");

            if (fact.ConsentStore != null)
            {
                builder.Register(fact.ConsentStore);
            }
            else
            {
                var inmemConsentStore = new InMemoryConsentStore();
                builder.RegisterInstance(inmemConsentStore).As<IConsentStore>();
            }

            if (fact.ClaimsProvider != null)
            {
                builder.Register(fact.ClaimsProvider);
            }
            else
            {
                builder.RegisterType<DefaultClaimsProvider>().As<IClaimsProvider>();
            }

            if (fact.TokenService != null)
            {
                builder.Register(fact.TokenService);
            }
            else
            {
                builder.RegisterType<DefaultTokenService>().As<ITokenService>();
            }

            if (fact.RefreshTokenService != null)
            {
                builder.Register(fact.RefreshTokenService);
            }
            else
            {
                builder.RegisterType<DefaultRefreshTokenService>().As<IRefreshTokenService>();
            }

            if (fact.TokenSigningService != null)
            {
                builder.Register(fact.TokenSigningService);
            }
            else
            {
                builder.RegisterType<DefaultTokenSigningService>().As<ITokenSigningService>();
            }

            if (fact.CustomRequestValidator != null)
            {
                builder.Register(fact.CustomRequestValidator);
            }
            else
            {
                builder.RegisterType<DefaultCustomRequestValidator>().As<ICustomRequestValidator>();
            }

            if (fact.CustomGrantValidator != null)
            {
                builder.Register(fact.CustomGrantValidator);
            }
            else
            {
                builder.RegisterType<DefaultCustomGrantValidator>().As<ICustomGrantValidator>();
            }

            if (fact.ExternalClaimsFilter != null)
            {
                builder.Register(fact.ExternalClaimsFilter);
            }
            else
            {
                builder.RegisterType<NopClaimsFilter>().As<IExternalClaimsFilter>();
            }

            if (fact.CustomTokenValidator != null)
            {
                builder.Register(fact.CustomTokenValidator);
            }
            else
            {
                builder.RegisterType<DefaultCustomTokenValidator>().As<ICustomTokenValidator>();
            }

            if (fact.ConsentService != null)
            {
                builder.Register(fact.ConsentService);
            }
            else
            {
                builder.RegisterType<DefaultConsentService>().As<IConsentService>();
            }

            if (fact.EventService != null)
            {
                builder.Register(fact.EventService);
            }
            else
            {
                builder.RegisterType<DefaultEventService>().As<IEventService>();
            }

            if (fact.RedirectUriValidator != null)
            {
                builder.Register(fact.RedirectUriValidator);
            }
            else
            {
                builder.RegisterType<DefaultRedirectUriValidator>().As<IRedirectUriValidator>();
            }

            // this is more of an internal interface, but maybe we want to open it up as pluggable?
            // this is used by the DefaultClientPermissionsService below, or it could be used
            // by a custom IClientPermissionsService
            builder.Register(ctx =>
            {
                var consent = ctx.Resolve<IConsentStore>();
                var refresh = ctx.Resolve<IRefreshTokenStore>();
                var code = ctx.Resolve<IAuthorizationCodeStore>();
                var access = ctx.Resolve<ITokenHandleStore>();
                return new AggregatePermissionsStore(
                    consent,
                    new TokenMetadataPermissionsStoreAdapter(refresh.GetAllAsync, refresh.RevokeAsync),
                    new TokenMetadataPermissionsStoreAdapter(code.GetAllAsync, code.RevokeAsync),
                    new TokenMetadataPermissionsStoreAdapter(access.GetAllAsync, access.RevokeAsync)
                );
            }).As<IPermissionsStore>();

            if (fact.ClientPermissionsService != null)
            {
                builder.Register(fact.ClientPermissionsService);
            }
            else
            {
                builder.RegisterType<DefaultClientPermissionsService>().As<IClientPermissionsService>();
            }

            if (fact.ViewService != null)
            {
                builder.Register(fact.ViewService);
            }
            else
            {
                builder.RegisterType<DefaultViewService>().As<IViewService>();
            }

            // hosting services
            builder.RegisterType<OwinEnvironmentService>();

            // validators
            builder.RegisterType<TokenRequestValidator>();
            builder.RegisterType<AuthorizeRequestValidator>();
            builder.RegisterType<ClientValidator>();
            builder.RegisterType<TokenValidator>();
            builder.RegisterType<EndSessionRequestValidator>();
            builder.RegisterType<BearerTokenUsageValidator>();
            builder.RegisterType<ScopeValidator>();

            // processors
            builder.RegisterType<TokenResponseGenerator>();
            builder.RegisterType<AuthorizeResponseGenerator>();
            builder.RegisterType<AuthorizeInteractionResponseGenerator>();
            builder.RegisterType<UserInfoResponseGenerator>();
            builder.RegisterType<EndSessionResponseGenerator>();

            // for authentication
            var authenticationOptions = options.AuthenticationOptions ?? new AuthenticationOptions();
            builder.RegisterInstance(authenticationOptions).AsSelf();

            // load core controller
            builder.RegisterApiControllers(typeof(AuthorizeEndpointController).Assembly);

            // add any additional dependencies from hosting application
            foreach(var registration in fact.Registrations)
            {
                builder.Register(registration);
            }

            return builder.Build();
        }
        public static IContainer Configure(IdentityServerOptions options, InternalConfiguration internalConfig)
        {
            if (options == null) throw new ArgumentNullException("options");
            if (options.Factory == null) throw new InvalidOperationException("null factory");
            if (internalConfig == null) throw new ArgumentNullException("internalConfig");

            IdentityServerServiceFactory fact = options.Factory;
            fact.Validate();

            var builder = new ContainerBuilder();

            builder.RegisterInstance(internalConfig).AsSelf();

            // mandatory from factory
            builder.Register(fact.UserService);
            builder.Register(fact.ScopeService);
            builder.Register(fact.ClientService);
            builder.Register(fact.CoreSettings);
            
            // optional from factory
            if (fact.AuthorizationCodeStore != null)
            {
                builder.Register(fact.AuthorizationCodeStore);
            }
            else
            {
                var inmemCodeStore = new InMemoryAuthorizationCodeStore();
                builder.RegisterInstance(inmemCodeStore).As<IAuthorizationCodeStore>();
            }

            if (fact.TokenHandleStore != null)
            {
                builder.Register(fact.TokenHandleStore);
            }
            else
            {
                var inmemTokenHandleStore = new InMemoryTokenHandleStore();
                builder.RegisterInstance(inmemTokenHandleStore).As<ITokenHandleStore>();
            }

            if (fact.RefreshTokenStore != null)
            {
                builder.Register(fact.RefreshTokenStore);
            }
            else
            {
                var inmemRefreshTokenStore = new InMemoryRefreshTokenStore();
                builder.RegisterInstance(inmemRefreshTokenStore).As<IRefreshTokenStore>();
            }

            if (fact.ConsentService != null)
            {
                builder.Register(fact.ConsentService);
            }
            else
            {
                var inmemConsentService = new InMemoryConsentService();
                builder.RegisterInstance(inmemConsentService).As<IConsentService>();
            }

            if (fact.ClaimsProvider != null)
            {
                builder.Register(fact.ClaimsProvider);
            }
            else
            {
                builder.RegisterType<DefaultClaimsProvider>().As<IClaimsProvider>();
            }

            if (fact.TokenService != null)
            {
                builder.Register(fact.TokenService);
            }
            else
            {
                builder.RegisterType<DefaultTokenService>().As<ITokenService>();
            }

            if (fact.RefreshTokenService != null)
            {
                builder.Register(fact.RefreshTokenService);
            }
            else
            {
                builder.RegisterType<DefaultRefreshTokenService>().As<IRefreshTokenService>();
            }

            if (fact.TokenSigningService != null)
            {
                builder.Register(fact.TokenSigningService);
            }
            else
            {
                builder.RegisterType<DefaultTokenSigningService>().As<ITokenSigningService>();
            }

            if (fact.CustomRequestValidator != null)
            {
                builder.Register(fact.CustomRequestValidator);
            }
            else
            {
                builder.RegisterType<DefaultCustomRequestValidator>().As<ICustomRequestValidator>();
            }

            if (fact.AssertionGrantValidator != null)
            {
                builder.Register(fact.AssertionGrantValidator);
            }
            else
            {
                builder.RegisterType<DefaultAssertionGrantValidator>().As<IAssertionGrantValidator>();
            }

            if (fact.ExternalClaimsFilter != null)
            {
                builder.Register(fact.ExternalClaimsFilter);
            }
            else
            {
                builder.RegisterType<DefaultExternalClaimsFilter>().As<IExternalClaimsFilter>();
            }

            if (fact.CustomTokenValidator != null)
            {
                builder.Register(fact.CustomTokenValidator);
            }
            else
            {
                builder.RegisterType<DefaultCustomTokenValidator>().As<ICustomTokenValidator>();
            }

            // validators
            builder.RegisterType<TokenRequestValidator>();
            builder.RegisterType<AuthorizeRequestValidator>();
            builder.RegisterType<ClientValidator>();
            builder.RegisterType<TokenValidator>();

            // processors
            builder.RegisterType<TokenResponseGenerator>();
            builder.RegisterType<AuthorizeResponseGenerator>();
            builder.RegisterType<AuthorizeInteractionResponseGenerator>();
            builder.RegisterType<UserInfoResponseGenerator>();

            // general services
            builder.RegisterType<CookieMiddlewareTrackingCookieService>().As<ITrackingCookieService>();

            // for authentication
            var authenticationOptions = options.AuthenticationOptions ?? new AuthenticationOptions();
            builder.RegisterInstance(authenticationOptions).AsSelf();

            // load core controller
            builder.RegisterApiControllers(typeof(AuthorizeEndpointController).Assembly);

            // add any additional dependencies from hosting application
            foreach(var registration in fact.Registrations)
            {
                builder.Register(registration);
            }

            return builder.Build();
        }