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

[bug]Session expired, session not ended #648

Closed qq1176914912 closed 6 months ago

qq1176914912 commented 7 months ago

Under normal circumstances, when the session has not expired, that is, when the account session does not display 'Expired', when I click the exit button on the client, I will be redirected to your 5001 page. To complete the user's exit, I need to click 'Revoke session'.

After testing, I found that when the client is configured with the 'Backchannel logout URL' and the session expires,which is when the session displays "Expired", when I refresh the client, it does not automatically redirect to the login page, but can be accessed normally. Moreover, when I click to exit, it does not show a "Revoke session" of 5001, but directly redirects to the login page. Then, I continue to log in, and after successfully logging in, the "Revoke session" button will appear instead, I need to click this button to log in to the client homepage, but there is a problem during this process. If I don't click the 'Revoke session' button after logging in, I will check the sessions in 5002Website and you will find that their 'Clients' are empty. image When I click the 'Revoke session' button and log in to the client, I can see that the sid used by the client here is still the same as before. image image If this browser is not closed and a new browser is opened, this phenomenon will persist when accessing the client, and the session ID that originally expired will always be used.I tested this using‘ https://github.com/duendesoftware/samples/tree/main/identityserver/v7/sessionmanagement/backchannelclient ’.I'm not sure if it's related to the logic of this project. I'm not sure if the client should exit after the session expires, but the current situation is definitely not right.

There is another situation where when the client's Backchannel logout URL is not set, I first log in to the client in the same browser, and then access it after a successful login‘ https://localhost:5001/master ’On 5001, I logged out the newly logged in user. When I clicked on the exit button on the client, it still redirected directly to the login page without displaying a 'Revoke session'. When I tried to log in again, the first thing that appeared was' Revoke session '. However, this time when I clicked on' Revoke session ', it would redirect back to the login page, meaning that I had to log in twice to log in normally, This will not result in using the same SID as mentioned above.However, in the 5002 session, there will still be a record with empty clients.

simpleidserver commented 7 months ago

I noticed two problems and both are fixed in the master branch:

Can you fetch the latest changes from the master and try again

qq1176914912 commented 7 months ago

I noticed two problems and both are fixed in the master branch:

  • When the session expires, clients are not notified. I added a Hangfire job to automatically notify clients when the session expires.
  • If the client does not have a Back Channel Logout Redirect URL and the session expires, clicking on the 'Disconnect' button redirects the end-user to the Login page instead of the client.

Can you fetch the latest changes from the master and try again

I have tested your new version and it still has issues. Firstly, I am still using the same project:“ https://github.com/duendesoftware/samples/tree/main/identityserver/v7/sessionmanagement/backchannelclient ”, Existing problems

  1. When the session expires, the project has not been logged out and clicking logout will not be able to log out. 'Secure' again will still display the previous login information,After testing, it was found that regardless of whether the Backchannel logout URL is configured or not, it cannot be exited

  2. The 'Backchannel logout URL' function is no longer working. Whether it is rejecting at session or exiting the account on 5001, the 'Backchannel logout URL' cannot receive messages and causes the client to exit

problem You can see that when the backchannelclient project is successfully logged in, there is a 'Refresh token' button, and the address of this method is: image If it's your project, how can I request a 'Refresh token'

recommendation Regarding session expiration, it is recommended that you add an option to set the session expiration time so that when testing, you can manually change the expiration time without restarting the project.

simpleidserver commented 7 months ago

I have tested the BackChannelClient, and everything is functioning correctly with the latest changes made on the master branch.

Could you please check the following points:

  1. Have you updated the discovery URL in the LogoutController class ?

Replace the following code:

var disco = await client.GetDiscoveryDocumentAsync("https://localhost:5001");

With

var disco = await client.GetDiscoveryDocumentAsync("https://localhost:5001/master");
  1. In the administration website, verify whether the client mvc.backchannel.sample has the Refresh Token grant-type.

image

  1. Replace the URL https://localhost:5001/connect/token with https://localhost:5001/master/token.

The session's lifetime can be updated in the client view. Navigate to the Advanced Tab and update the Token Expiration time field.

image

qq1176914912 commented 7 months ago

I have tested the BackChannelClient, and everything is functioning correctly with the latest changes made on the master branch.

Could you please check the following points:

  1. Have you updated the discovery URL in the LogoutController class ?

Replace the following code:

var disco = await client.GetDiscoveryDocumentAsync("https://localhost:5001");

With

var disco = await client.GetDiscoveryDocumentAsync("https://localhost:5001/master");
  1. In the administration website, verify whether the client mvc.backchannel.sample has the Refresh Token grant-type.

image

  1. Replace the URL https://localhost:5001/connect/token with https://localhost:5001/master/token.

The session's lifetime can be updated in the client view. Navigate to the Advanced Tab and update the Token Expiration time field.

image

After my testing, it still doesn't work. This is the configuration of my client: image image I added a sentence in the client logout interface: image When I rejected the session on 5002, the logout interface did not output Enter exit logic, which proves that he did not receive the message. Then I will use the project you previously submitted in "Dec 2, 2023" and the same database as the latest project. The old project will successfully notify the "Backchannel logout URL" and output "Enter exit logic". So where did the problem occur? Before you fix this problem: https://github.com/simpleidserver/SimpleIdServer/issues/648#issue-2027733047 , it can still be used normally

And I also found that the 5001 project keeps prompting this error. I found that this is the address of one of my clients, and the problem is that I am not using this client. Why does he keep prompting this error. image

simpleidserver commented 7 months ago

There is still an issue, because if at least one client in the session is not online, then the IdServer cannot call the endpoint Back Channel Logout URL to invalidate the session.

This issue is now fixed in the master branch.

qq1176914912 commented 7 months ago

There is still an issue, because if at least one client in the session is not online, then the IdServer cannot call the endpoint Back Channel Logout URL to invalidate the session.

This issue is now fixed in the master branch.

Are you sure you have fixed it? I downloaded the updated version of 'Dec 12, 2023' from your 'master', but it still has an issue and the 'Backchannel logout URL' is still not effective. Whether it is rejecting the session on 5002 or logging out on 5001, the client has not been notified. image

If there is indeed no problem with the Backchannel logout URL from your end, if it is convenient for you, this is my SQL file (please remove the. txt at the end). I am not sure if it is a problem with my configuration, and I really don't know where the problem is. __EFMigrationsHistory.sql.txt

simpleidserver commented 7 months ago

Can-you stop the application, execute this SQL Instruction and try again ?

UPDATE public."UserSession" SET "IsClientsNotified" = true
qq1176914912 commented 6 months ago

Can-you stop the application, execute this SQL Instruction and try again ?

UPDATE public."UserSession" SET "IsClientsNotified" = true

Following your instructions, everything is now working. Thank you for your patient assistance. Can you add a reject all button on the session page? If there are too many clients logged in to this account, it may be troublesome to kick them out one by one.I tried to add it myself before, rejecting all operations at the interface where you reject a single session. However, due to your recent changes in the logic of rejecting a single session, I don't know how to change it.

qq1176914912 commented 6 months ago

There is another question. I want to release the project to someone else who doesn't have a database installed on their computer, but I want them to use the things in my database. I know I can put my SQL file in the project to ensure that they are using the content of my database, but how to read this SQL file is a problem, just like the MDF file mentioned on Microsoft's official website: https://learn.microsoft.com/zh-cn/visualstudio/data-tools/add-new-connections?view=vs-2022
What I want to ask is, if I need to modify your project if I use MDF to read the database.

simpleidserver commented 6 months ago

To utilize the MDF file in the IdServer solution, follow these steps:

  1. Download the MDF file and place it in the SimpleIdServer.IdServer.Startup project.
  2. Edit the appsettings.json file.
  3. Set the properties DistributedCacheConfiguration.Type and StorageConfiguration.Type to SQLSERVER.
  4. Set the properties DistributedCacheConfiguration.ConnectionString and StorageConfiguration.ConnectionString to Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=<MDF_FILE_PATH>;Integrated Security=True;Connect Timeout=30. Be sure to replace the MDF_FILE_PATH variable with the full path of the MDF File.

By the way, I made some modifications in the master branch to revoke all sessions of a user :)

qq1176914912 commented 6 months ago

To utilize the MDF file in the IdServer solution, follow these steps:

  1. Download the MDF file and place it in the SimpleIdServer.IdServer.Startup project.
  2. Edit the appsettings.json file.
  3. Set the properties DistributedCacheConfiguration.Type and StorageConfiguration.Type to SQLSERVER.
  4. Set the properties DistributedCacheConfiguration.ConnectionString and StorageConfiguration.ConnectionString to Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=<MDF_FILE_PATH>;Integrated Security=True;Connect Timeout=30. Be sure to replace the MDF_FILE_PATH variable with the full path of the MDF File.

By the way, I made some modifications in the master branch to revoke all sessions of a user :)

Thank you, I found a way to configure sqlite in my previous questions: https://github.com/simpleidserver/SimpleIdServer/issues/611#issuecomment-1798541019 Because I am using a PostgreSQL database, I do not have an MDF file, so I would like to try sqlite .I see in your source code that it is written as follows: image Regarding the parameters of MigrationsAssembly, I see that all the parameters here correspond to a class library in your project: image If I want to use sqlite , should I also create a similar class library?I think sqlite is very suitable for demonstration projects because you don't need to connect to a remote database and can also use pre configured database data.

qq1176914912 commented 6 months ago

This is my configuration file: image Why does this error appear after the project starts when I use the SQLSERVER database: image The connection address I configured did not mention IdServer, which is why.

qq1176914912 commented 6 months ago

Have you updated the "Backchannel logout"? I have found that even if Advanced>Token signature algorithm is not configured as rs256 in the client, the issue mentioned in this question will not occur now:https://github.com/simpleidserver/SimpleIdServer/issues/632#issuecomment-1818402839

simpleidserver commented 6 months ago

SQL Exception:

There is an issue in the Program.cs file. Can you please replace the SQL query ALTER DATABASE IdServer SET ALLOW_SNAPSHOT_ISOLATION ON with ALTER DATABASE CURRENT SET ALLOW_SNAPSHOT_ISOLATION ON?

Token Signature Algorithm:

If the algorithm for the token signature is not set for the client, then the property DefaultTokenSignedResponseAlg from IdServerHostOptions class will be used.

SQLITE :

To configure SQLite, please follow the steps below:

  1. Create a new project with the name SimpleIdServer.IdServer.SqliteMigrations and install the Nuget package dotnet add package Microsoft.EntityFrameworkCore.Sqlite.
  2. Add a reference to this new project.
  3. Edit the StorageConfiguration file and add SQLITE to the StorageTypes enumeration.
  4. Edit the Program.cs file and add the following instruction in the ConfigureStorage method.
case StorageTypes.SQLITE:
    b.UseSqlite(conf.ConnectionString, o =>
    {
        o.MigrationsAssembly("SimpleIdServer.IdServer.SqliteMigrations");
        o.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
    });
    break;
  1. Edit the appsettings.json and set the property StorageConfiguration.Type to SQLITE.
  2. Finally, execute the following command line to create the migration scripts:
dotnet ef migrations add Init --project ../SimpleIdServer.IdServer.SqliteMigrations
qq1176914912 commented 6 months ago

SQL Exception:

There is an issue in the Program.cs file. Can you please replace the SQL query ALTER DATABASE IdServer SET ALLOW_SNAPSHOT_ISOLATION ON with ALTER DATABASE CURRENT SET ALLOW_SNAPSHOT_ISOLATION ON?

Token Signature Algorithm:

If the algorithm for the token signature is not set for the client, then the property DefaultTokenSignedResponseAlg from IdServerHostOptions class will be used.

SQLITE :

To configure SQLite, please follow the steps below:

  1. Create a new project with the name SimpleIdServer.IdServer.SqliteMigrations and install the Nuget package dotnet add package Microsoft.EntityFrameworkCore.Sqlite.
  2. Add a reference to this new project.
  3. Edit the StorageConfiguration file and add SQLITE to the StorageTypes enumeration.
  4. Edit the Program.cs file and add the following instruction in the ConfigureStorage method.
case StorageTypes.SQLITE:
    b.UseSqlite(conf.ConnectionString, o =>
    {
        o.MigrationsAssembly("SimpleIdServer.IdServer.SqliteMigrations");
        o.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
    });
    break;
  1. Edit the appsettings.json and set the property StorageConfiguration.Type to SQLITE.
  2. Finally, execute the following command line to create the migration scripts:
dotnet ef migrations add Init --project ../SimpleIdServer.IdServer.SqliteMigrations

SQL Exception:

Yes, according to what you said, changing the content in Program.cs will prevent this error. Are you considering changing this content in your project. SQLITE :

Yes, according to what you said, you can use the SQLITE database, but it is not complete enough. I will write down the complete process at the end for beginners like me to use. new problems:

I found that when I log in to a new client, if I click "reject" on the authorization page, an error message will appear: CERJO`YAP$LI{0 225GJ39 $5}H}799APJ}9DX}1OP2 V7

qq1176914912 commented 6 months ago

The following is the process I completed using the sqlite database:

1、Start by creating a new class library project named "SimpleIdServer.IdServer.SqliteMigrations" under the Migrations directory.

2、Create the class library project, and it is recommended to place the library in the src\IdServer\ directory.

3、Install the NuGet package "Microsoft.EntityFrameworkCore.Sqlite" for the new library, and make sure to use version 7. If you install the latest version 8, it may result in compatibility errors, preventing the successful installation of the package.

4、Add a reference to the "SimpleIdServer.IdServer.Store" project for the new library.

5、In the "SimpleIdServer.IdServer.Startup" project, add a reference to the newly created library project.

6、In the 'StorageConfiguration.cs' file of the "SimpleIdServer.IdServer.Startup" project, add "SQLITE."

7、In the "Program.cs" file of the "SimpleIdServer.IdServer.Startup" project, within the "ConfigureStorage" method, add the following content:

case StorageTypes.SQLITE: b.UseSqlite(conf.ConnectionString, o => { o.MigrationsAssembly("SimpleIdServer.IdServer.SqliteMigrations"); o.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery); }); break;

8、Modify the "appsettings.json" file in the "SimpleIdServer.IdServer.Startup" project under "StorageConfiguration" to change "Type" to "SQLITE" and "ConnectionString" to "Data Source=yourdatabasename.db," where 'yourdatabasename' is the desired name for the generated database.

"StorageConfiguration": { "Type": "SQLITE", "ConnectionString": "Data Source=yourdatabasename.db" }

9、Right-click on the newly created library "SimpleIdServer.IdServer.SqliteMigrations" and choose "Rebuild."

10、Right-click on the "SimpleIdServer.IdServer.Startup" project and select "Open in Terminal."

11、In the terminal, enter the following command and press Enter:

dotnet ef migrations add Init --project ../SimpleIdServer.IdServer.SqliteMigrations

12、Wait for completion, and if there are no errors along the way, you can now use the SQLite database.

simpleidserver commented 6 months ago

When the user rejects consent, an error with the code 'access_denied' and the description 'access has been revoked by the resource owner' is returned to the client. According to the RFC, https://openid.net/specs/openid-connect-basic-1_0.html, this is the expected behavior.

A UI must be added to the mvc.backchannel.sample client to handle errors received from the IdServer and display the appropriate messages. In the Startup.cs class, you can use the RemoveFailure event to override the default logic :).

options.Events = new Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectEvents
{
    OnRemoteFailure = context =>
    {
        context.Response.Redirect("/");
        context.HandleResponse();
        return Task.FromResult(0);
    }
};

Thank you for the tutorial on SQLITE. I have created a ticket #658 to support SQLITE in SimpleIdServer.

qq1176914912 commented 6 months ago

When the user rejects consent, an error with the code 'access_denied' and the description 'access has been revoked by the resource owner' is returned to the client. According to the RFC, https://openid.net/specs/openid-connect-basic-1_0.html, this is the expected behavior.

A UI must be added to the mvc.backchannel.sample client to handle errors received from the IdServer and display the appropriate messages. In the Startup.cs class, you can use the RemoveFailure event to override the default logic :).

options.Events = new Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectEvents
{
    OnRemoteFailure = context =>
    {
        context.Response.Redirect("/");
        context.HandleResponse();
        return Task.FromResult(0);
    }
};

Thank you for the tutorial on SQLITE. I have created a ticket #658 to support SQLITE in SimpleIdServer.

Understood, thank you for your help.