Comment ajouter des revendications pour obtenir un jeton d'accès de IdentityServer3 à l'aide de ressources propriétaire de flux avec javascript client
J'utilise le propriétaire de la ressource de flux avec IdentityServer3 et envoyer obtenir de demande de jeton à l'identité du serveur jeton d'extrémité avec le nom d'utilisateur et le mot de passe dans le code javascript ci-dessous:
function getToken() {
var uid = document.getElementById("username").value;
var pwd = document.getElementById("password").value;
var xhr = new XMLHttpRequest();
xhr.onload = function (e) {
console.log(xhr.status);
console.log(xhr.response);
var response_data = JSON.parse(xhr.response);
if (xhr.status === 200 && response_data.access_token) {
getUserInfo(response_data.access_token);
getValue(response_data.access_token);
}
}
xhr.open("POST", tokenUrl);
var data = {
username: uid,
password: pwd,
grant_type: "password",
scope: "openid profile roles",
client_id: 'client_id'
};
var body = "";
for (var key in data) {
if (body.length) {
body += "&";
}
body += key + "=";
body += encodeURIComponent(data[key]);
}
xhr.setRequestHeader("Authorization", "Basic " + btoa(client_id + ":" + client_secret));
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(body);
}
Le jeton d'accès est retourné à partir du serveur de l'identité et de l'authentification de l'utilisateur. Puis-je utiliser ce jeton d'envoyer une requête à mon Api Web.
Le problème est que lorsque je vérifie si l'utilisateur est affecté à un rôle, je trouve que la demande n'existe pas.
[Authorize]
//GET api/values
public IEnumerable<string> Get()
{
var id = RequestContext.Principal as ClaimsPrincipal;
bool geek = id.HasClaim("role", "Geek"); //false here
bool asset_mgr = id.HasClaim("role", "asset_manager"); //false here
return new string[] { "value1", "value2" };
}
Ici est de savoir comment le client est défini dans le serveur d'identité.
new Client
{
ClientName = "Client",
ClientId = "client_id",
Flow = Flows.ResourceOwner,
RequireConsent = false,
AllowRememberConsent = false,
AllowedScopes = new List<string>
{
"openid",
"profile",
"roles",
"sampleApi"
},
AbsoluteRefreshTokenLifetime = 86400,
SlidingRefreshTokenLifetime = 43200,
RefreshTokenUsage = TokenUsage.OneTimeOnly,
RefreshTokenExpiration = TokenExpiration.Sliding,
ClientSecrets = new List<Secret>
{
new Secret("4C701024-0770-4794-B93D-52B5EB6487A0".Sha256())
},
},
et c'est de cette façon l'utilisateur est défini:
new InMemoryUser
{
Username = "bob",
Password = "secret",
Subject = "1",
Claims = new[]
{
new Claim(Constants.ClaimTypes.GivenName, "Bob"),
new Claim(Constants.ClaimTypes.FamilyName, "Smith"),
new Claim(Constants.ClaimTypes.Role, "Geek"),
new Claim(Constants.ClaimTypes.Role, "Foo")
}
}
Comment puis-je ajouter des réclamations à l'access_token dans ce cas? Merci beaucoup!
OriginalL'auteur Yang Zhang | 2015-11-26
Vous devez vous connecter pour publier un commentaire.
Je viens de passer un moment en pensant cela par moi-même. @leastprivilege commentaire de Yang de la réponse qu'avait la moindre idée, cette réponse est juste en expansion.
C'est tout de la façon dont les oAuth et OIDC spécifications évolué, ce n'est pas un artefact de IdentityServer (qui est génial).
Tout d'abord, voici un assez décent à la discussion des différences entre l'identité des jetons et jetons d'accès: https://github.com/IdentityServer/IdentityServer3/issues/2015 qui est intéressant à lire.
Avec des Ressources Propriétaire de flux, comme vous le faites, vous pourrez toujours obtenir un Jeton d'Accès. Par défaut et par la spec, vous ne devriez pas inclure les revendications dans ce jeton (voir le lien ci-dessus pour expliquer pourquoi). Mais, dans la pratique, il est très agréable quand vous le pouvez; il vous permet d'économiser des efforts supplémentaires sur le client et le serveur.
Ce Leastprivilege est allusion, c'est que vous avez besoin pour créer une étendue, quelque chose comme ceci:
Et puis il vous faudra demander à la portée lorsque vous demandez pour le jeton. I. e. votre ligne
scope: "openid profile roles",
devrait changer pourscope: "member",
(eh bien, je dis que les étendues de jouer un double rôle ici, aussi loin que je peux voir - ils sont aussi une forme de contrôle, à savoir le client demande pour certaines étendues et peut être rejetée si elle n'est pas permis à ceux qui, mais c'est un autre sujet).De noter l'importance de la ligne qui m'a échappé pendant un certain temps, ce qui est
Type = ScopeType.Resource
(parce que les Jetons d'Accès sont sur le contrôle d'accès aux ressources). Cela signifie qu'il va s'appliquer à Jetons d'Accès et les allégations indiquées seront inclus dans le jeton (je pense que, éventuellement, contre les spec mais merveilleusement).Enfin, dans mon exemple, j'ai inclus à la fois des revendications particulières ainsi que
IncludeAllClaimsForUser
ce qui est évidemment ridicule, mais je voulais juste vous montrer quelques options.Dans mon application, je me retrouve avec une solution à ne mettre allégations génériques dans le champ d'application et de laisser le client demande de faire une demande distincte à une api de service pour connaître les capacités (réclamations) de l'utilisateur.
oui, techniquement, les jetons d'accès ne sont pas destinées à contenir des revendications comme les noms, donc, techniquement, vous êtes censé recevoir séparément. C'est juste gênant. Et oui, cette solution permettra de donner à chaque utilisateur de leurs revendications personnelles.
Quelqu'un sait pourquoi cela ne fonctionne pas dans IdentityServer4?
OriginalL'auteur Frans
Je trouve que je peux réaliser cela en remplaçant la valeur par défaut IClaimsProvider de IdentityServerServiceFactory.
La cusomized IClaimsProvider est comme ci-dessous:
Ensuite, remplacez le IClaimsProvider comme ceci:
Le résultat est que, lorsque la demande de jeton d'accès est envoyé à jeton d'extrémité les revendications sont ajoutés à l'access_token.
Que faire si les revendications sont différentes pour les différents utilisateurs? Si j'associe les revendications de portée, est-ce que les revendications doivent être les mêmes pour tous les utilisateurs?
OriginalL'auteur Yang Zhang
Pas seulement que j'ai essayé d'autres méthodes, j'ai essayé toutes les combinaisons possibles des étendues etc. Tout ce que je pouvais lire dans le jeton d'accès a été "portée", "nom de l'étendue", pour des Flux de Ressources il n'y avait pas de revendications, j'ai ajouté de la période.
J'ai eu à faire tout ce
Je suppose que cette dernière étape pourrait être fait primordial GetProfileDataAsync dans la coutume UserServiceBase, mais ce que je viens d'travaillé donc je ne voulait pas déranger.
Le grand problème n'est pas la façon de régler les réclamations, c'est l'endroit où vous de les remplir. Vous devez remplacer quelque chose quelque part.
Ce ici a travaillé pour moi car j'ai besoin des données à partir d'une base de données, quelqu'un d'autre devrait se remplir les revendications ailleurs. Mais ils ne vont pas apparaître comme par magie juste parce que vous avez bien défini les Étendues et les Revendications de l'Identité des configurations de Serveur.
La plupart des réponses ne dis pas un mot sur la où pour définir les valeurs de demande correctement. Dans chaque ignorer que vous avez fait, les paramètres transmis, quand ils ont des revendications, dans la fonction sont attachés à l'identité ou jeton d'accès.
Il suffit de prendre soin de tout cela et tout ira bien.
OriginalL'auteur alex.peter