我是身份服务器的新手,并且已经在我的开发中进行了设置,它主要在使用单个节点时起作用。如果我切换到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状态代码而我在控制器上有[授权]?
答案 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)的文档。这将允许您通过加密和解密此令牌来提供灵活的解决方案,以提供或读取关键的用户/过期信息。