【问题标题】:Chose identity scheme based on url parameter根据 url 参数选择身份方案
【发布时间】:2020-12-16 16:11:19
【问题描述】:

我正在尝试根据请求参数选择 openId 授权方案。

我添加了两个 openIdConnect 架构:

.AddOpenIdConnect("abc", abcHandler)
.AddOpenIdConnect("def", defHandler);

一开始我覆盖了整个授权中间件并挑战:

if (authorizeResult.Challenged)
{
    if (valueFromQueryString.Contains("abc"))
    {
        await context.ChallengeAsync("abc");
    }
    else if (valueFromQueryString.Contains("def"))
    {
        await context.ChallengeAsync("def");
    }
}

但后来我注意到有一些政策,所以尝试使用这些政策。我创建了我的要求,然后添加了两个具有如下架构的策略:

services.AddAuthorization(options =>
    {
        options.AddPolicy("abc", policy =>
            {
                policy.AuthenticationSchemes.Add("abc");
                policy.Requirements.Add(new TenantSpecificRequirement("abc"));
                policy.RequireAuthenticatedUser();
             });
        options.AddPolicy("def", policy =>
            {
                policy.AuthenticationSchemes.Add("def");
                policy.Requirements.Add(new TenantSpecificRequirement("def"));
                policy.RequireAuthenticatedUser();
            });
    });

我意识到策略必须像这样绑定到控制器:

[Authorize(Policy = "abc")]
[Authorize(Policy = "def")]

这完全不是我需要的。现在最好的办法是根据 url 动态地将策略分配给控制器,但这似乎是不可能的,因为在应用程序启动时没有添加控制器过滤器。

那么还有其他方法吗?

【问题讨论】:

    标签: c# authorization identityserver4 idp


    【解决方案1】:

    好的,我通过覆盖AuthenticationSchemeProvider找到了解决方案

    public class SubdomainAuthenticationSchemeProvider : AuthenticationSchemeProvider
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
    
        public CustomAuthenticationSchemeProvider(
            IHttpContextAccessor httpContextAccessor,
            IOptions<AuthenticationOptions> options)
            : base(options)
        {
            this._httpContextAccessor = httpContextAccessor;
        }
    
        private Task<AuthenticationScheme> GetRequestSchemeAsync()
        {
            // Get the subdomain for the host the request came from. Assumes no WWW in the string.
            var subdomainName = _httpContextAccessor.HttpContext.Request.Host.Host.Split(new char[] { '.' })[0];
    
            return GetSchemeAsync(subdomainName);
        }
    
        public override async Task<AuthenticationScheme> GetDefaultAuthenticateSchemeAsync() => await GetRequestSchemeAsync() ;
    
        public override async Task<AuthenticationScheme> GetDefaultChallengeSchemeAsync() =>
            await GetRequestSchemeAsync() ??
            await base.GetDefaultChallengeSchemeAsync();
    
        public override async Task<AuthenticationScheme> GetDefaultForbidSchemeAsync() =>
            await GetRequestSchemeAsync() ??
            await base.GetDefaultForbidSchemeAsync();
    
        public override async Task<AuthenticationScheme> GetDefaultSignInSchemeAsync() =>
            await GetRequestSchemeAsync() ??
            await base.GetDefaultSignInSchemeAsync();
    
        public override async Task<AuthenticationScheme> GetDefaultSignOutSchemeAsync() =>
            await GetRequestSchemeAsync() ??
            await base.GetDefaultSignOutSchemeAsync();
    
    }
    

    在此之后,将其添加到 ConfigureServices 方法中

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    services.AddSingleton<IAuthenticationSchemeProvider, SubdomainAuthenticationSchemeProvider>();
    

    【讨论】:

      猜你喜欢
      • 2013-05-15
      • 2020-11-15
      • 1970-01-01
      • 1970-01-01
      • 2020-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-06
      相关资源
      最近更新 更多