AS PNET CORE InvalidOperationException: невозможно выполнить перенаправление на конечную точку авторизации, конфигурация может отсутствовать или недействительна - PullRequest
0 голосов
/ 06 августа 2020

Я получаю сообщение об ошибке InvalidOperationException: невозможно перенаправить на конечную точку авторизации, конфигурация может отсутствовать или недействительна. диспетчер конфигурации отсутствует ". Я считаю это важным. Итак, что у меня было:

        /// <summary>
        /// Configures OpenID Connect authentication.
        /// </summary>
        /// <param name="builder">The <see cref="IPersonalIdentityServerBuilder"/> object.</param>
        /// <returns>The <see cref="IPersonalIdentityServerBuilder"/>.</returns>
        public static IPersonalIdentityServerBuilder AddOpenIdConnectAuthentication(this IPersonalIdentityServerBuilder builder)
        {
                IServiceCollection _services = builder?.Services ?? throw new ArgumentNullException(nameof(builder));

            _services
                .AddAuthentication(opt => opt.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme)
                .AddOpenIdConnect();

            _services.AddSingleton<IPostConfigureOptions<OpenIdConnectOptions>, ConfigureOpenIdConnectOptions>();

            return builder;
        }

Затем у меня был следующий класс, который настраивает параметры

/// <summary>
/// Configuration class for the <see cref="OpenIdConnectOptions"/>.
/// </summary>
internal class ConfigureOpenIdConnectOptions : 
    IPostConfigureOptions<OpenIdConnectOptions>
{
    /// <summary>
    /// My personal OpenId options.
    /// </summary>
    private readonly IOptions<PersonalIentityServerOpenIdOptions> _openIdOptions;

    /// <summary>
    /// The class that has the events for OpenId authentication.
    /// </summary>
    private readonly OpenIdNotificationEventHandler _eventHandler;

    /// <summary>
    /// Initializes a new instance of the <see cref="ConfigureOpenIdConnectOptions"/> class.
    /// </summary>
    /// <param name="openIdOptions">The personal OpenId options.</param>
    /// <param name="eventHandler">The handler for OpenId authentication events.</param>
    public ConfigureOpenIdConnectOptions(
        IOptions<PersonalIdentityServerOpenIdOptions> openIdOptions,
        OpenIdNotificationEventHandler eventHandler)
    {
        this._openIdOptions = openIdOptions ?? throw new ArgumentNullException(nameof(openIdOptions));
        this._eventHandler = eventHandler ?? throw new ArgumentNullException(nameof(eventHandler));
    }

    /// <summary>
    /// Configures the options.
    /// </summary>
    /// <param name="name">The name.</param>
    /// <param name="options">The options to configure.</param>
    public void PostConfigure(string name, OpenIdConnectOptions options)
    {
        PersonalIdentityServerOpenIdOptions _opt = this._openIdOptions.Value;

        options.Authority = _opt.Authority;
        options.ClientId = _opt.ClientId;
        options.ClientSecret = _opt.Secret;
        options.MetadataAddress = "/" + ProtocolPath.Discovery;
        options.ProtocolValidator.RequireNonce = true;
        options.ResponseType = OpenIdConnectResponseType.Code;
        options.UsePkce = true;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = JwtClaimTypes.Name,
            RoleClaimType = JwtClaimTypes.Role,
        };

        // Keeps id_token smaller
        options.GetClaimsFromUserInfoEndpoint = true;

        // The callback paths require a relative URL. This was a change that Microsoft made in the .NET Core version. We, however,
        // support an absolute URL. Attempting to set the callback paths to an absolute URL will cause an exception to be thrown.
        // Therefore, we will now support either. If it's an absolute URL then it gets set in the RedirectToIdentityProvider
        // event. If it's a relative URL, we'll set it here.
        if (!_opt.SetLowLevelRedirectUri) { options.CallbackPath = _opt.RedirectUri; }
        if (!_opt.SetLowLevelPostLogoutRedirectUri) { options.SignedOutCallbackPath = _opt.PostLogoutRedirectUri; }

        _opt.Scopes.ForEach(s => options.Scope.Add(s));

        options.Events = new OpenIdConnectEvents
        {
            OnAuthorizationCodeReceived = this._eventHandler.AuthorizationCodeRecieved,
            OnTokenResponseReceived = this._eventHandler.TokenResponseReceived,
            OnTokenValidated = this._eventHandler.TokenValidated,
            OnRedirectToIdentityProvider = this._eventHandler.RedirectToIdentityProvider,
        };
    }
}

Я закончил после долгой декомпиляции и поиска в Google, добавил следующую строку в метод AddOpenIdConnectAuthentication, определенный выше. Это конфигурация Microsoft для настроек открытого идентификатора.

            _services.AddSingleton<IPostConfigureOptions<OpenIdConnectOptions>, OpenIdConnectPostConfigureOptions>();

Это решило эту проблему, но теперь у меня есть тот, который указан в заголовке. Если посмотреть на источник, это похоже на то, что IssuerAddress пуст. За всю жизнь не могу понять почему. Кроме того, я не понимаю, почему мне потребовалось добавить конфигурацию для собственного класса Microsoft, чтобы заставить его работать.

Я знаю, что могу как-то обойти это и, вероятно, найду обходной путь, но я просто не думайте, что это должно быть так сложно.

Если у кого-то есть какие-то мысли, они были бы очень рады.

Обновление

Я хотел бы подробнее остановиться на некоторых вещах что я нашел и в конечном итоге изменил из-за времени, которое я потратил на это. Я хочу особо поблагодарить { ссылка } ниже.

В итоге я перешел с IPostConfigure<OpenIdConnectOptions> на IConfigure<OpenIdConnectOptions>. При этом кажется, что go через Configure(name, options) для IConfigureNamedOptions<OpenIdConnectOptions>, а не Configure(options) для IConfigureOptions<OpenIdConnectOptions>. Благодаря этому я реализовал оба. Я не знаю, нужно ли вам это, потому что я не пробовал все возможные комбинации, но это сработало.

При использовании IPostConfigurationOptions<OpenIdConnectOptions> вы должны добавить его в службу collection перед звонком на AddOpenIdConnect().

Я также удалил строку для ручной регистрации Microsoft IPostConfigreOptions, в этом нет необходимости.

1 Ответ

1 голос
/ 06 августа 2020

Адрес метаданных должен быть абсолютным адресом, начинающимся с https: //, а не относительным URL-адресом, как в вашем коде:

   options.MetadataAddress = "/" + ProtocolPath.Discovery;

, тогда я немного запутался, почему вам нужно добавить свой собственный ConfigureOpenIdConnectOptions класс? Чтобы настроить openid-connect, я просто:

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
}).AddCookie(options =>
{
    options.LoginPath = "/User/Login";
    options.LogoutPath = "/User/Logout";
    options.AccessDeniedPath = "/User/AccessDenied";
}).AddMyTestOpenIdConnect(options =>
{
    options.Authority = "https://localhost:6001";
    options.ClientId = "authcodeflowclient";
    options.ClientSecret = "mysecret";
    options.ResponseType = "code";
    ...
});

Если URL-адрес MetaData находится на HTTP, вам может потребоваться установить

options.RequireHttpsMetadata = false;

Но если вы установите поле Authority, тогда я сомневаюсь, что вам нужно также установить MetaDataAddress.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...