Asp.net core ASPNET CORE InvalidOperationException:无法重定向到授权端点,配置可能丢失或无效
我收到错误InvalidOperationException:无法重定向到授权端点,配置可能丢失或无效 在此之前,我有一个错误,上面写着“缺少权限、元地址、配置或配置管理器”。我觉得这很重要。所以,我所拥有的:Asp.net core ASPNET CORE InvalidOperationException:无法重定向到授权端点,配置可能丢失或无效,asp.net-core,openid,Asp.net Core,Openid,我收到错误InvalidOperationException:无法重定向到授权端点,配置可能丢失或无效 在此之前,我有一个错误,上面写着“缺少权限、元地址、配置或配置管理器”。我觉得这很重要。所以,我所拥有的: /// <summary> /// Configures OpenID Connect authentication. /// </summary> /// <param name="
/// <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;
}
//
///配置OpenID连接身份验证。
///
///物体。
///这个。
公共静态IPersonalIdentityServerBuilder AddOpenIdConnectAuthentication(此IPersonalIdentityServerBuilder)
{
IServiceCollection_services=builder?.services??抛出新的ArgumentNullException(nameof(builder));
_服务
.AddAuthentication(opt=>opt.DefaultChallengeScheme=OpenIdConnectDefaults.AuthenticationScheme)
.AddOpenIdConnect();
_services.AddSingleton();
返回生成器;
}
然后我有一个配置选项的类
/// <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,
};
}
}
//
///的配置类。
///
内部类配置OpenIDConnectOptions:
IPostConfigureOptions
{
///
///我的个人OpenId选项。
///
私有只读选项_openIdOptions;
///
///具有OpenId身份验证事件的类。
///
私有只读OpenIdNotificationEventHandler\u eventHandler;
///
///初始化类的新实例。
///
///个人OpenId选项。
///OpenId身份验证事件的处理程序。
公共配置OpenIDConnectOptions(
IOptions openIdOptions,
OpenIdNotificationEventHandler(事件处理程序)
{
这._openIdOptions=openIdOptions??抛出新的ArgumentNullException(nameof(openIdOptions));
这._eventHandler=eventHandler??抛出新的ArgumentNullException(nameof(eventHandler));
}
///
///配置选项。
///
///名字。
///要配置的选项。
public void PostConfigure(字符串名称、OpenIdConnectOptions选项)
{
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=新的TokenValidationParameters
{
NameClaimType=JwtClaimTypes.Name,
RoleClaimType=JwtClaimTypes.Role,
};
//使id_令牌更小
options.GetClaimsFromUserInfoEndpoint=true;
//回调路径需要相对URL。这是Microsoft在.NET核心版本中所做的更改。但是,
//支持绝对URL。尝试将回调路径设置为绝对URL将导致引发异常。
//因此,我们现在将支持其中一种。如果它是一个绝对URL,那么它将在RedirectToIdentityProvider中设置
//如果它是一个相对URL,我们将在这里设置它。
如果(!\u opt.SetLowLevelRedirectUri){options.CallbackPath=\u opt.RedirectUri;}
如果(!\u opt.setLowLevel PostLogoutRedectUri){options.SignedOutCallbackPath=\u opt.PostLogoutRedectUri;}
_opt.Scopes.ForEach(s=>options.Scope.Add);
options.Events=新的OpenIdConnectEvents
{
OnAuthorizationCodeReceived=此。\u eventHandler.AuthorizationCodeReceived,
OnTokenResponseReceived=this.\u eventHandler.TokenResponseReceived,
OnTokenValidated=this.\u eventHandler.TokenValidated,
OnRedirectToIdentityProvider=此。\u eventHandler.RedirectToIdentityProvider,
};
}
}
经过大量的反编译和谷歌搜索,我最终在上面定义的AddOpenIdConnectAuthentication方法中添加了以下内容。这是Microsofts针对开放ID设置的配置
_services.AddSingleton<IPostConfigureOptions<OpenIdConnectOptions>, OpenIdConnectPostConfigureOptions>();
\u services.AddSingleton();
这解决了这个问题,但现在我有一个在标题中。从源代码看,似乎是因为IssuerAddress为空。我一辈子都不明白为什么。此外,我不明白为什么我需要为Microsofts自己的类添加配置才能让它工作
我知道我可以找到解决办法,但我不认为这会这么难
如果有人有任何想法,我们将非常欢迎
更新
我想扩展我发现的一些东西,由于我花在这上面的时间,这些东西最终改变了。我想特别感谢下面的各位
我最终从使用IPostConfigure
改为使用IConfigure
。执行此操作时,似乎要通过iconfigureNameOptions的Configure(name,options)
,而不是IConfigureOptions的Configure(options)
。因此,我实现了这两种方法。我不知道你是否必须这样做,因为我没有尝试所有可能的组合,但这样做很有效
使用IPostConfigurationOptions
时,必须在调用AddOpenIdConnect()
之前将其添加到服务集合中
我还删除了手动注册MicrosoftsIPostConfigreOptions的行,这是不需要的。元数据地址应该是以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位于HTTP上,则可能需要
options.RequireHttpsMetadata = false;