Reputation:
Feel like I'm missing something in the IdentityServer or client configuration. I've upgraded from ASP membership to Identity, then have switched out to using SSO with IdentityServer. I can login via Identity Server and am returned to the client app where I can debug and see the UserKey and claims, but I can't see any roles in the claims and user.IsInRole(roleName) always returns false.
The IdentityServer configuration:
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;
}
The Client configuration (MVC 5 app):
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));
}
}
}
});
}
}
Any suggestions much appreciated!
Upvotes: 2
Views: 2171
Reputation: 26
The scope roles has only one scope claim, "role", this scope claim has the following property "AlwaysIncludeinIdToken" set to false, this means if you ask for the "token" response_type it won't be sent implicitly. (This is my understanding, maybe is not that simple)
First try to remove the "token" response_type, and ask only for the "openid" and "roles" scope. If this solves the problem, then it is not sending them implicitly.
You need to ask for the remaining claims, i.e. those not sent in the "id_token" request, explicitly. You need to use the access_token you got and the "userinfo" endpoint. (As a tip search in the documentation for the correct use of the endpoints)
EDIT:UserInfo Documentation, this maybe usefull on how to call the Userinfo endpoint.
Upvotes: 1