simpleidserver / SimpleIdServer

OpenID, OAuth 2.0, SCIM2.0, UMA2.0, FAPI, CIBA & OPENBANKING Framework for ASP.NET Core
https://simpleidserver.com/
Apache License 2.0
686 stars 90 forks source link

[question]Some questions about configuring roles and claims #632

Closed qq1176914912 closed 7 months ago

qq1176914912 commented 7 months ago

Sorry to bother you, I need to consult with some questions.

  1. When configuring 'clients', there is an option for' roles'. After I configure it, the user client logs in to access_ There is no such character in the token, so what is the purpose of this option and how should it be used? image
  2. When configuring 'Users', there are' Claims' and 'Groups' options. After I configure them, I use this account to log in to my client and access the API. The API will retrieve User. Claims, but the obtained Claims do not have the values I set. How do I use these two options? image

So what do I need to do to get the roles or groups?

simpleidserver commented 7 months ago

How to Assign Roles to a User ?

When a role is added to a client, a new scope named <client_id>\<role_name> is added and assigned to the client.

Once the role is defined, you can create a group and assign roles to it. Follow these instructions:

  1. On the Groups screen, click on the Add group button, fill in the form, and click on the Submit button.
  2. Click on the new group and navigate to the Roles tab.
  3. Click on the Add Role button, select your role, and click on the Save button.

Now, there is a group configured with one role; you can assign it to the User.

  1. On the Users screen, select the User and navigate to the Groups tab.
  2. Click on the Assign groups button and assign one or more groups.
  3. Navigate to the Claims tab, click on the Resolve roles checkbox, and check if the roles are displayed in the table.

How to Add Custom Claims to the id_token ?

In SimpleIdServer, you can define an Identity Scope with one or more Mapping Rules. These rules are used to retrieve user information and convert it into a list of claims that will be included in the Identity Token.

To return your custom testclaims into the Identity Token, you must create a SCOPE with one mapping rule:

  1. On the Scopes screen, click on the Add scope button.
  2. Select Identity Value and click on next.
  3. Fill in the form like this and click on the Save button to confirm the creation.
Parameter Value
name test
description test
protocol openid
Is Exposed false
  1. Navigate to the new scope, click on the Mappers tab, and click on the Add mapper button.
  2. Select Attribute and click on next.
  3. Fill in the form like this and click on the Save button to confirm the creation.
Parameter Value
name test
token claim name test
claim json type string
user attribute testclaims

Now the scope is configured; you can pass it into the authorization request. The value of thetestclaims claim will be passed into the identity token.

qq1176914912 commented 7 months ago

How to Assign Roles to a User ?

When a role is added to a client, a new scope named <client_id>\<role_name> is added and assigned to the client.

Once the role is defined, you can create a group and assign roles to it. Follow these instructions:

  1. On the Groups screen, click on the Add group button, fill in the form, and click on the Submit button.
  2. Click on the new group and navigate to the Roles tab.
  3. Click on the Add Role button, select your role, and click on the Save button.

Now, there is a group configured with one role; you can assign it to the User.

  1. On the Users screen, select the User and navigate to the Groups tab.
  2. Click on the Assign groups button and assign one or more groups.
  3. Navigate to the Claims tab, click on the Resolve roles checkbox, and check if the roles are displayed in the table.

How to Add Custom Claims to the id_token ?

In SimpleIdServer, you can define an Identity Scope with one or more Mapping Rules. These rules are used to retrieve user information and convert it into a list of claims that will be included in the Identity Token.

To return your custom testclaims into the Identity Token, you must create a SCOPE with one mapping rule:

  1. On the Scopes screen, click on the Add scope button.
  2. Select Identity Value and click on next.
  3. Fill in the form like this and click on the Save button to confirm the creation.

Parameter Value name test description test protocol openid Is Exposed false

  1. Navigate to the new scope, click on the Mappers tab, and click on the Add mapper button.
  2. Select Attribute and click on next.
  3. Fill in the form like this and click on the Save button to confirm the creation.

Parameter Value name test token claim name test claim json type string user attribute testclaims Now the scope is configured; you can pass it into the authorization request. The value of thetestclaims claim will be passed into the identity token.

  1. Sorry, I did not succeed in following your prompt Following your method, a scope was added: image The user's configuration is as follows: image And I also added this scope to the client: image And I added this scope to my client project: image Disappointingly, after logging in with my test account, the token I obtained did not have the set content The content of the Accesstoken is: image The content of idtoken is: image
  2. I also discovered another issue. Clicking on 'client scopes' in' clients' and clicking on the 'Name' of any 'Scope' will cause 'unknown scope' to appear in the upper right corner after jumping to the corresponding 'Scope' image
simpleidserver commented 7 months ago

This is the expected behavior as per the OPENID RFC. When the authorization code grant type is used, the id_token does not contain the user's claims. Instead, the website utilizes the access token to retrieve the user's claims from the userinfo API.

Could you please verify on your website whether the claims are present in the User.Claims property?

I have created a bug ticket, #633, to address the issue of "unknown scopes address`.

simpleidserver commented 7 months ago

@qq1176914912 : The issue #633 (unknown scopes address) is fixed in the master branch.

qq1176914912 commented 7 months ago

This is the expected behavior as per the OPENID RFC. When the authorization code grant type is used, the id_token does not contain the user's claims. Instead, the website utilizes the access token to retrieve the user's claims from the userinfo API.

Could you please verify on your website whether the claims are present in the User.Claims property?

I have created a bug ticket, #633, to address the issue of "unknown scopes address`.

I have roughly understood that if I want to obtain a user role and perform access control as shown in the following figure, I need to manually call the userinfo API before authorization, obtain the user role, and then manually add the role to the claims image

qq1176914912 commented 7 months ago

I have successfully implemented the functionality I need, and I customized a method before authorizing the API project: image In this method, call userinfo to query the role, and then add the role to the claims image Declaration of authorization for roles on API interface, successful testing image

This is a way I came up with, I'm not sure if there are any other ways

qq1176914912 commented 7 months ago

There is another question, what is the session in the user, and I see that they can reject it. What is the specific rejection function? If the user is already logged in and I reject it from here, the user will not redirect to the login page, so I want to know what can be done here image

simpleidserver commented 7 months ago

@qq1176914912

Custom Middleware

There is no need to implement custom middleware to retrieve claims from the userinfo endpoint, as this functionality is already implemented by Microsost.AspNetCore.Authentication.OpenIdConnect. If the property GetClaimsFromUserInfoEndpoint is set to true, the OpenIdConnectHandler class retrieves the claims from the userinfo endpoint: https://github.com/dotnet/aspnetcore/blob/main/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectHandler.cs#L795

Session

The concept of a user's session has been introduced by the RFC OpenID Connect Session Management (1.0) (https://openid.net/specs/openid-connect-session-1_0.html).

In short, when the web application is configured to use RP Initiated Logout, and the session is rejected, the end-user will automatically be disconnected from the Client/Web Application and the Identity Server.

You can follow this tutorial to implement a SPA application with session checks enabled; the source code can be found here: https://github.com/simpleidserver/SimpleIdServer/blob/master/samples/ProjectSPA/src/Website/

qq1176914912 commented 7 months ago

@qq1176914912

Custom Middleware

There is no need to implement custom middleware to retrieve claims from the userinfo endpoint, as this functionality is already implemented by Microsost.AspNetCore.Authentication.OpenIdConnect. If the property GetClaimsFromUserInfoEndpoint is set to true, the OpenIdConnectHandler class retrieves the claims from the userinfo endpoint: https://github.com/dotnet/aspnetcore/blob/main/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectHandler.cs#L795

Session

The concept of a user's session has been introduced by the RFC OpenID Connect Session Management (1.0) (https://openid.net/specs/openid-connect-session-1_0.html).

In short, when the web application is configured to use RP Initiated Logout, and the session is rejected, the end-user will automatically be disconnected from the Client/Web Application and the Identity Server.

You can follow this tutorial to implement a SPA application with session checks enabled; the source code can be found here: https://github.com/simpleidserver/SimpleIdServer/blob/master/samples/ProjectSPA/src/Website/

Custom Middleware Yes, what you said is correct. I checked your source code in the "SimpleIdServer. OpenIdConnect" project and found this judgment: image But I found that it only references it in your 'SimpleIdServer. IdServer. Startup' project image Your method only determines this property when I log in to your 'SimpleIdServer. IdServer. Website. Startup' project, but when I log in to my custom client (using only the IdServer project), it does not determine this property, which results in even if I configure 'Options' on my client GetClaimsFromUserInfoEndpoint=true ', I am also unable to obtain this role.

I referred to this project: https://github.com/IdentityServer/IdentityServer4/tree/4dc10e665f5ede63274427036c25cdc216130eb9/samples/Quickstarts/5_EntityFramework I found that he referenced a class library name similar to yours in the 'IdentityServer' project: image So I would like to know if your 'SimpleIdServer. OpenIdConnect' class library can be placed in the 'SimpleIdServer. IdServer. Startup' project. If you don't plan to do this, So I can follow your example and add a custom method on IDS. Before generating the token, I need to query the userinfo and add the role to the claims. This ensures that the generated token contains the role image

Session I found in your 'Website' project that 'Backchannel Logout URL' can be configured for clients. Based on my understanding, this is what you call RP Logout, image If that's the case, I added an interface for exiting in the client image When I successfully logged in to my client and logged in to your 5001 (also known as the ids project) again, I logged out this user on the ids project. However, my client's interface did not receive any content, meaning that the Backchannel Logout URL configured for your project did not take effect. Just in case, I also configured the Backchannel Logout URL in the ids4 example project. When I logged out this user on his ids, My client interface successfully received the content, so I'm not sure if there is a problem with your project here.

qq1176914912 commented 7 months ago

Thanks for your hard work..I have discovered a problem.When I set BackChannelLogoutUri in the client image When I use my client to exit, clicking on 'Revoke session' will result in an error: image image I also configured BackChannelLogoutUri on my IDS4 sample project, but I did not encounter this issue when I exited, so I think this issue lies in the logic of the 'Revoke session'

simpleidserver commented 7 months ago

Role:

By default, when using the Microsoft.AspNetCore.Authentication.OpenIdConnect NuGet Package, the role claim is not returned. To retrieve this claim from the userinfo endpoint, add the following code:

.AddOpenIdConnect("sid", options =>
{
    ...
    options.GetClaimsFromUserInfoEndpoint = true;
    options.Scope.Add("role");
    options.ClaimActions.MapJsonKey("role", "role");
    ...
});

Session:

You received this exception because the TokenSignedResponseAlg parameter is not configured in your client. I made some changes in the master branch to provide the ability to update this parameter in the UI. To do so:

This parameter is necessary to build and sign the Logout Token.

The sample project https://github.com/simpleidserver/SimpleIdServer/tree/master/samples/ProtectWebsiteServerside has been updated to support Logout functionality and also to retrieve the role claim from the userinfo endpoint.

Feel free to explore this project! :)

qq1176914912 commented 7 months ago

Role:

By default, when using the Microsoft.AspNetCore.Authentication.OpenIdConnect NuGet Package, the role claim is not returned. To retrieve this claim from the userinfo endpoint, add the following code:

.AddOpenIdConnect("sid", options =>
{
  ...
    options.GetClaimsFromUserInfoEndpoint = true;
    options.Scope.Add("role");
    options.ClaimActions.MapJsonKey("role", "role");
  ...
});

Session:

You received this exception because the TokenSignedResponseAlg parameter is not configured in your client. I made some changes in the master branch to provide the ability to update this parameter in the UI. To do so:

  • Navigate to the Clients screen
  • Select your client and go to the Advanced tab.
  • Set the token signature algorithm to RS256 and click on Update.

This parameter is necessary to build and sign the Logout Token.

The sample project https://github.com/simpleidserver/SimpleIdServer/tree/master/samples/ProtectWebsiteServerside has been updated to support Logout functionality and also to retrieve the role claim from the userinfo endpoint.

Feel free to explore this project! :)

  1. Regarding the 'Backchannel Logout URL' configured by the client, the normal logic should be that I have configured this address. On the same browser, when logging into my client and accessing the address of the ids (5001 for your project), there is no need to log in again. When I log out of this account on this ids, he should send a message to the 'Backchannel Logout URL' address I have configured, And this address can be the Signout for the project you provided, so that I can ensure that in the same browser, if I log out of this account on IDS, my colleagues who log in to this account will also log out of the client. Unfortunately, when I tried to test this feature with your project, I found that he did not send a message to the 'Backchannel Logout URL' address I configured.Alternatively, you not only need to configure the 'Backchannel Logout URL' here, but you also need to configure other things for it to take effect.
  2. Have you ever considered that when you click 'Reject' in 'Users' ->' Sessions', the client logged in with this account will also exit. Currently, I have found that it does not support it.After testing, it was found that when 'Reject' is clicked, the account on ids (5001) will automatically exit.Perhaps it can be linked to the 'Backchannel Logout URL', but I am missing other configurations. image
simpleidserver commented 7 months ago

Firstly, thank you for your feedback; it is very valuable for us to enhance our product :)

The implementation is currently missing, and I am actively working on it in the Ticket624 branch

qq1176914912 commented 7 months ago

Firstly, thank you for your feedback; it is very valuable for us to enhance our product :)

The implementation is currently missing, and I am actively working on it in the Ticket624 branch

So, regarding the issue of 'Backchannel Logout URL' not working, is it also not implemented on your end?

simpleidserver commented 7 months ago

The BackChannel Logout URL has already been implemented in SimpleIdServer.

However, I noticed two issues:

Once the changes are merged into the master branch, I will send you a sample project.

Currently, SimpleIdServer only supports access tokens in JWT format. Other formats, such as Reference, are not yet supported because they are not standard attributes in OAuth 2.0. I have created a new ticket, #640, to address the support for the Reference format.

qq1176914912 commented 7 months ago

By default, when using the Microsoft.AspNetCore.Authentication.OpenIdConnect NuGet Package, the role claim is not returned. To retrieve this claim from the userinfo endpoint, add the following code:

Role: Following your method, I successfully displayed the role on the client front-end: image image But the problem is that whether it is the accesstoken or the idtoken, the role is still not included. What I need is to make the accesstoken include the role.

qq1176914912 commented 7 months ago

The BackChannel Logout URL has already been implemented in SimpleIdServer.

However, I noticed two issues:

Once the changes are merged into the master branch, I will send you a sample project.

Currently, SimpleIdServer only supports access tokens in JWT format. Other formats, such as Reference, are not yet supported because they are not standard attributes in OAuth 2.0. I have created a new ticket, #640, to address the support for the Reference format.

The problem is not just with session rejection here, you can try it out. Normally, if the 'Backchannel Logout URL' is configured, if you log in to the client in the same browser and access ids (5001) in the same browser, and exit the account on ids, It should also trigger a request to this address (I referred to Identity Server 4 and configured the Backchannel Logout URL using its ids and tested it), but in actual use, your project did not trigger it.

simpleidserver commented 7 months ago

@Role :

According to the OPENID specification, it is normal for the id_token not to contain the requested claims. Claims are returned in the id_token when the response_type is equal to id_token.

Test Plan : https://www.certification.openid.net/log-detail.html?log=4wDrNyZLDgxFUKg&public=true

URL : https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims

When a response_type value is used that results in an Access Token being issued. However, when no Access Token is issued (which is the case for the response_type value id_token), the resulting Claims are returned in the ID Token.

At the moment, roles are only returned in the id_token because there is no requirement from the OPENID standard to return them into the access token. However, I can understand this requirement, and I have created a new ticket #641 to add the mapping into the API Resource.

@Session :

It is working on my local machine; can you please follow these steps:

  1. Get the latest changes in the master branch.
  2. Run the administration website and add a new client.
  3. On the Clients, screen, click on the Add client button.
  4. Select web application and click on next.
  5. Fill-in the form link this and click on the Save button to confirm the creation.
Parameter Value
Identifier protectedServersideApp
Secret password
Name protectedServersideApp
Redirection URLs http://localhost:7000/signin-oidc
  1. Navigate to the new client and update the following properties :
Parameter Value
Back Channel Logout session required Checked
Backchannel logout url http://localhost:7000/BackChannelLogout/Logout
Validation post logout redirect URIs http://localhost:7000/signout-callback-oidc
  1. Assign the role scope.
  2. Navigate to the sample project samples\ProtectWebsiteServerside\src\Website\ and run it.
  3. Browse the URL http://localhost:7000/claims and authenticate with your credentials.
  4. Click on the Logout button and click on Revoke button. The endpoint http://localhost:7000/BackChannelLogout/Logout will be called by SimpleIdServer.

I also tested with the sample project from Duende (successor of IdServer), and it is working : https://github.com/DuendeSoftware/Samples/tree/main/IdentityServer/v7/SessionManagement/BackChannelClient

qq1176914912 commented 7 months ago

@ROLE :

According to the OPENID specification, it is normal for the id_token not to contain the requested claims. Claims are returned in the id_token when the response_type is equal to id_token.

Test Plan : https://www.certification.openid.net/log-detail.html?log=4wDrNyZLDgxFUKg&public=true

URL : https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims

When a response_type value is used that results in an Access Token being issued. However, when no Access Token is issued (which is the case for the response_type value id_token), the resulting Claims are returned in the ID Token.

At the moment, roles are only returned in the id_token because there is no requirement from the OPENID standard to return them into the access token. However, I can understand this requirement, and I have created a new ticket #641 to add the mapping into the API Resource.

@Session :

It is working on my local machine; can you please follow these steps:

  1. Get the latest changes in the master branch.
  2. Run the administration website and add a new client.
  3. On the Clients, screen, click on the Add client button.
  4. Select web application and click on next.
  5. Fill-in the form link this and click on the Save button to confirm the creation.

Parameter Value Identifier protectedServersideApp Secret password Name protectedServersideApp Redirection URLs http://localhost:7000/signin-oidc

  1. Navigate to the new client and update the following properties :

Parameter Value Back Channel Logout session required Checked Backchannel logout url http://localhost:7000/BackChannelLogout/Logout Validation post logout redirect URIs http://localhost:7000/signout-callback-oidc

  1. Assign the role scope.
  2. Navigate to the sample project samples\ProtectWebsiteServerside\src\Website\ and run it.
  3. Browse the URL http://localhost:7000/claims and authenticate with your credentials.
  4. Click on the Logout button and click on Revoke button. The endpoint http://localhost:7000/BackChannelLogout/Logout will be called by SimpleIdServer.

I also tested with the sample project from Duende (successor of IdServer), and it is working : https://github.com/DuendeSoftware/Samples/tree/main/IdentityServer/v7/SessionManagement/BackChannelClient

ROLE : Yes, I need the accesstoken to be able to carry a role, because the client accesses the API with the accesstoken (jwt). It seems that I can only use the custom middleware mentioned earlier to add a role to the claims through userinfo. You can try the project you mentioned“ https://github.com/DuendeSoftware/Samples/tree/main/IdentityServer/v7/SessionManagement/BackChannelClient ”He only needs to do the following to add a role in the accesstoken:

  1. Add roles to users in TestUsers.cs in ids image
  2. Add the following content to Resources.cs image Don't touch anything else, log in to the client using a user with a set role, and the role can be carried in the accesstoken: image

Session: You are right. Currently, your program exits from the client and clicking 'Revoke' can trigger the set Backchannel Logout URL normally, but you have not attempted this operation:

  1. Log in to the client in the browser

  2. After the client login is completed, open a new page in the current browser to access the 5001/master page

  3. Exit the current user on 5001/master

In this situation, you will not trigger the 'Backchannel Logout URL'

You can try what you said‘ https://github.com/DuendeSoftware/Samples/tree/main/IdentityServer/v7/SessionManagement/BackChannelClient ’The project can still trigger the 'Backchannel Logout URL' when exiting the user on 5001, rather than having to click on 'Logout' on the client to trigger it. image image image

simpleidserver commented 7 months ago

My apologies, the session was not ending when the end-user clicked on the 'Logout' button on the IdServer website (https://localhost:5001/master). This issue has now been resolved in the 'master' branch.

Additionally, I have created tickets for the following issues:

You can track their progress on the project board: https://github.com/users/simpleidserver/projects/6/views/1

qq1176914912 commented 7 months ago

My apologies, the session was not ending when the end-user clicked on the 'Logout' button on the IdServer website (https://localhost:5001/master). This issue has now been resolved in the 'master' branch.

Additionally, I have created tickets for the following issues:

You can track their progress on the project board: https://github.com/users/simpleidserver/projects/6/views/1

Thank you very much for your patient answer during this period.