예제 #1
0
        public async Task ShouldOnlyGetPublicScopes()
        {
            await _setup;
            var   result = (await _scopeStore.GetScopesAsync(publicOnly: true)).ToArray();

            foreach (var evenScopeName in _evenScopeNames)
            {
                Assert.DoesNotContain(evenScopeName, result.Select(x => x.Name));
            }

            foreach (var oddScopeName in _oddScopeNames)
            {
                Assert.Contains(oddScopeName, result.Select(x => x.Name));
            }
        }
        public async Task <IEnumerable <string> > GetRequestedClaimTypesAsync(IEnumerable <string> scopes)
        {
            if (scopes == null || !scopes.Any())
            {
                return(Enumerable.Empty <string>());
            }

            var scopeString = string.Join(" ", scopes);

            Logger.InfoFormat("Scopes in access token: {0}", scopeString);

            var scopeDetails = await _scopes.GetScopesAsync();

            var scopeClaims = new List <string>();

            foreach (var scope in scopes)
            {
                var scopeDetail = scopeDetails.FirstOrDefault(s => s.Name == scope);

                if (scopeDetail != null)
                {
                    if (scopeDetail.Type == ScopeType.Identity)
                    {
                        scopeClaims.AddRange(scopeDetail.Claims.Select(c => c.Name));
                    }
                }
            }

            return(scopeClaims);
        }
        public async Task VerifyAdd()
        {
            Assert.Empty(await _scopeStore.GetScopesAsync(false));
            _ps.Invoke();

            var result = (await _scopeStore.GetScopesAsync(false)).ToArray();

            Assert.Equal(1, result.Length);
            var scope = result.Single();

            Assert.Equal("unit_test_scope", scope.Name);
            Assert.Equal("displayName", scope.DisplayName);
            Assert.Equal("claim description", scope.Description);
            Assert.Equal("customRuleName", scope.ClaimsRule);
            Assert.True(scope.Emphasize);
            Assert.True(scope.Enabled);
            Assert.True(scope.IncludeAllClaimsForUser);
            Assert.True(scope.Required);
            Assert.True(scope.ShowInDiscoveryDocument);
            Assert.Equal(ScopeType.Identity, scope.Type);
            Assert.Equal(2, scope.Claims.Count());
            var first = scope.Claims.OrderBy(x => x.Name).First();

            Assert.Equal("unit_test_claim1", first.Name);
            Assert.Equal("Sample description for unit test", first.Description);
            Assert.True(first.AlwaysIncludeInIdToken);

            var second = scope.Claims.OrderBy(x => x.Name).Skip(1).First();

            Assert.Equal("unit_test_claim2", second.Name);
            Assert.Equal("Sample description", second.Description);
            Assert.False(second.AlwaysIncludeInIdToken);
            Assert.True(scope.AllowUnrestrictedIntrospection);
            Assert.Equal(new List <Secret> {
                new Secret("secret1"),
                new Secret("secret2", "description", new DateTimeOffset(2000, 1, 1, 1, 1, 1, 1, TimeSpan.Zero))
                {
                    Type = "SomeOtherType"
                }
            }.Select(TestData.ToTestableString),
                         scope.ScopeSecrets.Select(TestData.ToTestableString));
        }
예제 #4
0
        public async Task <IEnumerable <Scope> > GetScopesAsync(bool publicOnly = true)
        {
            var key = GetKey(publicOnly);

            var scopes = await _cache.GetAsync(key,
                                               _options.CachingOptions.ScopeStoreExpiration,
                                               () => _inner.GetScopesAsync(publicOnly),
                                               _logger);

            return(scopes);
        }
예제 #5
0
 public async Task VerifyAllBuiltInScopes()
 {
     _ps.Invoke();
     Assert.Null(_data.GetPowershellErrors());
     Assert.Equal(
         ReadScopes.BuiltInScopes()
         .OrderBy(x => x.Name)
         .Select(TestData.ToTestableString),
         (await _scopeStore.GetScopesAsync(false))
         .OrderBy(x => x.Name)
         .Select(TestData.ToTestableString)
         );
 }
예제 #6
0
        /// <summary>
        /// Gets the client permissions asynchronous.
        /// </summary>
        /// <param name="subject">The subject identifier.</param>
        /// <returns>
        /// A list of client permissions
        /// </returns>
        /// <exception cref="System.ArgumentNullException">subject</exception>
        public async Task <IEnumerable <ClientPermission> > GetClientPermissionsAsync(string subject)
        {
            if (String.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentNullException("subject");
            }

            var consents = await this.permissionsStore.LoadAllAsync(subject);

            var list = new List <ClientPermission>();

            foreach (var consent in consents)
            {
                var client = await clientStore.FindClientByIdAsync(consent.ClientId);

                if (client != null)
                {
                    var scopes = await scopeStore.GetScopesAsync();

                    var identityScopes = scopes.Where(x => x.Type == ScopeType.Identity && consent.Scopes.Contains(x.Name)).Select(x => new PermissionDescription {
                        DisplayName = x.DisplayName, Description = x.Description
                    });
                    var resourceScopes = scopes.Where(x => x.Type == ScopeType.Resource && consent.Scopes.Contains(x.Name)).Select(x => new PermissionDescription {
                        DisplayName = x.DisplayName, Description = x.Description
                    });

                    list.Add(new ClientPermission
                    {
                        ClientId            = client.ClientId,
                        ClientName          = client.ClientName,
                        ClientUrl           = client.ClientUri,
                        ClientLogoUrl       = client.LogoUri.AbsoluteUri,
                        IdentityPermissions = identityScopes,
                        ResourcePermissions = resourceScopes
                    });
                }
            }

            return(list);
        }
예제 #7
0
        private async Task <bool> ValidateRequestedScopesAsync(NameValueCollection parameters)
        {
            var scopeValidator  = new ScopeValidator();
            var requestedScopes = scopeValidator.ParseScopes(parameters.Get(Constants.TokenRequest.Scope));

            if (requestedScopes == null)
            {
                return(false);
            }

            if (!scopeValidator.AreScopesAllowed(_validatedRequest.Client, requestedScopes))
            {
                return(false);
            }

            if (!scopeValidator.AreScopesValid(requestedScopes, await _scopes.GetScopesAsync()))
            {
                return(false);
            }

            _validatedRequest.Scopes          = requestedScopes;
            _validatedRequest.ValidatedScopes = scopeValidator;
            return(true);
        }
예제 #8
0
        private async Task <IEndpointResult> ExecuteDiscoDocAsync(HttpContext context)
        {
            _logger.LogTrace("Start discovery request");

            var baseUrl   = _context.GetIdentityServerBaseUrl().EnsureTrailingSlash();
            var allScopes = await _scopes.GetScopesAsync(publicOnly : true);

            var showScopes = new List <Scope>();

            var document = new DiscoveryDocument
            {
                issuer = _context.GetIssuerUri(),
                subject_types_supported = new[] { "public" },
                id_token_signing_alg_values_supported = new[] { Constants.SigningAlgorithms.RSA_SHA_256 }
            };

            // scopes
            if (_options.DiscoveryOptions.ShowIdentityScopes)
            {
                showScopes.AddRange(allScopes.Where(s => s.Type == ScopeType.Identity));
            }
            if (_options.DiscoveryOptions.ShowResourceScopes)
            {
                showScopes.AddRange(allScopes.Where(s => s.Type == ScopeType.Resource));
            }

            if (showScopes.Any())
            {
                document.scopes_supported = showScopes.Where(s => s.ShowInDiscoveryDocument).Select(s => s.Name).ToArray();
            }

            // claims
            if (_options.DiscoveryOptions.ShowClaims)
            {
                var claims = new List <string>();
                foreach (var s in allScopes)
                {
                    claims.AddRange(from c in s.Claims
                                    where s.Type == ScopeType.Identity
                                    select c.Name);
                }

                document.claims_supported = claims.Distinct().ToArray();
            }

            // grant types
            if (_options.DiscoveryOptions.ShowGrantTypes)
            {
                var standardGrantTypes = Constants.SupportedGrantTypes.AsEnumerable();
                if (this._options.AuthenticationOptions.EnableLocalLogin == false)
                {
                    standardGrantTypes = standardGrantTypes.Where(type => type != OidcConstants.GrantTypes.Password);
                }

                var showGrantTypes = new List <string>(standardGrantTypes);

                if (_options.DiscoveryOptions.ShowCustomGrantTypes)
                {
                    showGrantTypes.AddRange(_customGrants.GetAvailableGrantTypes());
                }

                document.grant_types_supported = showGrantTypes.ToArray();
            }

            // response types
            if (_options.DiscoveryOptions.ShowResponseTypes)
            {
                document.response_types_supported = Constants.SupportedResponseTypes.ToArray();
            }

            // response modes
            if (_options.DiscoveryOptions.ShowResponseModes)
            {
                document.response_modes_supported = Constants.SupportedResponseModes.ToArray();
            }

            // token endpoint authentication methods
            if (_options.DiscoveryOptions.ShowTokenEndpointAuthenticationMethods)
            {
                document.token_endpoint_auth_methods_supported = _parsers.GetAvailableAuthenticationMethods().ToArray();
            }

            // endpoints
            if (_options.DiscoveryOptions.ShowEndpoints)
            {
                if (_options.Endpoints.EnableEndSessionEndpoint)
                {
                    document.http_logout_supported = true;
                }

                if (_options.Endpoints.EnableAuthorizeEndpoint)
                {
                    document.authorization_endpoint = baseUrl + Constants.RoutePaths.Oidc.Authorize;
                }

                if (_options.Endpoints.EnableTokenEndpoint)
                {
                    document.token_endpoint = baseUrl + Constants.RoutePaths.Oidc.Token;
                }

                if (_options.Endpoints.EnableUserInfoEndpoint)
                {
                    document.userinfo_endpoint = baseUrl + Constants.RoutePaths.Oidc.UserInfo;
                }

                if (_options.Endpoints.EnableEndSessionEndpoint)
                {
                    document.end_session_endpoint = baseUrl + Constants.RoutePaths.Oidc.EndSession;
                }

                if (_options.Endpoints.EnableCheckSessionEndpoint)
                {
                    document.check_session_iframe = baseUrl + Constants.RoutePaths.Oidc.CheckSession;
                }

                if (_options.Endpoints.EnableTokenRevocationEndpoint)
                {
                    document.revocation_endpoint = baseUrl + Constants.RoutePaths.Oidc.Revocation;
                }

                if (_options.Endpoints.EnableIntrospectionEndpoint)
                {
                    document.introspection_endpoint = baseUrl + Constants.RoutePaths.Oidc.Introspection;
                }
            }

            if (_options.DiscoveryOptions.ShowKeySet)
            {
                if (_options.SigningCertificate != null)
                {
                    document.jwks_uri = baseUrl + Constants.RoutePaths.Oidc.DiscoveryWebKeys;
                }
            }

            return(new DiscoveryDocumentResult(document, _options.DiscoveryOptions.CustomEntries));
        }
예제 #9
0
        /// <summary>
        /// Gets all defined scopes.
        /// </summary>
        /// <param name="publicOnly">if set to <c>true</c> only public scopes are returned.</param>
        /// <returns></returns>
        public async Task <IEnumerable <Scope> > GetScopesAsync(bool publicOnly = true)
        {
            var key = GetKey(publicOnly);

            return(await cache.GetAsync(key, async() => await inner.GetScopesAsync(publicOnly)));
        }
예제 #10
0
        public async Task <ValidationResult> ValidateClientAsync()
        {
            Logger.Info("Start client validation");

            if (_validatedRequest.ClientId.IsMissing())
            {
                throw new InvalidOperationException("ClientId is empty. Validate protocol first.");
            }

            //////////////////////////////////////////////////////////
            // check for valid client
            //////////////////////////////////////////////////////////
            var client = await _clients.FindClientByIdAsync(_validatedRequest.ClientId);

            if (client == null || client.Enabled == false)
            {
                Logger.ErrorFormat("Unknown client or not enabled: {0}", _validatedRequest.ClientId);
                return(Invalid(ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient));
            }

            Logger.InfoFormat("Client found in registry: {0} / {1}", client.ClientId, client.ClientName);
            _validatedRequest.Client = client;

            //////////////////////////////////////////////////////////
            // check if redirect_uri is valid
            //////////////////////////////////////////////////////////
            if (!_validatedRequest.Client.RedirectUris.Contains(_validatedRequest.RedirectUri))
            {
                Logger.ErrorFormat("Invalid redirect_uri: {0}", _validatedRequest.RedirectUri);
                return(Invalid(ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient));
            }

            //////////////////////////////////////////////////////////
            // check if flow is allowed for client
            //////////////////////////////////////////////////////////
            if (_validatedRequest.Flow != _validatedRequest.Client.Flow)
            {
                Logger.ErrorFormat("Invalid flow for client: {0}", _validatedRequest.Flow);
                return(Invalid(ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient));
            }

            var scopeValidator = new ScopeValidator();

            //////////////////////////////////////////////////////////
            // check if scopes are valid/supported and check for resource scopes
            //////////////////////////////////////////////////////////
            if (!scopeValidator.AreScopesValid(_validatedRequest.RequestedScopes, await _scopes.GetScopesAsync()))
            {
                return(Invalid(ErrorTypes.Client, Constants.AuthorizeErrors.InvalidScope));
            }

            if (scopeValidator.ContainsOpenIdScopes && !_validatedRequest.IsOpenIdRequest)
            {
                Logger.Error("Identity related scope requests, but no openid scope");
                return(Invalid(ErrorTypes.Client, Constants.AuthorizeErrors.InvalidScope));
            }

            if (scopeValidator.ContainsResourceScopes)
            {
                _validatedRequest.IsResourceRequest = true;
            }

            //////////////////////////////////////////////////////////
            // check scopes and scope restrictions
            //////////////////////////////////////////////////////////
            if (!scopeValidator.AreScopesAllowed(_validatedRequest.Client, _validatedRequest.RequestedScopes))
            {
                return(Invalid(ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient));
            }

            _validatedRequest.ValidatedScopes = scopeValidator;

            //////////////////////////////////////////////////////////
            // check id vs resource scopes and response types plausability
            //////////////////////////////////////////////////////////
            if (!scopeValidator.IsResponseTypeValid(_validatedRequest.ResponseType))
            {
                return(Invalid(ErrorTypes.Client, Constants.AuthorizeErrors.InvalidScope));
            }

            var customResult = await _customValidator.ValidateAuthorizeRequestAsync(_validatedRequest);

            if (customResult.IsError)
            {
                Logger.Error("Error in custom validation: " + customResult.Error);
            }

            Logger.Info("Client validation successful");
            return(customResult);
        }
        public static async Task <IEnumerable <Scope> > GetEnabledScopesAsync(this IScopeStore store, bool publicOnly = true)
        {
            var scopes = await store.GetScopesAsync(publicOnly);

            return(scopes.Where(s => s.Enabled == true).ToArray());
        }
예제 #12
0
 /// <summary>
 /// Get Scope Secrets
 /// </summary>
 /// <param name="publicOnly">Public Only Flag</param>
 /// <returns>List of Scopes</returns>
 public Task <IEnumerable <Scope> > GetScopesAsync(bool publicOnly = true)
 {
     return(scopeStore.GetScopesAsync(publicOnly));
 }