感觉我在IdentityServer或客户端配置中遗漏了一些东西。我已经从ASP成员资格升级到Identity,然后已经转而使用带有IdentityServer的SSO。我可以通过Identity Server登录并返回客户端应用程序,我可以在其中调试并查看UserKey和声明,但我看不到声明中的任何角色和user.IsInRole(roleName)始终返回false。
IdentityServer配置:
public class Scopes
{
public static IEnumerable<Scope> Get()
{
return new Scope[]
{
StandardScopes.OpenId,
StandardScopes.Profile,
StandardScopes.Email,
StandardScopes.AllClaims,
StandardScopes.Roles,
StandardScopes.OfflineAccess,
new Scope
{
IncludeAllClaimsForUser = true,
Name = "read",
DisplayName = "Read data",
Type = ScopeType.Resource,
Emphasize = false,
},
new Scope
{
Name = "write",
DisplayName = "Write data",
Type = ScopeType.Resource,
Emphasize = false, //true
},
new Scope
{
Name = "forbidden",
DisplayName = "Forbidden scope",
Type = ScopeType.Resource,
Emphasize = false //true
}
};
}
}
public static class Clients
{
public static IEnumerable<Client> Get()
{
return new[]
{
new Client
{
Enabled = true,
ClientName = "MVC Client",
ClientId = "implicitclient",
Flow = Flows.Implicit,
AllowedScopes = new List<string> {
Constants.StandardScopes.OpenId,
Constants.StandardScopes.Profile,
Constants.StandardScopes.Email,
Constants.StandardScopes.Roles
},
RedirectUris = new List<string>
{
"https://localhost:44301/"
}
},
new Client
{
Enabled = true,
ClientName = "MyClientName",
ClientId = "myclientName",
Flow = Flows.Implicit,
AllowedScopes = new List<string> {
Constants.StandardScopes.OpenId,
Constants.StandardScopes.Profile,
Constants.StandardScopes.Email,
Constants.StandardScopes.Roles,
"read",
"write"
},
RedirectUris = new List<string>
{
"https://localhost:44302/"
}
}
};
}
}
public static IdentityServerServiceFactory Configure()
{
var factory = new IdentityServerServiceFactory();
var scopeStore = new InMemoryScopeStore(Scopes.Get());
factory.ScopeStore = new Registration<IScopeStore>(scopeStore);
var clientStore = new InMemoryClientStore(Clients.Get());
factory.ClientStore = new Registration<IClientStore>(clientStore);
factory.CorsPolicyService = new Registration<ICorsPolicyService>(new DefaultCorsPolicyService { AllowAll = true });
return factory;
}
客户端配置(MVC 5应用程序):
public void Configuration(IAppBuilder app)
{
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = "myclientname",
Authority = "https://localhost:44300/core", //Constants.BaseAddress, //STS Server Address
RedirectUri = "https://localhost:44302/", //This site
ResponseType = "id_token token",
//Scope = "openid email write",
Scope = "openid email roles",
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = async n =>
{
var token = n.ProtocolMessage.AccessToken;
// persist access token in cookie
if (!string.IsNullOrEmpty(token))
{
n.AuthenticationTicket.Identity.AddClaim(
new Claim("access_token", token));
}
}
}
});
}
}
任何建议都非常感谢!
答案 0 :(得分:1)
范围角色只有一个范围声明,&#34; 角色&#34;,此范围声明具有以下属性&#34; AlwaysIncludeinIdToken &# 34;设置为false,这意味着如果您要求&#34; 令牌&#34; response_type 它不会被隐式发送。 (这是我的理解,也许不那么简单)
首先尝试删除&#34; 令牌&#34; response_type ,只询问&#34; openid &#34;和&#34; 角色&#34;范围。如果这解决了问题,那么就不会隐式发送它们。
您需要询问剩余的声明,即未通过&#34; id_ 令牌&#34;请求,明确。您需要使用您获得的 access_token 和&#34; userinfo &#34;端点。 (作为正确使用端点的文档中的技巧搜索)
编辑:UserInfo Documentation,这对于如何调用 Userinfo 端点非常有用。