Open Id Connect Doubts - Identity Server 4 // How to grant specific users to concrete scopes?
I have some doubts after reading the Open Id docs. Any help will be much appreciated.
Following any of the oidc flows you end by having an id_token and a access_token.
a)When you send the access_token to a protected api, why or when (example) it would need to retrieve some claims about the user who owns it? Maybe if the protected api wants to use some data about the authenticated user?
b) For obtaining the claims the protected api will need to communicate with the UserEdnpoint endpoint?
It sends the access_token?
And which claims are contained in the returned id_token?/ What happens if it asks for more claims that the user has consent access?
c)Identity server 4: You define resources to be protected. They could be "identity resources" and "api resources".While defining ApiResources you can define inside fine-grained scopes. For example:
Scopes =
{
new Scope()
{
Name = "weather.api.full_access",
DisplayName = "Full access to WEATHER API",
},
new Scope
{
Name = "weather.api.read_only",
DisplayName = "Read only access to WEATHER API"
}
}
Also you define the clients , and to which scopes they have access.
How do yo you specify which users can access to specific resources? I don 't see how you will map specific permissions of users using the same client.
The steps will be:
- Give the client access to both scopes: "weather.api.full_access","weather.api.read_only"
- And now.... how I grant, for example "Billy" to have "weather.api.full_access", and "Jhon" to have "weather.api.read_only" ? They are using both the same client.
Many thanks!!
oauth-2.0 openid identityserver4 openid-connect
|
show 5 more comments
I have some doubts after reading the Open Id docs. Any help will be much appreciated.
Following any of the oidc flows you end by having an id_token and a access_token.
a)When you send the access_token to a protected api, why or when (example) it would need to retrieve some claims about the user who owns it? Maybe if the protected api wants to use some data about the authenticated user?
b) For obtaining the claims the protected api will need to communicate with the UserEdnpoint endpoint?
It sends the access_token?
And which claims are contained in the returned id_token?/ What happens if it asks for more claims that the user has consent access?
c)Identity server 4: You define resources to be protected. They could be "identity resources" and "api resources".While defining ApiResources you can define inside fine-grained scopes. For example:
Scopes =
{
new Scope()
{
Name = "weather.api.full_access",
DisplayName = "Full access to WEATHER API",
},
new Scope
{
Name = "weather.api.read_only",
DisplayName = "Read only access to WEATHER API"
}
}
Also you define the clients , and to which scopes they have access.
How do yo you specify which users can access to specific resources? I don 't see how you will map specific permissions of users using the same client.
The steps will be:
- Give the client access to both scopes: "weather.api.full_access","weather.api.read_only"
- And now.... how I grant, for example "Billy" to have "weather.api.full_access", and "Jhon" to have "weather.api.read_only" ? They are using both the same client.
Many thanks!!
oauth-2.0 openid identityserver4 openid-connect
You are falling into the trap of solving concerns of "Authorization" within IdentityServer which is meant to help solve concerns of "Authentication". Aka, validating that the user/machine is who they say they are. I would recommend to look into "PolicyServer" that the creators of IdentityServer have also produced. They also have a nice youtube video (don't have link at hand) discussing these boundaries between concerns.
– Vidmantas Blazevicius
Jan 2 at 15:27
Ok , many thanks, will you be so nice to answer my questions too? :) :)
– Badulake
Jan 2 at 15:59
2
Scopes are only what a client application has been authorized to do. It has no effect on what a user is allowed to do: auth0.com/blog/on-the-nature-of-oauth2-scopes You'll want a different solution for user authorization.
– Scott Brady
Jan 3 at 8:38
@ScottBrady do you recommend me some solution in .net for that purpose?
– Badulake
Jan 3 at 13:43
1
You could give PolicyServer a go: policyserver.io Other than that, I typically recommend keeping user authorization decisions within the client apps/protected resources themselves
– Scott Brady
Jan 3 at 15:53
|
show 5 more comments
I have some doubts after reading the Open Id docs. Any help will be much appreciated.
Following any of the oidc flows you end by having an id_token and a access_token.
a)When you send the access_token to a protected api, why or when (example) it would need to retrieve some claims about the user who owns it? Maybe if the protected api wants to use some data about the authenticated user?
b) For obtaining the claims the protected api will need to communicate with the UserEdnpoint endpoint?
It sends the access_token?
And which claims are contained in the returned id_token?/ What happens if it asks for more claims that the user has consent access?
c)Identity server 4: You define resources to be protected. They could be "identity resources" and "api resources".While defining ApiResources you can define inside fine-grained scopes. For example:
Scopes =
{
new Scope()
{
Name = "weather.api.full_access",
DisplayName = "Full access to WEATHER API",
},
new Scope
{
Name = "weather.api.read_only",
DisplayName = "Read only access to WEATHER API"
}
}
Also you define the clients , and to which scopes they have access.
How do yo you specify which users can access to specific resources? I don 't see how you will map specific permissions of users using the same client.
The steps will be:
- Give the client access to both scopes: "weather.api.full_access","weather.api.read_only"
- And now.... how I grant, for example "Billy" to have "weather.api.full_access", and "Jhon" to have "weather.api.read_only" ? They are using both the same client.
Many thanks!!
oauth-2.0 openid identityserver4 openid-connect
I have some doubts after reading the Open Id docs. Any help will be much appreciated.
Following any of the oidc flows you end by having an id_token and a access_token.
a)When you send the access_token to a protected api, why or when (example) it would need to retrieve some claims about the user who owns it? Maybe if the protected api wants to use some data about the authenticated user?
b) For obtaining the claims the protected api will need to communicate with the UserEdnpoint endpoint?
It sends the access_token?
And which claims are contained in the returned id_token?/ What happens if it asks for more claims that the user has consent access?
c)Identity server 4: You define resources to be protected. They could be "identity resources" and "api resources".While defining ApiResources you can define inside fine-grained scopes. For example:
Scopes =
{
new Scope()
{
Name = "weather.api.full_access",
DisplayName = "Full access to WEATHER API",
},
new Scope
{
Name = "weather.api.read_only",
DisplayName = "Read only access to WEATHER API"
}
}
Also you define the clients , and to which scopes they have access.
How do yo you specify which users can access to specific resources? I don 't see how you will map specific permissions of users using the same client.
The steps will be:
- Give the client access to both scopes: "weather.api.full_access","weather.api.read_only"
- And now.... how I grant, for example "Billy" to have "weather.api.full_access", and "Jhon" to have "weather.api.read_only" ? They are using both the same client.
Many thanks!!
oauth-2.0 openid identityserver4 openid-connect
oauth-2.0 openid identityserver4 openid-connect
asked Jan 2 at 12:03


BadulakeBadulake
1,1651823
1,1651823
You are falling into the trap of solving concerns of "Authorization" within IdentityServer which is meant to help solve concerns of "Authentication". Aka, validating that the user/machine is who they say they are. I would recommend to look into "PolicyServer" that the creators of IdentityServer have also produced. They also have a nice youtube video (don't have link at hand) discussing these boundaries between concerns.
– Vidmantas Blazevicius
Jan 2 at 15:27
Ok , many thanks, will you be so nice to answer my questions too? :) :)
– Badulake
Jan 2 at 15:59
2
Scopes are only what a client application has been authorized to do. It has no effect on what a user is allowed to do: auth0.com/blog/on-the-nature-of-oauth2-scopes You'll want a different solution for user authorization.
– Scott Brady
Jan 3 at 8:38
@ScottBrady do you recommend me some solution in .net for that purpose?
– Badulake
Jan 3 at 13:43
1
You could give PolicyServer a go: policyserver.io Other than that, I typically recommend keeping user authorization decisions within the client apps/protected resources themselves
– Scott Brady
Jan 3 at 15:53
|
show 5 more comments
You are falling into the trap of solving concerns of "Authorization" within IdentityServer which is meant to help solve concerns of "Authentication". Aka, validating that the user/machine is who they say they are. I would recommend to look into "PolicyServer" that the creators of IdentityServer have also produced. They also have a nice youtube video (don't have link at hand) discussing these boundaries between concerns.
– Vidmantas Blazevicius
Jan 2 at 15:27
Ok , many thanks, will you be so nice to answer my questions too? :) :)
– Badulake
Jan 2 at 15:59
2
Scopes are only what a client application has been authorized to do. It has no effect on what a user is allowed to do: auth0.com/blog/on-the-nature-of-oauth2-scopes You'll want a different solution for user authorization.
– Scott Brady
Jan 3 at 8:38
@ScottBrady do you recommend me some solution in .net for that purpose?
– Badulake
Jan 3 at 13:43
1
You could give PolicyServer a go: policyserver.io Other than that, I typically recommend keeping user authorization decisions within the client apps/protected resources themselves
– Scott Brady
Jan 3 at 15:53
You are falling into the trap of solving concerns of "Authorization" within IdentityServer which is meant to help solve concerns of "Authentication". Aka, validating that the user/machine is who they say they are. I would recommend to look into "PolicyServer" that the creators of IdentityServer have also produced. They also have a nice youtube video (don't have link at hand) discussing these boundaries between concerns.
– Vidmantas Blazevicius
Jan 2 at 15:27
You are falling into the trap of solving concerns of "Authorization" within IdentityServer which is meant to help solve concerns of "Authentication". Aka, validating that the user/machine is who they say they are. I would recommend to look into "PolicyServer" that the creators of IdentityServer have also produced. They also have a nice youtube video (don't have link at hand) discussing these boundaries between concerns.
– Vidmantas Blazevicius
Jan 2 at 15:27
Ok , many thanks, will you be so nice to answer my questions too? :) :)
– Badulake
Jan 2 at 15:59
Ok , many thanks, will you be so nice to answer my questions too? :) :)
– Badulake
Jan 2 at 15:59
2
2
Scopes are only what a client application has been authorized to do. It has no effect on what a user is allowed to do: auth0.com/blog/on-the-nature-of-oauth2-scopes You'll want a different solution for user authorization.
– Scott Brady
Jan 3 at 8:38
Scopes are only what a client application has been authorized to do. It has no effect on what a user is allowed to do: auth0.com/blog/on-the-nature-of-oauth2-scopes You'll want a different solution for user authorization.
– Scott Brady
Jan 3 at 8:38
@ScottBrady do you recommend me some solution in .net for that purpose?
– Badulake
Jan 3 at 13:43
@ScottBrady do you recommend me some solution in .net for that purpose?
– Badulake
Jan 3 at 13:43
1
1
You could give PolicyServer a go: policyserver.io Other than that, I typically recommend keeping user authorization decisions within the client apps/protected resources themselves
– Scott Brady
Jan 3 at 15:53
You could give PolicyServer a go: policyserver.io Other than that, I typically recommend keeping user authorization decisions within the client apps/protected resources themselves
– Scott Brady
Jan 3 at 15:53
|
show 5 more comments
2 Answers
2
active
oldest
votes
IdentityServer has three parts:
- ApiResource configuration
- IdentityResource configuration
- User information (claims)
There are two tokens: the access token and the identity token. The access token is used to access resources (api and also UserInfo endpoint), the identity token contains information about the user.
While IdentityServer is about authenticating the user, it also contains configuration for authorization. You can use something like a PolicyServer to take the authorization out of IdentityServer, but for basic authorization you don't have to.
There are two types of user claims:
- claims about who the user is, like name, gender, birtday, etc.
- claims about what the user is authorized to, like roles, employeeId, etc.
The first set of claims are part of the identity token and tell the client about WHO the user is, the other claims are part of the access token and tell the API what the user is allowed to do.
About the Identity Token, the only thing you can count on is the fact that it always contains the sub
claim (the Id from the user table). The short version of the filosophy here is to keep the token small because all you need is that claim. Additional information can be requested at the UserInfo endpoint. The content of the identity tokencan vary. E.g. you can force to add all claims to the first token (AlwaysIncludeUserClaimsInIdToken) in order to prevent an additional call.
On the other hand, if the user chooses to not give consent then the identity token will remain empty (except for the sub claim, because scope=openid is required). Also when requested from the UserInfo endpoint.
So the question is, how are you going to use the identity token? How much value does the token have? You shouldn't use it to access resources (that's where the access token is for) and it may not contain the requested information.
About the access token, this is the token that actually make it possible for the client to access a resource (api). In the client_credentials flow, there is no user (so there won't be an identity token as well), while in other flwos the client will act on behalf of the user. The difference between the first flow and the others is the sub
claim. That tells the Api on who's behalf the client requests access.
For access tokens counts the same, if the user doesn't give consent then the client will not be able to access the resource.
About resources and scopes. A resource is a logical name of a resource. By that I mean that it is possible that you have multiple Api's that are part of the same resource. That's fine. Because one resource can have many scopes. In the examples it is 1:1, but when you are really using scopes, then you'll see that a scope actually defines a certain piece of functionality within the resource. Like micro services.
Back to IdentityServer. An important job of IdentityServer is to filter claims. Because the user can have many claims, but you only want them when you need them. So per token the requested claims are added.
The Identity Token claims tell something about who the user is. But there is more, these claims are not context dependent. They are always true. Your name is everywhere the same, so is your birthday, etc. Use the IdentityResource table to define the scopes, e.g. openid, profile, email.
The claims in the access token are context dependent. Because only the API knows what a claim means. Use namespace types to distinct between claims.
It doesn't really matter how the Api resource is setup, just remember that when a scope is requested all claims from the resource (including the other scopes in that resource) are added to the request filter, while when a scope is requested, only the claims for that scope are added to the request filter. The request filter that is used to add all matching claims from the user to the token.
So now you have an access token. The token must contain information about the scopes. Why? Because you don't want clients to access resources that are not allowed. Limit access by defining the scopes per client. As a scope is a piece of functionality, you know which scopes the client needs. In the IdentityServer you configure the same scopes in order to match the client. Never trust a client.
The access token contains all claims from the requested scope/resources. That means that with that token all api's within the resource/scope can be accessed with that token, without having to obtain a new token per api.
This also means that the token can become quite large. Something you should avoid before hitting limits. That is why you don't want permissions in the token. If you want permissions, then implement your own authorization server.
On the other hand, do you need permissions? Given a design where the Api (resource) knows what a user is allowed to access, use policies (sort of business rules) and resource based authorization. You can implement a local user table that contains information about the permissions.
Also, do you really need CRUD permissions on every object? With policies you have the chance to define more complex authorization than just comparing string values.
As for the user, the user is the resource for the identity. But knows nothing about scopes. So you can't bind scopes to users. The client has scopes, which opens the door to the api, but the api decides whether the user actually has access.
And now to answer your questions:
a) All claims from the user that match the requested claim types are added to the access token. Where requested claim types are taken from the requested scopes. Where all ApiResource claim types that are related to the requested scopes are added and the claim types of the requested scopes themselves.
If the Api needs information about the user, then it can use the access token to call the UserInfo endpoint. The default identity token only contains the sub
claim (something the user can't deny or revoke).
b) The tokens are requested by adding scopes to the client. By default the openid, profile scopes are added. The client credentials will not receive an identity token and there is one additional token, the refresh token. Please note that this token is not available to all flows. To request the refresh token add the offline_access
scope. Where you can take offline access literal. This is a token that allows the client to request new access tokens, without requiring user input. So in case the user is offline, the service can still proceed.
When user consent is required then it is possible that certain information or options are not available. E.g. if the user doesn't want offline access, then the service (e.g. some synchronization service) will not be able to run. This also occurs when the user revokes a given consent. Requesting new access token will result in an unauthorized response.
In order to bypass missing user information, simply ask the user for information and store it locally. You are most likely going to need it there anyway.
c) Forget permissions, use policies and resource based authorization. Implement this in the Api. That's the place where the exact context is known. The client can open the door to the api, but it depends on the user (claims, local authorization info) if the resource can be accessed.
Suppose you have the resource 'weather' and scopes 'weather.api.full_access' and 'weather.api.read_only' (as part of the resource 'weather').
Please note that the name 'weather.api.full_access' doesn't say anything about the level of access, only about the expected functionality.
The actual access level should be based on local information from the resource or policies, e.g. user has a read subscription or an admin role.
In order to give Billy full access add the http://api/admin (value: true) claim to Billy. And for Jhon add a record in the subscriptions table.
In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested.
I hope this makes sense to you. It's hard to give a short and complete answer. Let me know if you have questions about this answer.
In short, IdentityServer can implement it all. If you want permissions then take a look at the policy server.
what do you mean by : "In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested." ?? Thanks
– Badulake
Jan 8 at 9:54
Your help was 10/10 . I still have some doubts , that`s the reason why i oepened a new question. It is more focused in a concrete example. Many thanks!!
– Badulake
Jan 8 at 9:55
add a comment |
a)When you send the access_token to a protected api, why or when (example) it would need to retrieve some claims about the user who owns it? Maybe if the protected api wants to use some data about the authenticated user?
For example, if your users can be subdivided into organisations or departments and you want to add a policy within your api to only allow access to certain endpoints for when the user is in one of those subdivided groups - you can add a custom claim "organisationid"
or "departmentid
" and add that claim with its value to the tokens that are issued. Whether this is applicable or not, it will depend based on the context of your problem and there is a fine line when the concern of authorization
can mistakenly be attempted to be solved within authentication
.
b) For obtaining the claims the protected api will need to communicate with the UserEdnpoint endpoint? It sends the access_token? And which claims are contained in the returned id_token?/ What happens if it asks for more claims that the user has consent access?
You don't necessarlily need to use UserInfo endpoint. You can set the client property AlwaysIncludeUserClaimsInIdToken
to true and all the claims will be included in the id_token
by default therefore removing the need of the round trip to UserInfo endpoint. If you do end up taking the round trip, you were correct in saying that you need to send access_token
representing the user, however, what is returned is not an id_token
, but rather user info.
Example from IdentityServer4 docs:
Request: GET /connect/userinfo
Authorization: Bearer {access_token}
Response: HTTP/1.1 200 OK
Content-Type: application/json
{
"sub": "248289761001",
"name": "Bob Smith",
"given_name": "Bob",
"family_name": "Smith",
"role": [
"user",
"admin"
] }
Lastly
How do yo you specify which users can access to specific resources?
This should most likely be solved through Authorization
which is not the concern of OAuth2 protocol or IdentityServer4. Authorization
is normally handled differently within each application based on problem domain needs. I would recommend to take a look at Policy Server by the creators of Identity Server. They have an excellent video where they delve deeper into this topic and they also have a product to address this problem.
@question b // i think you wrote a mistake => access_token sent , right?
– Badulake
Jan 4 at 10:19
@Badulake yes, good spot. I've seen your other question too - yes, I have some projects using PolicyServer in production so it is definitely worthwhile looking into. In general, I would suggest at looking at defaultAuthorizationPolicy
framework in ASP.NET Core. If that doesn't suit your business needs, you can look into external libs likePolicyServer
. If that doesn't work - you need to create your own business logic. It is unlikely you will get a concrete answer on StackOverflow for this as you need to understand the problem domain very well to identify what suits best.
– Vidmantas Blazevicius
Jan 4 at 11:04
Your help is being awesome. Many thanks!!!!!
– Badulake
Jan 4 at 11:26
@Badulake no problems, happy to help.
– Vidmantas Blazevicius
Jan 4 at 11:50
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54006026%2fopen-id-connect-doubts-identity-server-4-how-to-grant-specific-users-to-con%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
IdentityServer has three parts:
- ApiResource configuration
- IdentityResource configuration
- User information (claims)
There are two tokens: the access token and the identity token. The access token is used to access resources (api and also UserInfo endpoint), the identity token contains information about the user.
While IdentityServer is about authenticating the user, it also contains configuration for authorization. You can use something like a PolicyServer to take the authorization out of IdentityServer, but for basic authorization you don't have to.
There are two types of user claims:
- claims about who the user is, like name, gender, birtday, etc.
- claims about what the user is authorized to, like roles, employeeId, etc.
The first set of claims are part of the identity token and tell the client about WHO the user is, the other claims are part of the access token and tell the API what the user is allowed to do.
About the Identity Token, the only thing you can count on is the fact that it always contains the sub
claim (the Id from the user table). The short version of the filosophy here is to keep the token small because all you need is that claim. Additional information can be requested at the UserInfo endpoint. The content of the identity tokencan vary. E.g. you can force to add all claims to the first token (AlwaysIncludeUserClaimsInIdToken) in order to prevent an additional call.
On the other hand, if the user chooses to not give consent then the identity token will remain empty (except for the sub claim, because scope=openid is required). Also when requested from the UserInfo endpoint.
So the question is, how are you going to use the identity token? How much value does the token have? You shouldn't use it to access resources (that's where the access token is for) and it may not contain the requested information.
About the access token, this is the token that actually make it possible for the client to access a resource (api). In the client_credentials flow, there is no user (so there won't be an identity token as well), while in other flwos the client will act on behalf of the user. The difference between the first flow and the others is the sub
claim. That tells the Api on who's behalf the client requests access.
For access tokens counts the same, if the user doesn't give consent then the client will not be able to access the resource.
About resources and scopes. A resource is a logical name of a resource. By that I mean that it is possible that you have multiple Api's that are part of the same resource. That's fine. Because one resource can have many scopes. In the examples it is 1:1, but when you are really using scopes, then you'll see that a scope actually defines a certain piece of functionality within the resource. Like micro services.
Back to IdentityServer. An important job of IdentityServer is to filter claims. Because the user can have many claims, but you only want them when you need them. So per token the requested claims are added.
The Identity Token claims tell something about who the user is. But there is more, these claims are not context dependent. They are always true. Your name is everywhere the same, so is your birthday, etc. Use the IdentityResource table to define the scopes, e.g. openid, profile, email.
The claims in the access token are context dependent. Because only the API knows what a claim means. Use namespace types to distinct between claims.
It doesn't really matter how the Api resource is setup, just remember that when a scope is requested all claims from the resource (including the other scopes in that resource) are added to the request filter, while when a scope is requested, only the claims for that scope are added to the request filter. The request filter that is used to add all matching claims from the user to the token.
So now you have an access token. The token must contain information about the scopes. Why? Because you don't want clients to access resources that are not allowed. Limit access by defining the scopes per client. As a scope is a piece of functionality, you know which scopes the client needs. In the IdentityServer you configure the same scopes in order to match the client. Never trust a client.
The access token contains all claims from the requested scope/resources. That means that with that token all api's within the resource/scope can be accessed with that token, without having to obtain a new token per api.
This also means that the token can become quite large. Something you should avoid before hitting limits. That is why you don't want permissions in the token. If you want permissions, then implement your own authorization server.
On the other hand, do you need permissions? Given a design where the Api (resource) knows what a user is allowed to access, use policies (sort of business rules) and resource based authorization. You can implement a local user table that contains information about the permissions.
Also, do you really need CRUD permissions on every object? With policies you have the chance to define more complex authorization than just comparing string values.
As for the user, the user is the resource for the identity. But knows nothing about scopes. So you can't bind scopes to users. The client has scopes, which opens the door to the api, but the api decides whether the user actually has access.
And now to answer your questions:
a) All claims from the user that match the requested claim types are added to the access token. Where requested claim types are taken from the requested scopes. Where all ApiResource claim types that are related to the requested scopes are added and the claim types of the requested scopes themselves.
If the Api needs information about the user, then it can use the access token to call the UserInfo endpoint. The default identity token only contains the sub
claim (something the user can't deny or revoke).
b) The tokens are requested by adding scopes to the client. By default the openid, profile scopes are added. The client credentials will not receive an identity token and there is one additional token, the refresh token. Please note that this token is not available to all flows. To request the refresh token add the offline_access
scope. Where you can take offline access literal. This is a token that allows the client to request new access tokens, without requiring user input. So in case the user is offline, the service can still proceed.
When user consent is required then it is possible that certain information or options are not available. E.g. if the user doesn't want offline access, then the service (e.g. some synchronization service) will not be able to run. This also occurs when the user revokes a given consent. Requesting new access token will result in an unauthorized response.
In order to bypass missing user information, simply ask the user for information and store it locally. You are most likely going to need it there anyway.
c) Forget permissions, use policies and resource based authorization. Implement this in the Api. That's the place where the exact context is known. The client can open the door to the api, but it depends on the user (claims, local authorization info) if the resource can be accessed.
Suppose you have the resource 'weather' and scopes 'weather.api.full_access' and 'weather.api.read_only' (as part of the resource 'weather').
Please note that the name 'weather.api.full_access' doesn't say anything about the level of access, only about the expected functionality.
The actual access level should be based on local information from the resource or policies, e.g. user has a read subscription or an admin role.
In order to give Billy full access add the http://api/admin (value: true) claim to Billy. And for Jhon add a record in the subscriptions table.
In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested.
I hope this makes sense to you. It's hard to give a short and complete answer. Let me know if you have questions about this answer.
In short, IdentityServer can implement it all. If you want permissions then take a look at the policy server.
what do you mean by : "In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested." ?? Thanks
– Badulake
Jan 8 at 9:54
Your help was 10/10 . I still have some doubts , that`s the reason why i oepened a new question. It is more focused in a concrete example. Many thanks!!
– Badulake
Jan 8 at 9:55
add a comment |
IdentityServer has three parts:
- ApiResource configuration
- IdentityResource configuration
- User information (claims)
There are two tokens: the access token and the identity token. The access token is used to access resources (api and also UserInfo endpoint), the identity token contains information about the user.
While IdentityServer is about authenticating the user, it also contains configuration for authorization. You can use something like a PolicyServer to take the authorization out of IdentityServer, but for basic authorization you don't have to.
There are two types of user claims:
- claims about who the user is, like name, gender, birtday, etc.
- claims about what the user is authorized to, like roles, employeeId, etc.
The first set of claims are part of the identity token and tell the client about WHO the user is, the other claims are part of the access token and tell the API what the user is allowed to do.
About the Identity Token, the only thing you can count on is the fact that it always contains the sub
claim (the Id from the user table). The short version of the filosophy here is to keep the token small because all you need is that claim. Additional information can be requested at the UserInfo endpoint. The content of the identity tokencan vary. E.g. you can force to add all claims to the first token (AlwaysIncludeUserClaimsInIdToken) in order to prevent an additional call.
On the other hand, if the user chooses to not give consent then the identity token will remain empty (except for the sub claim, because scope=openid is required). Also when requested from the UserInfo endpoint.
So the question is, how are you going to use the identity token? How much value does the token have? You shouldn't use it to access resources (that's where the access token is for) and it may not contain the requested information.
About the access token, this is the token that actually make it possible for the client to access a resource (api). In the client_credentials flow, there is no user (so there won't be an identity token as well), while in other flwos the client will act on behalf of the user. The difference between the first flow and the others is the sub
claim. That tells the Api on who's behalf the client requests access.
For access tokens counts the same, if the user doesn't give consent then the client will not be able to access the resource.
About resources and scopes. A resource is a logical name of a resource. By that I mean that it is possible that you have multiple Api's that are part of the same resource. That's fine. Because one resource can have many scopes. In the examples it is 1:1, but when you are really using scopes, then you'll see that a scope actually defines a certain piece of functionality within the resource. Like micro services.
Back to IdentityServer. An important job of IdentityServer is to filter claims. Because the user can have many claims, but you only want them when you need them. So per token the requested claims are added.
The Identity Token claims tell something about who the user is. But there is more, these claims are not context dependent. They are always true. Your name is everywhere the same, so is your birthday, etc. Use the IdentityResource table to define the scopes, e.g. openid, profile, email.
The claims in the access token are context dependent. Because only the API knows what a claim means. Use namespace types to distinct between claims.
It doesn't really matter how the Api resource is setup, just remember that when a scope is requested all claims from the resource (including the other scopes in that resource) are added to the request filter, while when a scope is requested, only the claims for that scope are added to the request filter. The request filter that is used to add all matching claims from the user to the token.
So now you have an access token. The token must contain information about the scopes. Why? Because you don't want clients to access resources that are not allowed. Limit access by defining the scopes per client. As a scope is a piece of functionality, you know which scopes the client needs. In the IdentityServer you configure the same scopes in order to match the client. Never trust a client.
The access token contains all claims from the requested scope/resources. That means that with that token all api's within the resource/scope can be accessed with that token, without having to obtain a new token per api.
This also means that the token can become quite large. Something you should avoid before hitting limits. That is why you don't want permissions in the token. If you want permissions, then implement your own authorization server.
On the other hand, do you need permissions? Given a design where the Api (resource) knows what a user is allowed to access, use policies (sort of business rules) and resource based authorization. You can implement a local user table that contains information about the permissions.
Also, do you really need CRUD permissions on every object? With policies you have the chance to define more complex authorization than just comparing string values.
As for the user, the user is the resource for the identity. But knows nothing about scopes. So you can't bind scopes to users. The client has scopes, which opens the door to the api, but the api decides whether the user actually has access.
And now to answer your questions:
a) All claims from the user that match the requested claim types are added to the access token. Where requested claim types are taken from the requested scopes. Where all ApiResource claim types that are related to the requested scopes are added and the claim types of the requested scopes themselves.
If the Api needs information about the user, then it can use the access token to call the UserInfo endpoint. The default identity token only contains the sub
claim (something the user can't deny or revoke).
b) The tokens are requested by adding scopes to the client. By default the openid, profile scopes are added. The client credentials will not receive an identity token and there is one additional token, the refresh token. Please note that this token is not available to all flows. To request the refresh token add the offline_access
scope. Where you can take offline access literal. This is a token that allows the client to request new access tokens, without requiring user input. So in case the user is offline, the service can still proceed.
When user consent is required then it is possible that certain information or options are not available. E.g. if the user doesn't want offline access, then the service (e.g. some synchronization service) will not be able to run. This also occurs when the user revokes a given consent. Requesting new access token will result in an unauthorized response.
In order to bypass missing user information, simply ask the user for information and store it locally. You are most likely going to need it there anyway.
c) Forget permissions, use policies and resource based authorization. Implement this in the Api. That's the place where the exact context is known. The client can open the door to the api, but it depends on the user (claims, local authorization info) if the resource can be accessed.
Suppose you have the resource 'weather' and scopes 'weather.api.full_access' and 'weather.api.read_only' (as part of the resource 'weather').
Please note that the name 'weather.api.full_access' doesn't say anything about the level of access, only about the expected functionality.
The actual access level should be based on local information from the resource or policies, e.g. user has a read subscription or an admin role.
In order to give Billy full access add the http://api/admin (value: true) claim to Billy. And for Jhon add a record in the subscriptions table.
In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested.
I hope this makes sense to you. It's hard to give a short and complete answer. Let me know if you have questions about this answer.
In short, IdentityServer can implement it all. If you want permissions then take a look at the policy server.
what do you mean by : "In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested." ?? Thanks
– Badulake
Jan 8 at 9:54
Your help was 10/10 . I still have some doubts , that`s the reason why i oepened a new question. It is more focused in a concrete example. Many thanks!!
– Badulake
Jan 8 at 9:55
add a comment |
IdentityServer has three parts:
- ApiResource configuration
- IdentityResource configuration
- User information (claims)
There are two tokens: the access token and the identity token. The access token is used to access resources (api and also UserInfo endpoint), the identity token contains information about the user.
While IdentityServer is about authenticating the user, it also contains configuration for authorization. You can use something like a PolicyServer to take the authorization out of IdentityServer, but for basic authorization you don't have to.
There are two types of user claims:
- claims about who the user is, like name, gender, birtday, etc.
- claims about what the user is authorized to, like roles, employeeId, etc.
The first set of claims are part of the identity token and tell the client about WHO the user is, the other claims are part of the access token and tell the API what the user is allowed to do.
About the Identity Token, the only thing you can count on is the fact that it always contains the sub
claim (the Id from the user table). The short version of the filosophy here is to keep the token small because all you need is that claim. Additional information can be requested at the UserInfo endpoint. The content of the identity tokencan vary. E.g. you can force to add all claims to the first token (AlwaysIncludeUserClaimsInIdToken) in order to prevent an additional call.
On the other hand, if the user chooses to not give consent then the identity token will remain empty (except for the sub claim, because scope=openid is required). Also when requested from the UserInfo endpoint.
So the question is, how are you going to use the identity token? How much value does the token have? You shouldn't use it to access resources (that's where the access token is for) and it may not contain the requested information.
About the access token, this is the token that actually make it possible for the client to access a resource (api). In the client_credentials flow, there is no user (so there won't be an identity token as well), while in other flwos the client will act on behalf of the user. The difference between the first flow and the others is the sub
claim. That tells the Api on who's behalf the client requests access.
For access tokens counts the same, if the user doesn't give consent then the client will not be able to access the resource.
About resources and scopes. A resource is a logical name of a resource. By that I mean that it is possible that you have multiple Api's that are part of the same resource. That's fine. Because one resource can have many scopes. In the examples it is 1:1, but when you are really using scopes, then you'll see that a scope actually defines a certain piece of functionality within the resource. Like micro services.
Back to IdentityServer. An important job of IdentityServer is to filter claims. Because the user can have many claims, but you only want them when you need them. So per token the requested claims are added.
The Identity Token claims tell something about who the user is. But there is more, these claims are not context dependent. They are always true. Your name is everywhere the same, so is your birthday, etc. Use the IdentityResource table to define the scopes, e.g. openid, profile, email.
The claims in the access token are context dependent. Because only the API knows what a claim means. Use namespace types to distinct between claims.
It doesn't really matter how the Api resource is setup, just remember that when a scope is requested all claims from the resource (including the other scopes in that resource) are added to the request filter, while when a scope is requested, only the claims for that scope are added to the request filter. The request filter that is used to add all matching claims from the user to the token.
So now you have an access token. The token must contain information about the scopes. Why? Because you don't want clients to access resources that are not allowed. Limit access by defining the scopes per client. As a scope is a piece of functionality, you know which scopes the client needs. In the IdentityServer you configure the same scopes in order to match the client. Never trust a client.
The access token contains all claims from the requested scope/resources. That means that with that token all api's within the resource/scope can be accessed with that token, without having to obtain a new token per api.
This also means that the token can become quite large. Something you should avoid before hitting limits. That is why you don't want permissions in the token. If you want permissions, then implement your own authorization server.
On the other hand, do you need permissions? Given a design where the Api (resource) knows what a user is allowed to access, use policies (sort of business rules) and resource based authorization. You can implement a local user table that contains information about the permissions.
Also, do you really need CRUD permissions on every object? With policies you have the chance to define more complex authorization than just comparing string values.
As for the user, the user is the resource for the identity. But knows nothing about scopes. So you can't bind scopes to users. The client has scopes, which opens the door to the api, but the api decides whether the user actually has access.
And now to answer your questions:
a) All claims from the user that match the requested claim types are added to the access token. Where requested claim types are taken from the requested scopes. Where all ApiResource claim types that are related to the requested scopes are added and the claim types of the requested scopes themselves.
If the Api needs information about the user, then it can use the access token to call the UserInfo endpoint. The default identity token only contains the sub
claim (something the user can't deny or revoke).
b) The tokens are requested by adding scopes to the client. By default the openid, profile scopes are added. The client credentials will not receive an identity token and there is one additional token, the refresh token. Please note that this token is not available to all flows. To request the refresh token add the offline_access
scope. Where you can take offline access literal. This is a token that allows the client to request new access tokens, without requiring user input. So in case the user is offline, the service can still proceed.
When user consent is required then it is possible that certain information or options are not available. E.g. if the user doesn't want offline access, then the service (e.g. some synchronization service) will not be able to run. This also occurs when the user revokes a given consent. Requesting new access token will result in an unauthorized response.
In order to bypass missing user information, simply ask the user for information and store it locally. You are most likely going to need it there anyway.
c) Forget permissions, use policies and resource based authorization. Implement this in the Api. That's the place where the exact context is known. The client can open the door to the api, but it depends on the user (claims, local authorization info) if the resource can be accessed.
Suppose you have the resource 'weather' and scopes 'weather.api.full_access' and 'weather.api.read_only' (as part of the resource 'weather').
Please note that the name 'weather.api.full_access' doesn't say anything about the level of access, only about the expected functionality.
The actual access level should be based on local information from the resource or policies, e.g. user has a read subscription or an admin role.
In order to give Billy full access add the http://api/admin (value: true) claim to Billy. And for Jhon add a record in the subscriptions table.
In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested.
I hope this makes sense to you. It's hard to give a short and complete answer. Let me know if you have questions about this answer.
In short, IdentityServer can implement it all. If you want permissions then take a look at the policy server.
IdentityServer has three parts:
- ApiResource configuration
- IdentityResource configuration
- User information (claims)
There are two tokens: the access token and the identity token. The access token is used to access resources (api and also UserInfo endpoint), the identity token contains information about the user.
While IdentityServer is about authenticating the user, it also contains configuration for authorization. You can use something like a PolicyServer to take the authorization out of IdentityServer, but for basic authorization you don't have to.
There are two types of user claims:
- claims about who the user is, like name, gender, birtday, etc.
- claims about what the user is authorized to, like roles, employeeId, etc.
The first set of claims are part of the identity token and tell the client about WHO the user is, the other claims are part of the access token and tell the API what the user is allowed to do.
About the Identity Token, the only thing you can count on is the fact that it always contains the sub
claim (the Id from the user table). The short version of the filosophy here is to keep the token small because all you need is that claim. Additional information can be requested at the UserInfo endpoint. The content of the identity tokencan vary. E.g. you can force to add all claims to the first token (AlwaysIncludeUserClaimsInIdToken) in order to prevent an additional call.
On the other hand, if the user chooses to not give consent then the identity token will remain empty (except for the sub claim, because scope=openid is required). Also when requested from the UserInfo endpoint.
So the question is, how are you going to use the identity token? How much value does the token have? You shouldn't use it to access resources (that's where the access token is for) and it may not contain the requested information.
About the access token, this is the token that actually make it possible for the client to access a resource (api). In the client_credentials flow, there is no user (so there won't be an identity token as well), while in other flwos the client will act on behalf of the user. The difference between the first flow and the others is the sub
claim. That tells the Api on who's behalf the client requests access.
For access tokens counts the same, if the user doesn't give consent then the client will not be able to access the resource.
About resources and scopes. A resource is a logical name of a resource. By that I mean that it is possible that you have multiple Api's that are part of the same resource. That's fine. Because one resource can have many scopes. In the examples it is 1:1, but when you are really using scopes, then you'll see that a scope actually defines a certain piece of functionality within the resource. Like micro services.
Back to IdentityServer. An important job of IdentityServer is to filter claims. Because the user can have many claims, but you only want them when you need them. So per token the requested claims are added.
The Identity Token claims tell something about who the user is. But there is more, these claims are not context dependent. They are always true. Your name is everywhere the same, so is your birthday, etc. Use the IdentityResource table to define the scopes, e.g. openid, profile, email.
The claims in the access token are context dependent. Because only the API knows what a claim means. Use namespace types to distinct between claims.
It doesn't really matter how the Api resource is setup, just remember that when a scope is requested all claims from the resource (including the other scopes in that resource) are added to the request filter, while when a scope is requested, only the claims for that scope are added to the request filter. The request filter that is used to add all matching claims from the user to the token.
So now you have an access token. The token must contain information about the scopes. Why? Because you don't want clients to access resources that are not allowed. Limit access by defining the scopes per client. As a scope is a piece of functionality, you know which scopes the client needs. In the IdentityServer you configure the same scopes in order to match the client. Never trust a client.
The access token contains all claims from the requested scope/resources. That means that with that token all api's within the resource/scope can be accessed with that token, without having to obtain a new token per api.
This also means that the token can become quite large. Something you should avoid before hitting limits. That is why you don't want permissions in the token. If you want permissions, then implement your own authorization server.
On the other hand, do you need permissions? Given a design where the Api (resource) knows what a user is allowed to access, use policies (sort of business rules) and resource based authorization. You can implement a local user table that contains information about the permissions.
Also, do you really need CRUD permissions on every object? With policies you have the chance to define more complex authorization than just comparing string values.
As for the user, the user is the resource for the identity. But knows nothing about scopes. So you can't bind scopes to users. The client has scopes, which opens the door to the api, but the api decides whether the user actually has access.
And now to answer your questions:
a) All claims from the user that match the requested claim types are added to the access token. Where requested claim types are taken from the requested scopes. Where all ApiResource claim types that are related to the requested scopes are added and the claim types of the requested scopes themselves.
If the Api needs information about the user, then it can use the access token to call the UserInfo endpoint. The default identity token only contains the sub
claim (something the user can't deny or revoke).
b) The tokens are requested by adding scopes to the client. By default the openid, profile scopes are added. The client credentials will not receive an identity token and there is one additional token, the refresh token. Please note that this token is not available to all flows. To request the refresh token add the offline_access
scope. Where you can take offline access literal. This is a token that allows the client to request new access tokens, without requiring user input. So in case the user is offline, the service can still proceed.
When user consent is required then it is possible that certain information or options are not available. E.g. if the user doesn't want offline access, then the service (e.g. some synchronization service) will not be able to run. This also occurs when the user revokes a given consent. Requesting new access token will result in an unauthorized response.
In order to bypass missing user information, simply ask the user for information and store it locally. You are most likely going to need it there anyway.
c) Forget permissions, use policies and resource based authorization. Implement this in the Api. That's the place where the exact context is known. The client can open the door to the api, but it depends on the user (claims, local authorization info) if the resource can be accessed.
Suppose you have the resource 'weather' and scopes 'weather.api.full_access' and 'weather.api.read_only' (as part of the resource 'weather').
Please note that the name 'weather.api.full_access' doesn't say anything about the level of access, only about the expected functionality.
The actual access level should be based on local information from the resource or policies, e.g. user has a read subscription or an admin role.
In order to give Billy full access add the http://api/admin (value: true) claim to Billy. And for Jhon add a record in the subscriptions table.
In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested.
I hope this makes sense to you. It's hard to give a short and complete answer. Let me know if you have questions about this answer.
In short, IdentityServer can implement it all. If you want permissions then take a look at the policy server.
answered Jan 3 at 4:05
Ruard van ElburgRuard van Elburg
6,19821230
6,19821230
what do you mean by : "In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested." ?? Thanks
– Badulake
Jan 8 at 9:54
Your help was 10/10 . I still have some doubts , that`s the reason why i oepened a new question. It is more focused in a concrete example. Many thanks!!
– Badulake
Jan 8 at 9:55
add a comment |
what do you mean by : "In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested." ?? Thanks
– Badulake
Jan 8 at 9:54
Your help was 10/10 . I still have some doubts , that`s the reason why i oepened a new question. It is more focused in a concrete example. Many thanks!!
– Badulake
Jan 8 at 9:55
what do you mean by : "In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested." ?? Thanks
– Badulake
Jan 8 at 9:54
what do you mean by : "In order to divide a resource over multiple api's (per scope), use events to validate the scope. You don't want a client to access the full_access functionality when only the read scope was requested." ?? Thanks
– Badulake
Jan 8 at 9:54
Your help was 10/10 . I still have some doubts , that`s the reason why i oepened a new question. It is more focused in a concrete example. Many thanks!!
– Badulake
Jan 8 at 9:55
Your help was 10/10 . I still have some doubts , that`s the reason why i oepened a new question. It is more focused in a concrete example. Many thanks!!
– Badulake
Jan 8 at 9:55
add a comment |
a)When you send the access_token to a protected api, why or when (example) it would need to retrieve some claims about the user who owns it? Maybe if the protected api wants to use some data about the authenticated user?
For example, if your users can be subdivided into organisations or departments and you want to add a policy within your api to only allow access to certain endpoints for when the user is in one of those subdivided groups - you can add a custom claim "organisationid"
or "departmentid
" and add that claim with its value to the tokens that are issued. Whether this is applicable or not, it will depend based on the context of your problem and there is a fine line when the concern of authorization
can mistakenly be attempted to be solved within authentication
.
b) For obtaining the claims the protected api will need to communicate with the UserEdnpoint endpoint? It sends the access_token? And which claims are contained in the returned id_token?/ What happens if it asks for more claims that the user has consent access?
You don't necessarlily need to use UserInfo endpoint. You can set the client property AlwaysIncludeUserClaimsInIdToken
to true and all the claims will be included in the id_token
by default therefore removing the need of the round trip to UserInfo endpoint. If you do end up taking the round trip, you were correct in saying that you need to send access_token
representing the user, however, what is returned is not an id_token
, but rather user info.
Example from IdentityServer4 docs:
Request: GET /connect/userinfo
Authorization: Bearer {access_token}
Response: HTTP/1.1 200 OK
Content-Type: application/json
{
"sub": "248289761001",
"name": "Bob Smith",
"given_name": "Bob",
"family_name": "Smith",
"role": [
"user",
"admin"
] }
Lastly
How do yo you specify which users can access to specific resources?
This should most likely be solved through Authorization
which is not the concern of OAuth2 protocol or IdentityServer4. Authorization
is normally handled differently within each application based on problem domain needs. I would recommend to take a look at Policy Server by the creators of Identity Server. They have an excellent video where they delve deeper into this topic and they also have a product to address this problem.
@question b // i think you wrote a mistake => access_token sent , right?
– Badulake
Jan 4 at 10:19
@Badulake yes, good spot. I've seen your other question too - yes, I have some projects using PolicyServer in production so it is definitely worthwhile looking into. In general, I would suggest at looking at defaultAuthorizationPolicy
framework in ASP.NET Core. If that doesn't suit your business needs, you can look into external libs likePolicyServer
. If that doesn't work - you need to create your own business logic. It is unlikely you will get a concrete answer on StackOverflow for this as you need to understand the problem domain very well to identify what suits best.
– Vidmantas Blazevicius
Jan 4 at 11:04
Your help is being awesome. Many thanks!!!!!
– Badulake
Jan 4 at 11:26
@Badulake no problems, happy to help.
– Vidmantas Blazevicius
Jan 4 at 11:50
add a comment |
a)When you send the access_token to a protected api, why or when (example) it would need to retrieve some claims about the user who owns it? Maybe if the protected api wants to use some data about the authenticated user?
For example, if your users can be subdivided into organisations or departments and you want to add a policy within your api to only allow access to certain endpoints for when the user is in one of those subdivided groups - you can add a custom claim "organisationid"
or "departmentid
" and add that claim with its value to the tokens that are issued. Whether this is applicable or not, it will depend based on the context of your problem and there is a fine line when the concern of authorization
can mistakenly be attempted to be solved within authentication
.
b) For obtaining the claims the protected api will need to communicate with the UserEdnpoint endpoint? It sends the access_token? And which claims are contained in the returned id_token?/ What happens if it asks for more claims that the user has consent access?
You don't necessarlily need to use UserInfo endpoint. You can set the client property AlwaysIncludeUserClaimsInIdToken
to true and all the claims will be included in the id_token
by default therefore removing the need of the round trip to UserInfo endpoint. If you do end up taking the round trip, you were correct in saying that you need to send access_token
representing the user, however, what is returned is not an id_token
, but rather user info.
Example from IdentityServer4 docs:
Request: GET /connect/userinfo
Authorization: Bearer {access_token}
Response: HTTP/1.1 200 OK
Content-Type: application/json
{
"sub": "248289761001",
"name": "Bob Smith",
"given_name": "Bob",
"family_name": "Smith",
"role": [
"user",
"admin"
] }
Lastly
How do yo you specify which users can access to specific resources?
This should most likely be solved through Authorization
which is not the concern of OAuth2 protocol or IdentityServer4. Authorization
is normally handled differently within each application based on problem domain needs. I would recommend to take a look at Policy Server by the creators of Identity Server. They have an excellent video where they delve deeper into this topic and they also have a product to address this problem.
@question b // i think you wrote a mistake => access_token sent , right?
– Badulake
Jan 4 at 10:19
@Badulake yes, good spot. I've seen your other question too - yes, I have some projects using PolicyServer in production so it is definitely worthwhile looking into. In general, I would suggest at looking at defaultAuthorizationPolicy
framework in ASP.NET Core. If that doesn't suit your business needs, you can look into external libs likePolicyServer
. If that doesn't work - you need to create your own business logic. It is unlikely you will get a concrete answer on StackOverflow for this as you need to understand the problem domain very well to identify what suits best.
– Vidmantas Blazevicius
Jan 4 at 11:04
Your help is being awesome. Many thanks!!!!!
– Badulake
Jan 4 at 11:26
@Badulake no problems, happy to help.
– Vidmantas Blazevicius
Jan 4 at 11:50
add a comment |
a)When you send the access_token to a protected api, why or when (example) it would need to retrieve some claims about the user who owns it? Maybe if the protected api wants to use some data about the authenticated user?
For example, if your users can be subdivided into organisations or departments and you want to add a policy within your api to only allow access to certain endpoints for when the user is in one of those subdivided groups - you can add a custom claim "organisationid"
or "departmentid
" and add that claim with its value to the tokens that are issued. Whether this is applicable or not, it will depend based on the context of your problem and there is a fine line when the concern of authorization
can mistakenly be attempted to be solved within authentication
.
b) For obtaining the claims the protected api will need to communicate with the UserEdnpoint endpoint? It sends the access_token? And which claims are contained in the returned id_token?/ What happens if it asks for more claims that the user has consent access?
You don't necessarlily need to use UserInfo endpoint. You can set the client property AlwaysIncludeUserClaimsInIdToken
to true and all the claims will be included in the id_token
by default therefore removing the need of the round trip to UserInfo endpoint. If you do end up taking the round trip, you were correct in saying that you need to send access_token
representing the user, however, what is returned is not an id_token
, but rather user info.
Example from IdentityServer4 docs:
Request: GET /connect/userinfo
Authorization: Bearer {access_token}
Response: HTTP/1.1 200 OK
Content-Type: application/json
{
"sub": "248289761001",
"name": "Bob Smith",
"given_name": "Bob",
"family_name": "Smith",
"role": [
"user",
"admin"
] }
Lastly
How do yo you specify which users can access to specific resources?
This should most likely be solved through Authorization
which is not the concern of OAuth2 protocol or IdentityServer4. Authorization
is normally handled differently within each application based on problem domain needs. I would recommend to take a look at Policy Server by the creators of Identity Server. They have an excellent video where they delve deeper into this topic and they also have a product to address this problem.
a)When you send the access_token to a protected api, why or when (example) it would need to retrieve some claims about the user who owns it? Maybe if the protected api wants to use some data about the authenticated user?
For example, if your users can be subdivided into organisations or departments and you want to add a policy within your api to only allow access to certain endpoints for when the user is in one of those subdivided groups - you can add a custom claim "organisationid"
or "departmentid
" and add that claim with its value to the tokens that are issued. Whether this is applicable or not, it will depend based on the context of your problem and there is a fine line when the concern of authorization
can mistakenly be attempted to be solved within authentication
.
b) For obtaining the claims the protected api will need to communicate with the UserEdnpoint endpoint? It sends the access_token? And which claims are contained in the returned id_token?/ What happens if it asks for more claims that the user has consent access?
You don't necessarlily need to use UserInfo endpoint. You can set the client property AlwaysIncludeUserClaimsInIdToken
to true and all the claims will be included in the id_token
by default therefore removing the need of the round trip to UserInfo endpoint. If you do end up taking the round trip, you were correct in saying that you need to send access_token
representing the user, however, what is returned is not an id_token
, but rather user info.
Example from IdentityServer4 docs:
Request: GET /connect/userinfo
Authorization: Bearer {access_token}
Response: HTTP/1.1 200 OK
Content-Type: application/json
{
"sub": "248289761001",
"name": "Bob Smith",
"given_name": "Bob",
"family_name": "Smith",
"role": [
"user",
"admin"
] }
Lastly
How do yo you specify which users can access to specific resources?
This should most likely be solved through Authorization
which is not the concern of OAuth2 protocol or IdentityServer4. Authorization
is normally handled differently within each application based on problem domain needs. I would recommend to take a look at Policy Server by the creators of Identity Server. They have an excellent video where they delve deeper into this topic and they also have a product to address this problem.
edited Jan 4 at 11:01
answered Jan 2 at 16:21
Vidmantas BlazeviciusVidmantas Blazevicius
2,2382419
2,2382419
@question b // i think you wrote a mistake => access_token sent , right?
– Badulake
Jan 4 at 10:19
@Badulake yes, good spot. I've seen your other question too - yes, I have some projects using PolicyServer in production so it is definitely worthwhile looking into. In general, I would suggest at looking at defaultAuthorizationPolicy
framework in ASP.NET Core. If that doesn't suit your business needs, you can look into external libs likePolicyServer
. If that doesn't work - you need to create your own business logic. It is unlikely you will get a concrete answer on StackOverflow for this as you need to understand the problem domain very well to identify what suits best.
– Vidmantas Blazevicius
Jan 4 at 11:04
Your help is being awesome. Many thanks!!!!!
– Badulake
Jan 4 at 11:26
@Badulake no problems, happy to help.
– Vidmantas Blazevicius
Jan 4 at 11:50
add a comment |
@question b // i think you wrote a mistake => access_token sent , right?
– Badulake
Jan 4 at 10:19
@Badulake yes, good spot. I've seen your other question too - yes, I have some projects using PolicyServer in production so it is definitely worthwhile looking into. In general, I would suggest at looking at defaultAuthorizationPolicy
framework in ASP.NET Core. If that doesn't suit your business needs, you can look into external libs likePolicyServer
. If that doesn't work - you need to create your own business logic. It is unlikely you will get a concrete answer on StackOverflow for this as you need to understand the problem domain very well to identify what suits best.
– Vidmantas Blazevicius
Jan 4 at 11:04
Your help is being awesome. Many thanks!!!!!
– Badulake
Jan 4 at 11:26
@Badulake no problems, happy to help.
– Vidmantas Blazevicius
Jan 4 at 11:50
@question b // i think you wrote a mistake => access_token sent , right?
– Badulake
Jan 4 at 10:19
@question b // i think you wrote a mistake => access_token sent , right?
– Badulake
Jan 4 at 10:19
@Badulake yes, good spot. I've seen your other question too - yes, I have some projects using PolicyServer in production so it is definitely worthwhile looking into. In general, I would suggest at looking at default
AuthorizationPolicy
framework in ASP.NET Core. If that doesn't suit your business needs, you can look into external libs like PolicyServer
. If that doesn't work - you need to create your own business logic. It is unlikely you will get a concrete answer on StackOverflow for this as you need to understand the problem domain very well to identify what suits best.– Vidmantas Blazevicius
Jan 4 at 11:04
@Badulake yes, good spot. I've seen your other question too - yes, I have some projects using PolicyServer in production so it is definitely worthwhile looking into. In general, I would suggest at looking at default
AuthorizationPolicy
framework in ASP.NET Core. If that doesn't suit your business needs, you can look into external libs like PolicyServer
. If that doesn't work - you need to create your own business logic. It is unlikely you will get a concrete answer on StackOverflow for this as you need to understand the problem domain very well to identify what suits best.– Vidmantas Blazevicius
Jan 4 at 11:04
Your help is being awesome. Many thanks!!!!!
– Badulake
Jan 4 at 11:26
Your help is being awesome. Many thanks!!!!!
– Badulake
Jan 4 at 11:26
@Badulake no problems, happy to help.
– Vidmantas Blazevicius
Jan 4 at 11:50
@Badulake no problems, happy to help.
– Vidmantas Blazevicius
Jan 4 at 11:50
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54006026%2fopen-id-connect-doubts-identity-server-4-how-to-grant-specific-users-to-con%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You are falling into the trap of solving concerns of "Authorization" within IdentityServer which is meant to help solve concerns of "Authentication". Aka, validating that the user/machine is who they say they are. I would recommend to look into "PolicyServer" that the creators of IdentityServer have also produced. They also have a nice youtube video (don't have link at hand) discussing these boundaries between concerns.
– Vidmantas Blazevicius
Jan 2 at 15:27
Ok , many thanks, will you be so nice to answer my questions too? :) :)
– Badulake
Jan 2 at 15:59
2
Scopes are only what a client application has been authorized to do. It has no effect on what a user is allowed to do: auth0.com/blog/on-the-nature-of-oauth2-scopes You'll want a different solution for user authorization.
– Scott Brady
Jan 3 at 8:38
@ScottBrady do you recommend me some solution in .net for that purpose?
– Badulake
Jan 3 at 13:43
1
You could give PolicyServer a go: policyserver.io Other than that, I typically recommend keeping user authorization decisions within the client apps/protected resources themselves
– Scott Brady
Jan 3 at 15:53