我试图了解在构建OpenIDConnectOptions时如何使用强类型。
我知道我们可以使用POCO类和IOptions实现为appsettings和其他项实现强类型,并从Controller构造函数中访问它们但是在这里,我的问题出现在控制器部分之前。在运行时starup失败。
首先,我使用startup.configureservice:
services.AddAzureADOpenIDAuthentication(Configuration);
我为AddAzureADOpenIDAuthentication提供了IServiceCollection的扩展方法,如:
services.Configure<AzureADOptions>(configuration.GetSection("Authentication:AzureAd"));
services.AddSingleton<IOptionsMonitor<OpenIdConnectOptions>, AzureADOpenIdConnectOptionsSetup>();
services.AddAuthentication(auth =>
{
auth.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
auth.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie().AddOpenIdConnect();
return services;
最后我将AzureADOpenIdConnectOptionsSetup与IOptionsMonitor一起实现,如下所示:
public class AzureADOpenIdConnectOptionsSetup : IOptionsMonitor<OpenIdConnectOptions>
{
public OpenIdConnectOptions CurrentValue { get; set; }
public AzureADOpenIdConnectOptionsSetup(IOptionsMonitor<AzureADOptions> azureADOptions)
{
CurrentValue = new OpenIdConnectOptions();
CurrentValue.ClientId = azureADOptions.CurrentValue.ClientId;
CurrentValue.Authority = azureADOptions.CurrentValue.Authority;
CurrentValue.CallbackPath = azureADOptions.CurrentValue.CallbackPath;
}
public OpenIdConnectOptions Get(string name)
{
return CurrentValue;
}
public IDisposable OnChange(Action<OpenIdConnectOptions, string> listener)
{
throw new NotImplementedException();
}
}
当我运行此代码时,它命中了构造函数和OpenIdConnectOptions获取两次并通过构造函数级别的断点,我检查设置是否正确地从azureADOptions传输到OpenIdConnectOptions CurrentValue。 不过,我收到一条错误消息(在我按下登录之前,它意味着自己启动)
InvalidOperationException:向OpenIdConnectOptions提供Authority,MetadataAddress,Configuration或ConfigurationManager
我不确定,我是否正确实现了OpenIdConnectOptions Get(字符串名称)。 还有一个疑问是,我应该如何实现OnChange(Action侦听器)来监听appsettings.json的运行时更改
答案 0 :(得分:1)
要返回OpenIdConnectOptions
,您需要初始化ConfigurationManager,以及如下的简单代码:
public static class AzureAdAuthenticationBuilderExtensions
{
public static AuthenticationBuilder AddAzureADOpenIDAuthentication(this AuthenticationBuilder builder, IConfiguration configuration)
{
builder.Services.Configure<AzureAdOptions>(configuration.GetSection("AzureAd"));
builder.Services.AddSingleton<IOptionsMonitor<OpenIdConnectOptions>, AzureADOpenIdConnectOptionsSetup>();
builder.Services.AddAuthentication(auth =>
{
auth.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
auth.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddOpenIdConnect();
return builder;
}
public class AzureADOpenIdConnectOptionsSetup : IOptionsMonitor<OpenIdConnectOptions>
{
public OpenIdConnectOptions CurrentValue { get; set; }
private IDataProtectionProvider _dataProtectionProvider;
public AzureADOpenIdConnectOptionsSetup(IOptionsMonitor<AzureAdOptions> azureADOptions,IDataProtectionProvider dataProtectionProvider)
{
_dataProtectionProvider = dataProtectionProvider;
CurrentValue = new OpenIdConnectOptions
{
ClientId = azureADOptions.CurrentValue.ClientId,
Authority = $"{azureADOptions.CurrentValue.Instance}{azureADOptions.CurrentValue.TenantId}",
CallbackPath = azureADOptions.CurrentValue.CallbackPath
};
}
public OpenIdConnectOptions Get(string name)
{
OpenIdConnectPostConfigureOptions op = new OpenIdConnectPostConfigureOptions(_dataProtectionProvider);
op.PostConfigure(name, CurrentValue);
return CurrentValue;
}
public IDisposable OnChange(Action<OpenIdConnectOptions, string> listener)
{
throw new NotImplementedException();
}
}
}