Beispiel #1
0
        public async Task <IEndpointResult> ProcessAsync(HttpContext context)
        {
            _logger.LogTrace("Processing discovery request.");

            // validate HTTP
            if (context.Request.Method != "GET")
            {
                _logger.LogWarning("Discovery endpoint only supports GET requests");
                return(new StatusCodeResult(HttpStatusCode.MethodNotAllowed));
            }

            _logger.LogDebug("Start discovery request");

            if (!_options.Endpoints.EnableDiscoveryEndpoint)
            {
                _logger.LogInformation("Discovery endpoint disabled. 404.");
                return(new StatusCodeResult(HttpStatusCode.NotFound));
            }

            var baseUrl   = context.GetIdentityServerBaseUrl().EnsureTrailingSlash();
            var issuerUri = context.GetIdentityServerIssuerUri();

            // generate response
            _logger.LogTrace("Calling into discovery response generator: {type}", _responseGenerator.GetType().FullName);
            var response = await _responseGenerator.CreateDiscoveryDocumentAsync(baseUrl, issuerUri);

            return(new DiscoveryDocumentResult(response, _options.Discovery.ResponseCacheInterval));
        }
Beispiel #2
0
        public Task <IEndpointResult> ProcessAsync(HttpContext context)
        {
            _logger.LogTrace("Processing discovery request.");

            // validate HTTP
            if (!HttpMethods.IsGet(context.Request.Method))
            {
                _logger.LogWarning("Discovery endpoint only supports GET requests");
                return(Task.FromResult((IEndpointResult) new StatusCodeResult(HttpStatusCode.MethodNotAllowed)));
            }

            if (!_options.Endpoints.EnableDiscoveryEndpoint)
            {
                _logger.LogInformation("Discovery endpoint disabled. 404.");
                return(Task.FromResult((IEndpointResult) new StatusCodeResult(HttpStatusCode.NotFound)));
            }

            var baseUrl   = context.GetIdentityServerBaseUri();
            var issuerUri = context.GetIdentityServerIssuerUri();

            // generate response
            _logger.LogTrace("Calling into discovery response generator: {type}", _responseGenerator.GetType().FullName);
            var response = _responseCache.GetOrAdd(1, _ => _responseGenerator.CreateDiscoveryDocumentAsync(baseUrl, issuerUri).GetAwaiter().GetResult());

            _logger.LogTrace("Discovery request completed. Return DiscoveryDocumentResult");
            return(Task.FromResult((IEndpointResult) new DiscoveryDocumentResult(response, _options.Discovery.ResponseCacheInterval)));
        }
    public async Task <IEndpointResult> ProcessAsync(HttpContext context)
    {
        using var activity = Tracing.BasicActivitySource.StartActivity(Constants.EndpointNames.Discovery + "Endpoint");

        _logger.LogTrace("Processing discovery request.");

        // validate HTTP
        if (!HttpMethods.IsGet(context.Request.Method))
        {
            _logger.LogWarning("Discovery endpoint only supports GET requests");
            return(new StatusCodeResult(HttpStatusCode.MethodNotAllowed));
        }

        _logger.LogDebug("Start discovery request");

        if (!_options.Endpoints.EnableDiscoveryEndpoint)
        {
            _logger.LogInformation("Discovery endpoint disabled. 404.");
            return(new StatusCodeResult(HttpStatusCode.NotFound));
        }

        var baseUrl   = _urls.BaseUrl;
        var issuerUri = await _issuerNameService.GetCurrentAsync();

        // generate response
        _logger.LogTrace("Calling into discovery response generator: {type}", _responseGenerator.GetType().FullName);
        var response = await _responseGenerator.CreateDiscoveryDocumentAsync(baseUrl, issuerUri);

        return(new DiscoveryDocumentResult(response, _options.Discovery.ResponseCacheInterval));
    }
Beispiel #4
0
        private async Task <IEndpointResult> ExecuteDiscoDocAsync(HttpContext context)
        {
            _logger.LogDebug("Start discovery request");

            if (!_options.Endpoints.EnableDiscoveryEndpoint)
            {
                _logger.LogInformation("Discovery endpoint disabled. 404.");
                return(new StatusCodeResult(HttpStatusCode.NotFound));
            }

            var baseUrl   = context.GetIdentityServerBaseUrl().EnsureTrailingSlash();
            var issuerUri = context.GetIdentityServerIssuerUri();

            var response = await _responseGenerator.CreateDiscoveryDocumentAsync(baseUrl, issuerUri);

            return(new DiscoveryDocumentResult(response));
        }
Beispiel #5
0
        /// <summary>
        /// Creates the discovery document.
        /// </summary>
        /// <param name="baseUrl">The base URL.</param>
        /// <param name="issuerUri">The issuer URI.</param>
        public async Task <Dictionary <string, object> > CreateDiscoveryDocumentAsync(string baseUrl, string issuerUri)
        {
            var entries = await _inner.CreateDiscoveryDocumentAsync(baseUrl, issuerUri);

            // response modes
            if (_options.Discovery.ShowResponseModes)
            {
                if (entries.ContainsKey(IdentityModel.OidcConstants.Discovery.ResponseModesSupported))
                {
                    var response_modes = (string[])entries[IdentityModel.OidcConstants.Discovery.ResponseModesSupported];
                    if (!response_modes.Any(rm => rm == OidcConstants.ResponseModes.Json))
                    {
                        entries[IdentityModel.OidcConstants.Discovery.ResponseModesSupported] = new List <string>(response_modes)
                        {
                            OidcConstants.ResponseModes.Json
                        }
                        .ToArray();
                    }
                }
            }

            // claims
            if (_anonIdsrvOptions.AlwaysIncludeAnonymousIdInProfile && _options.Discovery.ShowClaims)
            {
                if (entries.ContainsKey(IdentityModel.OidcConstants.Discovery.ClaimsSupported))
                {
                    var claims = (string[])entries[IdentityModel.OidcConstants.Discovery.ClaimsSupported];
                    if (!claims.Any(rm => rm == JwtClaimTypes.AnonymousId))
                    {
                        entries[IdentityModel.OidcConstants.Discovery.ClaimsSupported] = new List <string>(claims)
                        {
                            JwtClaimTypes.AnonymousId
                        }
                        .ToArray();
                    }
                }
            }

            return(entries);
        }
        public async Task <ActionResult> GetConfig()
        {
            var context   = this.Request.HttpContext;
            var baseUrl   = EnsureTrailingSlash(context.GetIdentityServerBaseUrl());
            var issuerUri = context.GetIdentityServerIssuerUri();

            Dictionary <string, object> response = await _responseGenerator.CreateDiscoveryDocumentAsync(baseUrl, issuerUri);

            // if the document is being accessed via the initernal docker hostname then rewrite the urls
            // used in client side browser redirects to use the base url exposed by docker to the host OS

            string browserAccessibleBaseUrl = _config.GetValue <string>("IdentityServerIssuerUri");

            if (!string.IsNullOrWhiteSpace(browserAccessibleBaseUrl))
            {
                response["authorization_endpoint"] = $"{browserAccessibleBaseUrl}/connect/authorize";
                response["check_session_iframe"]   = $"{browserAccessibleBaseUrl}/connect/checksession";
                response["end_session_endpoint"]   = $"{browserAccessibleBaseUrl}/connect/endsession";
            }

            return(Json(response));
        }
Beispiel #7
0
        public async Task <IEndpointResult> ProcessAsync(HttpContext context)
        {
            if (!HttpMethods.IsGet(context.Request.Method))
            {
                _logger.LogWarning("Discovery endpoint only supports GET requests");
                return(new StatusCodeResult(HttpStatusCode.MethodNotAllowed));
            }

            _logger.LogDebug("Start discovery request");

            if (!_options.Endpoints.EnableDiscoveryEndpoint)
            {
                _logger.LogInformation("Discovery endpoint disabled. 404.");
                return(new StatusCodeResult(HttpStatusCode.NotFound));
            }

            String baseUrl   = context.GetPolicyServerBaseUrl().EnsureTrailingSlash();
            String issuerUri = context.GetPolicyServerIssuerUri();
            Dictionary <String, Object> response = await _responseGenerator.CreateDiscoveryDocumentAsync(baseUrl, issuerUri);

            return(new DiscoveryDocumentResult(response, _options.Discovery.ResponseCacheInterval));
        }
        private async Task <Dictionary <string, string> > FetchDiscoveryData(HttpContext httpContext)
        {
            if (_endpointDictionary == null)
            {
                var baseUrl    = httpContext.GetIdentityServerBaseUrl().EnsureTrailingSlash();
                var issuerUri  = httpContext.GetIdentityServerIssuerUri();
                var index      = issuerUri.IndexOf("://") + 3;
                var runningUri = issuerUri.Substring(index);
                index = runningUri.IndexOf('/');
                var baseUrlSegment = index >= 0?runningUri.Substring(index):"";
                // generate response
                _logger.LogTrace("Calling into discovery response generator: {type}",
                                 _responseGenerator.GetType().FullName);
                var response = await _responseGenerator.CreateDiscoveryDocumentAsync(baseUrl, issuerUri);

                var issuer = response["issuer"] as string;

                _endpointDictionary = new Dictionary <string, string>
                {
                    {
                        "discovery",
                        $"{baseUrlSegment}/.well-known/openid-configuration"
                    },
                    {
                        "jwks_uri",
                        $"{baseUrlSegment}{(response["jwks_uri"] as string).Substring(issuer.Length)}"
                    },
                    {
                        "authorization_endpoint",
                        $"{baseUrlSegment}{(response["authorization_endpoint"] as string).Substring(issuer.Length)}"
                    },
                    {
                        "token_endpoint",
                        $"{baseUrlSegment}{(response["token_endpoint"] as string).Substring(issuer.Length)}"
                    },
                    {
                        "userinfo_endpoint",
                        $"{baseUrlSegment}{(response["userinfo_endpoint"] as string).Substring(issuer.Length)}"
                    },
                    {
                        "end_session_endpoint",
                        $"{baseUrlSegment}{(response["end_session_endpoint"] as string).Substring(issuer.Length)}"
                    },
                    {
                        "check_session_iframe",
                        $"{baseUrlSegment}{(response["check_session_iframe"] as string).Substring(issuer.Length)}"
                    },

                    {
                        "revocation_endpoint",
                        $"{baseUrlSegment}{(response["revocation_endpoint"] as string).Substring(issuer.Length)}"
                    },
                    {
                        "introspection_endpoint",
                        $"{baseUrlSegment}{(response["introspection_endpoint"] as string).Substring(issuer.Length)}"
                    }
                };
            }

            return(_endpointDictionary);
        }
Beispiel #9
0
        /// <summary>
        /// Registers the asynchronous.
        /// </summary>
        /// <param name="registration">The client registration.</param>
        /// <param name="httpContext">The HTTP context.</param>
        /// <returns></returns>
        public async Task <ClientRegisteration> RegisterAsync(ClientRegisteration registration, HttpContext httpContext)
        {
            var uri       = $"{httpContext.Request.Scheme}://{httpContext.Request.Host}/";
            var discovery = await _discoveryResponseGenerator.CreateDiscoveryDocumentAsync(uri, uri).ConfigureAwait(false);

            ValidateCaller(registration, httpContext);
            Validate(registration, discovery);

            var clientName = registration.ClientNames?.FirstOrDefault(n => n.Culture == null)?.Value ??
                             registration.ClientNames?.FirstOrDefault()?.Value ?? Guid.NewGuid().ToString();
            var existing = await _clientStore.GetAsync(clientName, null).ConfigureAwait(false);

            registration.Id = existing != null?Guid.NewGuid().ToString() : clientName;

            registration.Id = registration.Id.Contains(' ') ? Guid.NewGuid().ToString() : registration.Id;
            var secret = Guid.NewGuid().ToString();

            var serializerSettings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore
            };
            var jwkKeys     = registration.Jwks?.Keys;
            var sercretList = jwkKeys != null?jwkKeys.Select(k => new ClientSecret
            {
                Id    = Guid.NewGuid().ToString(),
                Type  = IdentityServer4.IdentityServerConstants.SecretTypes.JsonWebKey,
                Value = JsonConvert.SerializeObject(k, serializerSettings)
            }).ToList() : new List <ClientSecret>();

            sercretList.Add(new ClientSecret
            {
                Id    = Guid.NewGuid().ToString(),
                Type  = IdentityServer4.IdentityServerConstants.SecretTypes.SharedSecret,
                Value = secret
            });

            var client = new Client
            {
                AllowedGrantTypes = registration.GrantTypes.Select(grant => new ClientGrantType
                {
                    Id        = Guid.NewGuid().ToString(),
                    GrantType = grant
                }).ToList(),
                AccessTokenLifetime          = _defaultValues.AccessTokenLifetime,
                AbsoluteRefreshTokenLifetime = _defaultValues.AbsoluteRefreshTokenLifetime,
                AccessTokenType             = (int)_defaultValues.AccessTokenType,
                AllowOfflineAccess          = registration.ApplicationType == "web" && registration.GrantTypes.Contains("refresh_token"),
                AllowAccessTokensViaBrowser = registration.ApplicationType == "web",
                AllowedScopes = new List <ClientScope> {
                    new ClientScope
                    {
                        Id    = Guid.NewGuid().ToString(),
                        Scope = "openid"
                    },
                    new ClientScope
                    {
                        Id    = Guid.NewGuid().ToString(),
                        Scope = "profile"
                    },
                    new ClientScope
                    {
                        Id    = Guid.NewGuid().ToString(),
                        Scope = "address"
                    },
                    new ClientScope
                    {
                        Id    = Guid.NewGuid().ToString(),
                        Scope = "email"
                    },
                    new ClientScope
                    {
                        Id    = Guid.NewGuid().ToString(),
                        Scope = "phone"
                    }
                },
                AllowRememberConsent             = _defaultValues.AllowRememberConsent,
                AllowPlainTextPkce               = _defaultValues.AllowPlainTextPkce,
                AlwaysIncludeUserClaimsInIdToken = _defaultValues.AlwaysIncludeUserClaimsInIdToken,
                AlwaysSendClientClaims           = _defaultValues.AlwaysSendClientClaims,
                AuthorizationCodeLifetime        = _defaultValues.AuthorizationCodeLifetime,
                BackChannelLogoutSessionRequired = !string.IsNullOrEmpty(_defaultValues.BackChannelLogoutUri),
                BackChannelLogoutUri             = _defaultValues.BackChannelLogoutUri,
                ClientClaimsPrefix               = _defaultValues.ClientClaimsPrefix,
                ClientName         = clientName,
                ClientSecrets      = sercretList,
                ClientUri          = registration.ClientUris?.FirstOrDefault(u => u.Culture == null)?.Value ?? registration.ClientUris?.FirstOrDefault()?.Value,
                ConsentLifetime    = _defaultValues.ConsentLifetime,
                Description        = _defaultValues.Description,
                DeviceCodeLifetime = _defaultValues.DeviceCodeLifetime,
                Enabled            = true,
                EnableLocalLogin   = _defaultValues.EnableLocalLogin,
                FrontChannelLogoutSessionRequired = !string.IsNullOrEmpty(_defaultValues.FrontChannelLogoutUri),
                FrontChannelLogoutUri             = _defaultValues.FrontChannelLogoutUri,
                Id = registration.Id,
                IdentityTokenLifetime = _defaultValues.IdentityTokenLifetime,
                IncludeJwtId          = _defaultValues.IncludeJwtId,
                LogoUri             = registration.LogoUris?.FirstOrDefault(u => u.Culture == null)?.Value ?? registration.LogoUris?.FirstOrDefault()?.Value,
                NonEditable         = false,
                PairWiseSubjectSalt = _defaultValues.PairWiseSubjectSalt,
                ProtocolType        = _defaultValues.ProtocolType,
                RedirectUris        = registration.RedirectUris.Select(u => new ClientUri
                {
                    Id   = Guid.NewGuid().ToString(),
                    Kind = UriKinds.Cors | UriKinds.Redirect,
                    Uri  = u
                }).ToList(),
                RefreshTokenExpiration = (int)_defaultValues.RefreshTokenExpiration,
                RefreshTokenUsage      = (int)_defaultValues.RefreshTokenUsage,
                RequireClientSecret    = false,
                RequireConsent         = _defaultValues.RequireConsent,
                RequirePkce            = false,
                Resources = registration.ClientNames.Where(n => n.Culture != null)
                            .Select(n => new ClientLocalizedResource
                {
                    Id           = Guid.NewGuid().ToString(),
                    CultureId    = n.Culture,
                    ResourceKind = EntityResourceKind.DisplayName,
                    Value        = n.Value
                })
                            .Union(registration.ClientUris != null ? registration.ClientUris.Where(u => u.Culture != null).Select(u => new ClientLocalizedResource
                {
                    Id           = Guid.NewGuid().ToString(),
                    CultureId    = u.Culture,
                    ResourceKind = EntityResourceKind.ClientUri,
                    Value        = u.Value
                }) : new List <ClientLocalizedResource>(0))
                            .Union(registration.LogoUris != null ? registration.LogoUris.Where(u => u.Culture != null).Select(u => new ClientLocalizedResource
                {
                    Id           = Guid.NewGuid().ToString(),
                    CultureId    = u.Culture,
                    ResourceKind = EntityResourceKind.LogoUri,
                    Value        = u.Value
                }) : new List <ClientLocalizedResource>(0))
                            .Union(registration.PolicyUris != null ? registration.PolicyUris.Where(u => u.Culture != null).Select(u => new ClientLocalizedResource
                {
                    Id           = Guid.NewGuid().ToString(),
                    CultureId    = u.Culture,
                    ResourceKind = EntityResourceKind.PolicyUri,
                    Value        = u.Value
                }) : new List <ClientLocalizedResource>(0))
                            .Union(registration.TosUris != null ? registration.TosUris.Where(u => u.Culture != null).Select(u => new ClientLocalizedResource
                {
                    Id           = Guid.NewGuid().ToString(),
                    CultureId    = u.Culture,
                    ResourceKind = EntityResourceKind.TosUri,
                    Value        = u.Value
                }) : new List <ClientLocalizedResource>(0))
                            .ToList(),
                Properties = new List <ClientProperty>
                {
                    new ClientProperty
                    {
                        Id    = Guid.NewGuid().ToString(),
                        Key   = "applicationType",
                        Value = registration.ApplicationType
                    }
                }.Union(registration.Contacts != null ? new List <ClientProperty>
                {
                    new ClientProperty
                    {
                        Id    = Guid.NewGuid().ToString(),
                        Key   = "contacts",
                        Value = string.Join("; ", registration.Contacts)
                    }
                } : new List <ClientProperty>(0))
                .ToList(),
                SlidingRefreshTokenLifetime      = _defaultValues.SlidingRefreshTokenLifetime,
                UpdateAccessTokenClaimsOnRefresh = _defaultValues.UpdateAccessTokenClaimsOnRefresh,
                UserCodeType    = _defaultValues.UserCodeType,
                UserSsoLifetime = _defaultValues.UserSsoLifetime,
                PolicyUri       = registration.TosUris?.FirstOrDefault(u => u.Culture == null)?.Value ?? registration.TosUris?.FirstOrDefault()?.Value,
                TosUri          = registration.TosUris?.FirstOrDefault(u => u.Culture == null)?.Value ?? registration.TosUris?.FirstOrDefault()?.Value,
            };

            client.RegistrationToken = Guid.NewGuid();

            await _clientStore.CreateAsync(client).ConfigureAwait(false);

            registration.RegistrationToken    = client.RegistrationToken.ToString();
            registration.RegistrationUri      = $"{discovery["registration_endpoint"]}/{client.Id}";
            registration.JwksUri              = discovery["jwks_uri"].ToString();
            registration.ClientSecret         = secret;
            registration.ClientSecretExpireAt = 0;

            return(registration);
        }