首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >控制允许使用单点登录identityServer4登录到客户端的用户

控制允许使用单点登录identityServer4登录到客户端的用户
EN

Stack Overflow用户
提问于 2018-05-08 14:59:45
回答 2查看 982关注 0票数 0

IdentityServer4提供了单点登录体验和STS功能。根据OAuth OpenId连接对客户端进行验证后,单点登录即可工作。所以如果用户的身份是基于cookie的。

我想知道是否有人为多租户方式实现了这一点,以限制用户只允许一组客户端(这意味着SSO仍然在它们之间工作-让我们将组称为租户)。当涉及到不允许的用户和客户端时,identity server应将其带到登录屏幕。

启动时的配置-用户存储的AspNetIdentity

代码语言:javascript
复制
     services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddUserManager<CustomUserManager>()
                .AddSignInManager<CustomSignInManager>()
                .AddDefaultTokenProviders();
            //TODO Tenant based cookie SaasKit/Finbuckle
            services.ConfigureApplicationCookie(cookieOptions =>
            {
                cookieOptions.Cookie = new Microsoft.AspNetCore.Http.CookieBuilder
                {
                    Name="Tenant_Cookie"
                };
            });   

 var builder = services.AddIdentityServer(options =>
                {
                    options.Events.RaiseErrorEvents = true;
                    options.Events.RaiseInformationEvents = true;
                    options.Events.RaiseFailureEvents = true;
                    options.Events.RaiseSuccessEvents = true;
                }).AddSigningCredential(GetSigningCertificate("my", "a7 e2 f5 f7 9a b8 8c 86 2c 37 f5 22 1b ea 8c 19 b1 58 99 3c", true))                  
                .AddResponseGenerators()
                .AddCustomAuthorizeRequestValidator<TenantAuthorizeRequestValidator>()
                .AddCustomTokenRequestValidator<TenantTokenRequestValidator>()
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryClients(Config.GetClients())
                .AddProfileService<CustomProfileService>()
                .AddAspNetIdentity<ApplicationUser>();

租户令牌请求验证器-验证用户和客户端

代码语言:javascript
复制
 public class TenantTokenRequestValidator : ICustomTokenRequestValidator
{
    HttpContext _context;
    IClientService _clientService;
    public TenantTokenRequestValidator(IHttpContextAccessor contextAccessor, IClientService clientService)
    {
        _context = contextAccessor.HttpContext;
        _clientService = clientService;
    }

    public Task ValidateAsync(CustomTokenRequestValidationContext context)
    {
        if (!context.Result.IsError)
        {
            //AuthorizationCode authorization_code
            if (context.Result.ValidatedRequest.UserName!=null && 
                !_clientService.IsValidUser(context.Result.ValidatedRequest.Client.ClientId,context.Result.ValidatedRequest.UserName))
            {
                context.Result.IsError = true;
                context.Result.Error = "UnauthorizedUser";
            }
        }

        return Task.CompletedTask;
    }
}

租户授权请求验证器-验证客户端和租户

代码语言:javascript
复制
 public class TenantAuthorizeRequestValidator : ICustomAuthorizeRequestValidator
{
    HttpContext _context;
    ITenantService _tenantService;
    public TenantAuthorizeRequestValidator(IHttpContextAccessor contextAccessor,ITenantService tenantService)
    {
        _context = contextAccessor.HttpContext;
        _tenantService = tenantService;
    }
    public Task ValidateAsync(CustomAuthorizeRequestValidationContext context)
    {
        if (!context.Result.IsError)
        {
            var tenant = context.Result.ValidatedRequest.GetTenant();
            if (!string.IsNullOrEmpty(tenant))
            {                  
                if (!_tenantService.IsValidClient(tenant,context.Result.ValidatedRequest.ClientId))
                {
                    context.Result.IsError = true;
                    context.Result.Error = OidcConstants.AuthorizeErrors.UnauthorizedClient;
                }
                context.Result.ValidatedRequest.ClientClaims.Add(new Claim(
                TenantConstants.TokenKey,
                tenant,
                IdentityServerConstants.ClaimValueTypes.Json));
            }             


            //Find a way to respond the error message
        }

        return Task.CompletedTask;
    }
}

数据库就像

代码语言:javascript
复制
public static Dictionary<string, string[]> TenantClients()
    {
        return new Dictionary<string, string[]>()
        {
            { "tenant1",new string[]{ "tenant1.mvc","tenant1.mvc2" } },
            { "tenant2",new string[]{ "tenant2.mvc" } }
        };
    }
public static Dictionary<string, string[]> ClientUsers()
    {
        return new Dictionary<string, string[]>()
        {
            { "tenant1.mvc", new string[]{"alice","bob"} },
            { "tenant1.mvc2", new string[]{"alice","bob"} },
            { "tenant2.mvc", new string[]{"alice"}}
        };
    }

我正在用上面的代码验证客户端和租户以及客户端和用户。然而,无法实现基于租户的cookie,因此不同的登录将使用不同的cookie在同一浏览器会话上工作。Saaskit似乎不能很好地与aspnet core 2.0一起工作,没有找到一种使用finbuckle的方法。

问题-如何使用租户设置cookie名称?基于上下文ACR值从请求中解析。这种方法有效吗?

EN

回答 2

Stack Overflow用户

发布于 2018-07-09 15:01:56

我们最终向用户帐户添加了一组额外的客户端特定声明,并根据传入的声明设置授权策略。

例如:

Api资源希望根据令牌中的作用域限制访问,这对于客户端验证和用户验证都很好,它在令牌中查找特定的声明并提供访问权限。

使用上面的方法,我们必须维护通过UI来的用户的声明,对于没有用户而访问服务器到服务器的其他客户端,到客户端声明中。

虽然这不是最好的方法,但这解决了我们目前的需求。

票数 0
EN

Stack Overflow用户

发布于 2020-05-19 00:43:13

我们的方法是,您需要在启动时创建几个AddCookie,每个租户使用自己的方案名称创建一个。

然后,在ICustomAuthorizeRequestValidator中,将方案名称设置为与为租户创建的方案相同(因此,您可能必须定义一个通用格式,如: Cookies-MyTenantId1或Cookies-MyTenantId2)。这样就为每个租户创建了一个不同的cookie。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50227702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档