使用ClaimsTransformation和DI来了解范围问题,以访问dbContext

时间:2018-08-15 18:30:42

标签: azure-active-directory asp.net-core-2.0 claims-based-identity

当前,我正在尝试在OnTokenValidated事件内实现ClaimsTransformation,并且遇到了范围界定问题。我收到的错误是:

  

System.InvalidOperationException:无法使用单例“ Microsoft.Extensions.Options.IConfigureOptions`1 [Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions]”中的作用域服务“ Microsoft.AspNetCore.Authentication.IClaimsTransformation”。

首先,这是我的服务注册。

services.AddAuthentication(sharedOptions =>
{
    sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAd(options => Configuration.Bind("AzureAd", options))
.AddCookie
    (cookie =>
    { 
        cookie.AccessDeniedPath = "/Error";
    });

// This sample uses an in-memory cache for tokens and subscriptions.
services.AddMemoryCache();
services.AddSession();

// Add application services.
//services.AddSingleton<IConfiguration>(Configuration);
services.AddSingleton<IGraphAuthProvider, GraphAuthProvider>();
services.AddTransient<IGraphSdkHelper, GraphSdkHelper>();

// DI for claims transformation
services.AddTransient<IClaimsTransformation, ClaimsTransformer>();

// DEBUG DB (local)
services.AddDbContext<TestContext>(options =>
 options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=TestContext;Trusted_Connection=True;MultipleActiveResultSets=true"));

接下来,我在AuthenticationBuilder中注册其他服务。

public static AuthenticationBuilder AddAzureAd(this AuthenticationBuilder builder, Action<AzureAdOptions> configureOptions)
{
    builder.Services.Configure(configureOptions);
    builder.Services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, ConfigureAzureOptions>();
    builder.AddOpenIdConnect();
    return builder;
}

在托管OpenIdConnectResponseType事件的AzureAdAuthenticationBuilderExtensions文件中,我传入了Claims主体。

},OnTokenValidated = async (context) =>
{
    // Pass in the claims principal to append ACLs
    await _claimsTransformer.TransformAsync(context.Principal);
}

这是我尝试通过DI访问dbContext的代码段,这会导致范围问题。

private readonly Test.Models.TestContext _dbContext;

public ClaimsTransformer(TestContext dbContext)
{
    _dbContext = dbContext;
}

我了解某个服务的总体问题取决于另一个使用寿命较短的服务,但是,我在线上跟踪了几种不同的资源,以使该实现陷入困境,但我不确定如何解决问题并允许访问ClaimsTransformation实现中的dbContext服务。我确实看到了完全不同的解决方案,这些解决方案根本不使用ClaimsTransformation,而是选择使用UserClaimsPrincipalFactory,尽管我不知道这是否是替代方案,或者实际上是当前鼓励实现此功能的方式

https://kevin-junghans.blogspot.com/2017/08/customizing-claims-for-authorization-in.html

此外,随时欢迎对代码和/或问题的任何批评,我总是感谢您有学习的机会!作为附录,我正在使用AzureAD,但没有能力在此Azure实例中创建组,因此我计划在数据库中创建用户条目并存储其关联角色以供应用程序中的授权使用。因此,一旦用户通过身份验证,就需要向主体追加新的要求,并且需要在我的数据库中执行查找以查看用户应具有的角色。

0 个答案:

没有答案