Service Fabric和Identity Server 4

时间:2016-11-23 14:11:14

标签: azure-service-fabric identityserver4

我是身份服务器的新手,并且已经在我的开发中进行了设置,它主要在使用单个节点时起作用。如果我切换到5个节点,它有时会工作,有时它不会。

我在控制器上有Authorize属性,它扩展了一个基本控制器,它具有一个从用户声明中获取用户角色的功能。

protected string GetUserRole()
    {
        var roleClaim = User.Claims.SingleOrDefault(c => c.Type == "role");

        if (roleClaim == null)
        {
            throw new ArgumentNullException("Cant find role claim on: " + Request.Host.Host);
        }
        else
        {
            return roleClaim.Value;
        }
   }

当我进行授权调用(在标头中有一个标记)时,发生的事情是,当崩溃时,roleClaim为null。然后我尝试拨打电话,但这次未经授权并得到了相同的结果。

这是我api的配置:

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = "http://localhost:19081/App/Identity",
            ScopeName = "api1",
            RequireHttpsMetadata = false,
            AutomaticAuthenticate = true
        });

身份服务器的配置:

var cert = new X509Certificate2(Path.Combine(_contentRoot, "damienbodserver.pfx"), "");
        services.AddDeveloperIdentityServer()
            .SetSigningCredential(cert)
            .AddInMemoryScopes(Scopes.Get())
            .AddInMemoryClients(Clients.Get())
            .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
            .AddProfileService<ProfileService>();

        services.AddMvc();

我的客户:

public static IEnumerable<Client> Get()
    {
        return new[]
        {
            new Client()
            {
                ClientId = "myapi",
                ClientSecrets = new List<Secret>
                {
                    new Secret("secret".Sha256())
                },
                ClientName = "My Beautiful Api",
                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                AllowAccessTokensViaBrowser = true,
                RequireConsent = false,
                AllowedScopes = {
                    "openid",
                    "api1"
                },
                AllowedCorsOrigins = new List<string> {
                    "*"
                },
                Enabled = true
            }
        };
    }
}

范围:

public static IEnumerable<Scope> Get()
    {
        return new List<Scope>
        {
            StandardScopes.OpenId,
            StandardScopes.ProfileAlwaysInclude,
            StandardScopes.EmailAlwaysInclude,
            StandardScopes.OfflineAccess,
            StandardScopes.RolesAlwaysInclude,
            new Scope
            {
                Name = "api1",
                DisplayName = "API 1",
                Description = "API 1 features and data",
                Type = ScopeType.Resource,
                ScopeSecrets = new List<Secret>
                {
                    new Secret("secret".Sha256())
                },
                Claims = new List<ScopeClaim>
                {
                    new ScopeClaim("role")
                }
            }
        };
    }

我试过阅读文档,但似乎缺少很多,所以我的问题首先是:

为什么roleClaim有时只存在?

第二:

为什么Identity Server在未经授权的情况下不会响应401状态代码而我在控制器上有[授权]?

2 个答案:

答案 0 :(得分:0)

当idsrv位于负载均衡器后面的多个节点上时,后续请求将发送到不同的节点,您需要为其提供一致性。

所有实例均应至少为数据库实现IPersistedGrantStore( AddPersistedGrantStore )。

我猜他们也应该具有相同的证书( AddSigningCredential )和ASP密钥库( AddDataProtection )。 我建议您从distributed cache and data protection开始。您也可以临时实施IPersistedGrantStore like here

答案 1 :(得分:-1)

如果您打算将Service Fabric和Identity Server用作服务,则可能会遇到有关状态和内存存储的问题。与传统的单片架构方法相比,利用Service Fabric将提供各种优势。如果您还没有,我会确保您专注于提供无状态方法,真正阅读有关JSON Web令牌(JWT)的文档。这将允许您通过加密和解密此令牌来提供灵活的解决方案,以提供或读取关键的用户/过期信息。