aspnet core 2.0的强类型OpenIdConnectOptions

时间:2017-08-19 06:00:41

标签: asp.net-core-identity asp.net-core-2.0

我试图了解在构建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的运行时更改

1 个答案:

答案 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();
        }
    }        
}