예제 #1
0
        public async Task Excluded_endpoints_should_not_fail_validation()
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                ValidateEndpoints             = true,
                EndpointValidationExcludeList =
                {
                    "jwks_uri",
                    "authorization_endpoint",
                    "token_endpoint",
                    "userinfo_endpoint",
                    "end_session_endpoint",
                    "check_session_iframe",
                    "revocation_endpoint",
                    "introspection_endpoint",
                }
            });

            var handler = GetHandler("https://authority", "https://otherserver");
            var client  = new HttpClient(handler);

            var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = "https://authority",
                Policy  = policy
            });

            disco.IsError.Should().BeFalse();
        }
    protected override Task InitializeAsync(object initializationData = null)
    {
        if (!HttpResponse.IsSuccessStatusCode)
        {
            ErrorMessage = initializationData as string;
            return(Task.CompletedTask);
        }

        Policy = initializationData as DiscoveryPolicy ?? new DiscoveryPolicy();

        var validationError = Validate(Policy);

        if (validationError.IsPresent())
        {
            Json = default;

            ErrorType    = ResponseErrorType.PolicyViolation;
            ErrorMessage = validationError;
        }

        MtlsEndpointAliases =
            new MtlsEndpointAliases(Json.TryGetValue(OidcConstants.Discovery.MtlsEndpointAliases));

        return(Task.CompletedTask);
    }
예제 #3
0
        /// <summary>
        /// 刷新 Access Token
        /// </summary>
        /// <param name="_RefreshToken"></param>
        /// <param name="address"></param>
        /// <returns></returns>
        private bool RefreshToken(string _RefreshToken, string address)
        {
            HttpClient      _client = new HttpClient();
            DiscoveryPolicy policy  = new DiscoveryPolicy
            {
                RequireHttps = false
            };
            DiscoveryDocumentRequest request = new DiscoveryDocumentRequest();

            request.Address = address;
            request.Policy  = policy;
            var _discover = _client.GetDiscoveryDocumentAsync(request).Result;

            if (!_discover.IsError)
            {
                var rcct = new RefreshTokenRequest();
                rcct.Address      = _discover.TokenEndpoint;
                rcct.ClientId     = FDConst.IS_Client;
                rcct.ClientSecret = FDConst.IS_ClientSecret;
                rcct.RefreshToken = _RefreshToken;
                var token = _client.RequestRefreshTokenAsync(rcct).Result;
                if (!token.IsError)
                {
                    //Set new Access token
                    //Commonutility.GetContext().SetValue(FDConst.IS_AuthenticationToken, token.AccessToken);
                    //set new refresh token
                    //Commonutility.GetContext().SetValue(FDConst.IS_AuthenticationRefreshToken, token.RefreshToken);
                }

                return(token.IsError);
            }

            return(_discover.IsError);
        }
예제 #4
0
        public async Task Endpoints_not_belonging_to_authority_host_must_be_allowed_if_whitelisted(string authority, string endpointBase)
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                RequireHttps       = true,
                ValidateIssuerName = true,
                ValidateEndpoints  = true,

                AdditionalEndpointBaseAddresses =
                {
                    endpointBase
                }
            });

            var handler = GetHandler(authority, endpointBase);
            var client  = new HttpClient(handler);

            var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = authority,
                Policy  = policy
            });

            disco.IsError.Should().BeFalse();
        }
        public static async Task <ProviderInformation> GetProviderInformation()
        {
            // Discover endpoints from metadata.
            using HttpClient client = new ();

            // Create a discovery request
            using DiscoveryDocumentRequest discoveryDocumentRequest = new ()
                  {
                      Address = AdhIdentityUrl,
                      Policy  = new DiscoveryPolicy
                      {
                          ValidateIssuerName = false,
                      },
                  };

            DiscoveryDocumentResponse discoveryResponse =
                await client.GetDiscoveryDocumentAsync(discoveryDocumentRequest).ConfigureAwait(false);

            return(discoveryResponse.IsError
                ? throw new Exception($"Error while getting the discovery document: {discoveryResponse.Error}")
                : new ProviderInformation()
            {
                IssuerName = discoveryResponse.Issuer,
                KeySet = discoveryResponse.KeySet,
                AuthorizeEndpoint = discoveryResponse.AuthorizeEndpoint,
                TokenEndpoint = discoveryResponse.TokenEndpoint,
                EndSessionEndpoint = discoveryResponse.EndSessionEndpoint,
                UserInfoEndpoint = discoveryResponse.UserInfoEndpoint,
                TokenEndPointAuthenticationMethods =
                    discoveryResponse.TokenEndpointAuthenticationMethodsSupported,
            });
        }
 public DiscoveryEndpointFactory(string authority, HttpClient httpClient)
 {
     _authority       = authority;
     _httpClient      = httpClient;
     _discoveryPolicy = new DiscoveryPolicy
     {
         RequireHttps = authority.StartsWith("https://")
     };
 }
예제 #7
0
        public SigningKeysProvider(string authority)
        {
            var policy = new DiscoveryPolicy
            {
                ValidateIssuerName = false
            };

            cache = new DiscoveryCache(authority, () => new HttpClient(), policy);
        }
        protected DiscoveryPolicy ForceTestedAuthorityValidationStrategy(DiscoveryPolicy policy)
        {
            if (policy == null)
            {
                throw new ArgumentNullException(nameof(policy));
            }

            policy.AuthorityValidationStrategy = _authorityValidationStrategy;
            return(policy);
        }
예제 #9
0
        public async void GetDiscoveryData_JWKSkeys(TraceWriter log)
        {
            log.Info("Enter Task");


            //Intialize DiscoverPolicy
            DiscoveryPolicy dpolicy = new DiscoveryPolicy();

            dpolicy.RequireHttps       = true;
            dpolicy.ValidateIssuerName = true;

            //Assign the Sandbox Discovery url for the Apps' Dev clientid and clientsecret that you use
            //Or
            //Assign the Production Discovery url for the Apps' Production clientid and clientsecret that you use



            if (discoveryUrl != null && clientID != null && clientSecret != null)
            {
                discoveryClient = new DiscoveryClient(discoveryUrl);
                log.Info("Enterted if");
            }
            log.Info("Exit if");

            DiscoveryResponse doc = await discoveryClient.GetAsync();

            log.Info("Doc done");

            if (doc.StatusCode == HttpStatusCode.OK)
            {
                //Authorization endpoint url
                authorizationEndpoint = doc.AuthorizeEndpoint;

                //Token endpoint url
                tokenEndpoint = doc.TokenEndpoint;

                //UseInfo endpoint url
                userinfoEndPoint = doc.UserInfoEndpoint;

                //Revoke endpoint url
                revokeEndpoint = doc.RevocationEndpoint;

                //Issuer endpoint Url
                issuerUrl = doc.Issuer;

                //JWKS Keys
                keys = doc.KeySet.Keys;
                log.Info("Discovery Data obtained.");
            }

            else
            {
                log.Info("Discovery error");
            }
        }
예제 #10
0
        private async Task <string> GetAccessTokenAsync(CancellationToken cancellationToken)
        {
            if (_accessToken != null && DateTime.UtcNow < _accessTokenExpiry)
            {
                return(_accessToken);
            }

            using HttpClient client = new ();
            using DiscoveryDocumentRequest discoveryRequest = new ()
                  {
                      Address = _resource + "/identity",
                      Policy  = new DiscoveryPolicy
                      {
                          Authority          = "https://identity.aveva.com",
                          ValidateEndpoints  = false,
                          ValidateIssuerName = false,
                      },
                  };

            DiscoveryDocumentResponse discoveryResponse = await client.GetDiscoveryDocumentAsync(discoveryRequest, cancellationToken).ConfigureAwait(false);

            if (discoveryResponse.IsError)
            {
                throw new InvalidOperationException(discoveryResponse.Error);
            }

            using ClientCredentialsTokenRequest clientCredentialsTokenRequest = new ()
                  {
                      Address      = discoveryResponse.TokenEndpoint,
                      ClientId     = _clientId,
                      ClientSecret = _clientSecret,
                      Scope        = "ocsapi",
                  };

            DateTime now = DateTime.UtcNow;

            TokenResponse tokenResponse = await client.RequestClientCredentialsTokenAsync(clientCredentialsTokenRequest, cancellationToken).ConfigureAwait(false);

            if (discoveryResponse.IsError)
            {
                throw new InvalidOperationException(tokenResponse.Error);
            }

            if (string.IsNullOrEmpty(tokenResponse.AccessToken))
            {
                throw new InvalidOperationException("Failed to acquire Access Token");
            }

            _accessToken = tokenResponse.AccessToken;

            // Add a buffer of 30 seconds to the expiration delta.
            _accessTokenExpiry = now.AddSeconds(tokenResponse.ExpiresIn - 30);

            return(_accessToken);
        }
        private DiscoveryClient CreateDiscoveryClient(string authorityUrl)
        {
            var policy = new DiscoveryPolicy {
                RequireKeySet      = true,
                RequireHttps       = Options.RequireHttps,
                ValidateIssuerName = true,
                ValidateEndpoints  = true,
            };
            var client = new DiscoveryClient(authorityUrl);

            client.Policy = policy;
            return(client);
        }
예제 #12
0
        /// <summary>
        /// Get Discovery Data
        /// </summary>
        /// <returns></returns>
        public async System.Threading.Tasks.Task getDiscoveryData_JWKSkeys()
        {
            output("Fetching Discovery Data.");

            //Intialize DiscoverPolicy
            DiscoveryPolicy dpolicy = new DiscoveryPolicy();

            dpolicy.RequireHttps       = true;
            dpolicy.ValidateIssuerName = true;


            //Assign the Sandbox Discovery url for the Apps' Dev clientid and clientsecret that you use
            //Or
            //Assign the Production Discovery url for the Apps' Production clientid and clientsecret that you use



            if (discoveryUrl != null && clientID != null && clientSecret != null)
            {
                discoveryClient = new DiscoveryClient(discoveryUrl);
            }

            doc = await discoveryClient.GetAsync();

            if (doc.StatusCode == HttpStatusCode.OK)
            {
                //Authorization endpoint url
                authorizationEndpoint = doc.AuthorizeEndpoint;

                //Token endpoint url
                tokenEndpoint = doc.TokenEndpoint;

                //UseInfo endpoint url
                userinfoEndPoint = doc.UserInfoEndpoint;

                //Revoke endpoint url
                revokeEndpoint = doc.RevocationEndpoint;

                //Issuer endpoint Url
                issuerUrl = doc.Issuer;

                //JWKS Keys
                keys = doc.KeySet.Keys;
                output("Discovery Data obtained.");
            }
            else
            {
                output("Discovery error");
            }
        }
        //获取Token
        //获取Token
        public async Task <string> GetToken()
        {
            var    client = _httpClientFactory.CreateClient("MI.Web");
            string token  = await Untity.StackRedis.Current.Get("ApiToken");

            if (!string.IsNullOrEmpty(token))
            {
                return(token);
            }
            try
            {
                //DiscoveryClient类:IdentityModel提供给我们通过基础地址(如:http://localhost:5000)就可以访问令牌服务端;
                //当然可以根据上面的restful api里面的url自行构建;上面就是通过基础地址,获取一个TokenClient;(对应restful的url:token_endpoint   "http://localhost:5000/connect/token")
                //RequestClientCredentialsAsync方法:请求令牌;
                //获取令牌后,就可以通过构建http请求访问API接口;这里使用HttpClient构建请求,获取内容;

                DiscoveryPolicy discoveryPolicy = new DiscoveryPolicy {
                    RequireHttps = false
                };
                var cache = new DiscoveryCache(_configuration["ServiceAddress:Service.Identity"], client, discoveryPolicy);
                var disco = await cache.GetAsync();

                if (disco.IsError)
                {
                    throw new Exception(disco.Error);
                }
                var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                {
                    Address      = disco.TokenEndpoint,
                    ClientId     = "MI.Web",
                    ClientSecret = "miwebsecret",
                    Scope        = "MI.Service"
                });

                if (tokenResponse.IsError)
                {
                    throw new Exception(tokenResponse.Error);
                }
                token = tokenResponse.AccessToken;
                int minute = tokenResponse.ExpiresIn / 60;
                await Untity.StackRedis.Current.Set("ApiToken", token, minute);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            return(token);
        }
예제 #14
0
        public async Task If_policy_allows_http_non_http_must_not_return_error()
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                RequireHttps = false
            });

            var client = new HttpClient(GetHandler("http://authority"));
            var disco  = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = "http://authority",
                Policy  = policy
            });

            disco.IsError.Should().BeFalse();
        }
예제 #15
0
        public async Task Valid_Urls_with_default_policy_should_succeed(string input)
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                RequireHttps        = true,
                AllowHttpOnLoopback = true
            });

            var client = new HttpClient(GetHandler(input));
            var disco  = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = input,
                Policy  = policy
            });

            disco.IsError.Should().BeFalse();
        }
예제 #16
0
        public async Task Http_on_loopback_must_not_return_error(string input)
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                RequireHttps        = true,
                AllowHttpOnLoopback = true
            });

            var client = new HttpClient(GetHandler(input));
            var disco  = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = input,
                Policy  = policy
            });

            disco.IsError.Should().BeFalse();
        }
예제 #17
0
        public void SerializeSettings()
        {
            var introspectionDiscoveryPolicy = new DiscoveryPolicy
            {
                ValidateEndpoints               = true,
                RequireHttps                    = true,
                ValidateIssuerName              = true,
                AllowHttpOnLoopback             = true,
                RequireKeySet                   = true,
                Authority                       = "https://identityserver:443",
                AdditionalEndpointBaseAddresses = { "https://identityserver", "https://identityserver:443" },
                //EndpointValidationExcludeList = { "https://lclhst", "https://lclhst:443" }
            };
            var value = JsonSerializer.Serialize(introspectionDiscoveryPolicy);

            value.Should().NotBeEmpty();
        }
        public async Task Policy_authority_does_not_get_overwritten()
        {
            var policy = new DiscoveryPolicy
            {
                Authority = "https://server:123"
            };

            var client = new DiscoveryClient(_endpoint, _successHandler)
            {
                Policy = policy
            };

            var disco = await client.GetAsync();

            disco.IsError.Should().BeTrue();
            policy.Authority.Should().Be("https://server:123");
        }
예제 #19
0
        public async Task Policy_authority_does_not_get_overwritten()
        {
            var policy = new DiscoveryPolicy
            {
                Authority = "https://server:123"
            };

            var client = new HttpClient(_successHandler);
            var disco  = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = _endpoint,
                Policy  = policy
            });

            disco.IsError.Should().BeTrue();
            policy.Authority.Should().Be("https://server:123");
        }
예제 #20
0
        public async Task String_comparison_with_uri_equivalence_is_default_strategy()
        {
            DiscoveryPolicy policy = new DiscoveryPolicy()
            {
                ValidateIssuerName = true
            };

            var handler = GetHandler(issuer: "https://authority:443/tenantid/");
            var client  = new HttpClient(handler);

            var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = "https://authority/tenantid",
                Policy  = policy
            });

            disco.IsError.Should().BeTrue();
        }
예제 #21
0
        public async Task Valid_issuer_name_must_return_no_error()
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                ValidateIssuerName = true
            });

            var handler = GetHandler("https://authority");
            var client  = new HttpClient(handler);

            var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = "https://authority",
                Policy  = policy
            });

            disco.IsError.Should().BeFalse();
        }
예제 #22
0
        public async Task Authority_comparison_with_uri_equivalence()
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                ValidateIssuerName          = true,
                AuthorityValidationStrategy = new AuthorityUrlValidationStrategy()
            });

            var handler = GetHandler(issuer: "https://authority:443/tenantid/");
            var client  = new HttpClient(handler);

            var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = "https://authority/tenantid",
                Policy  = policy
            });

            disco.IsError.Should().BeFalse();
        }
        public async Task Authority_comparison_may_be_case_insensitive()
        {
            DiscoveryPolicy policy = new DiscoveryPolicy()
            {
                ValidateIssuerName          = true,
                AuthorityValidationStrategy = new StringComparisonAuthorityValidationStrategy(StringComparison.OrdinalIgnoreCase)
            };

            var handler = GetHandler("https://authority/tenantid");
            var client  = new HttpClient(handler);

            var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = "https://authority/TENANTID",
                Policy  = policy
            });

            disco.IsError.Should().BeFalse();
        }
예제 #24
0
        public async Task Invalid_issuer_name_must_return_policy_error()
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                ValidateIssuerName = true
            });

            var client = new HttpClient(GetHandler("https://differentissuer"));
            var disco  = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = "https://authority",
                Policy  = policy
            });

            disco.IsError.Should().BeTrue();
            disco.Json.Should().BeNull();
            disco.ErrorType.Should().Be(ResponseErrorType.PolicyViolation);
            disco.Error.Should().StartWith("Issuer name does not match authority");
        }
예제 #25
0
        public async Task Issuer_and_endpoint_can_be_unrelated_if_allowed()
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                RequireHttps       = true,
                ValidateIssuerName = true,
                ValidateEndpoints  = false
            });

            var handler = GetHandler("https://authority", "https://differentauthority");
            var client  = new HttpClient(handler);

            var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = "https://authority",
                Policy  = policy
            });

            disco.IsError.Should().BeFalse();
        }
예제 #26
0
        public async Task Connecting_to_http_should_return_error()
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                RequireHttps        = true,
                AllowHttpOnLoopback = true
            });

            var client = new HttpClient();
            var disco  = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = "http://authority",
                Policy  = policy
            });

            disco.IsError.Should().BeTrue();
            disco.Json.Should().BeNull();
            disco.ErrorType.Should().Be(ResponseErrorType.Exception);
            disco.Error.Should().StartWith("Error connecting to");
            disco.Error.Should().EndWith("HTTPS required.");
        }
예제 #27
0
        public async Task <IActionResult> Index()
        {
            var model       = new IdentityStatusModel();
            var discoPolicy = new DiscoveryPolicy {
                ValidateIssuerName = false, RequireHttps = false
            };

            using (var discoClient =
                       new DiscoveryClient(_appConfiguration.IdentityServerConfidentialClientSettings.Authority)
            {
                Policy = discoPolicy
            })
            {
                var discoveryDocument = await discoClient.GetAsync();

                model.ScopesSupported = discoveryDocument?.ScopesSupported ?? new List <string>();
                model.GrantsSupported = discoveryDocument?.GrantTypesSupported ?? new List <string>();
            }
            model.ClientCount = _clientManagementStore.GetClientCount();

            return(View(model));
        }
    /// <summary>
    /// Determines whether uses a secure scheme accoding to the policy.
    /// </summary>
    /// <param name="url">The URL.</param>
    /// <param name="policy">The policy.</param>
    /// <returns>
    ///   <c>true</c> if [is secure scheme] [the specified URL]; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsSecureScheme(Uri url, DiscoveryPolicy policy)
    {
        if (policy.RequireHttps == true)
        {
            if (policy.AllowHttpOnLoopback == true)
            {
                var hostName = url.DnsSafeHost;

                foreach (var address in policy.LoopbackAddresses)
                {
                    if (string.Equals(hostName, address, StringComparison.OrdinalIgnoreCase))
                    {
                        return(true);
                    }
                }
            }

            return(string.Equals(url.Scheme, "https", StringComparison.OrdinalIgnoreCase));
        }

        return(true);
    }
예제 #29
0
        public async Task Endpoints_not_belonging_to_authority_host_must_return_policy_error(string authority, string endpointBase)
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                RequireHttps       = true,
                ValidateIssuerName = true,
                ValidateEndpoints  = true
            });

            var handler = GetHandler(authority, endpointBase);
            var client  = new HttpClient(handler);

            var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = authority,
                Policy  = policy
            });

            disco.IsError.Should().BeTrue();
            disco.Json.Should().BeNull();
            disco.ErrorType.Should().Be(ResponseErrorType.PolicyViolation);
            disco.Error.Should().StartWith("Endpoint is on a different host than authority");
        }
예제 #30
0
        public async Task Issuer_and_endpoint_can_be_unrelated_if_allowed_but_https_is_still_enforced()
        {
            DiscoveryPolicy policy = ForceTestedAuthorityValidationStrategy(new DiscoveryPolicy()
            {
                RequireHttps       = true,
                ValidateIssuerName = true,
                ValidateEndpoints  = false
            });

            var handler = GetHandler("https://authority", "http://differentauthority");
            var client  = new HttpClient(handler);

            var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = "https://authority",
                Policy  = policy
            });

            disco.IsError.Should().BeTrue();
            disco.Json.Should().BeNull();
            disco.ErrorType.Should().Be(ResponseErrorType.PolicyViolation);
            disco.Error.Should().StartWith("Endpoint does not use HTTPS");
        }