{"id":13431597,"url":"https://github.com/Xabaril/JWTSimpleServer","last_synced_at":"2025-03-16T12:30:41.868Z","repository":{"id":65414062,"uuid":"119758059","full_name":"Xabaril/JWTSimpleServer","owner":"Xabaril","description":"A lightweight, dynamic jwt server for ASP.NET Core ","archived":true,"fork":false,"pushed_at":"2019-06-26T09:53:51.000Z","size":169,"stargazers_count":194,"open_issues_count":5,"forks_count":30,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-04T20:47:35.552Z","etag":null,"topics":["asp-net-core","jwt-claims","jwt-client","jwt-server","netcore2","typescript-library"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Xabaril.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-31T23:46:49.000Z","updated_at":"2024-11-28T01:16:16.000Z","dependencies_parsed_at":"2023-01-23T10:55:08.917Z","dependency_job_id":null,"html_url":"https://github.com/Xabaril/JWTSimpleServer","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xabaril%2FJWTSimpleServer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xabaril%2FJWTSimpleServer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xabaril%2FJWTSimpleServer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xabaril%2FJWTSimpleServer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Xabaril","download_url":"https://codeload.github.com/Xabaril/JWTSimpleServer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243869178,"owners_count":20360967,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asp-net-core","jwt-claims","jwt-client","jwt-server","netcore2","typescript-library"],"created_at":"2024-07-31T02:01:04.393Z","updated_at":"2025-03-16T12:30:41.530Z","avatar_url":"https://github.com/Xabaril.png","language":"C#","funding_links":[],"categories":["Frameworks, Libraries and Tools","others","框架, 库和工具"],"sub_categories":["Security","安全"],"readme":"[![Build status](https://ci.appveyor.com/api/projects/status/xkosic4gm7salll3?svg=true)](https://ci.appveyor.com/project/Xabaril/jwtsimpleserver) [![MyGet CI](https://img.shields.io/myget/xabaril/v/JWTSimpleServer.svg)](http://myget.org/gallery/jwtsimpleserver) [![NuGet](https://img.shields.io/nuget/v/JWTSimpleServer.svg)](https://www.nuget.org/packages/JWTSimpleServer/)\n[![npm version](https://badge.fury.io/js/jwt-simpleserver-client.svg)](https://badge.fury.io/js/jwt-simpleserver-client)\n\n[![Build history](https://buildstats.info/appveyor/chart/xabaril/jwtsimpleserver)](https://ci.appveyor.com/project/Xabaril/jwtsimpleserver/history?branch=master)\n\n# JWT Simple Server\n\nA light-weight, dynamic jwt server for ASP.NET Core 2.1\n\n## What is the motivation behind it?\n\nJWT Simple server arises from the need of having an ease-to-use JWT server in ASP.NET, avoiding the user all the ceremony configuration and providing additional features.\n\n## What JWT Simple Server offers?\n\n- Easy to use JWT Server, configured with a few lines of code.\n- Flexible and customizable. You can provide your own authentication and store mechanisms.\n- Implements middleware that exposes the token endpoint so you don't have to create and mantain your own.\n- Provides refresh tokens feature with several store implementations (InMemory, Entity Framework, Redis, Message Pack).\n- Provides a typescript library that will allow you to interact with JWT Server easily. This library offers a JWT Client to request and refresh access tokens and a refresh token automatic renewal service.\n\n## Getting Started\n\n1.  Install the standard Nuget package into your ASP.NET Core application.\n\n    ```\n    Install-Package JWTSimpleServer\n    ```\n\n    ```\n    Install-Package JWTSimpleServer.InMemoryRefreshTokenStore\n    ```\n\n2.  Create your own IAuthenticationProvider for user authentication. You should execute context.success and provide the user claims that will be encoded in the token or context.Reject if the authentication was not successful.\n\n    ```csharp\n    public class CustomAuthenticationProvider : IAuthenticationProvider\n    {\n        public Task ValidateClientAuthentication(JwtSimpleServerContext context)\n        {\n            if(context.UserName == \"demo\" \u0026\u0026 context.Password == \"demo\")\n            {\n                var claims = new List\u003cClaim\u003e();\n                claims.Add(new Claim(ClaimTypes.Name, \"demo\"));\n\n                context.Success(claims);\n            }\n            else\n            {\n                context.Reject(\"Invalid user authentication\");\n            }\n\n            return Task.CompletedTask;\n        }\n    }\n    ```\n\n3.  In the _ConfigureServices_ method of _Startup.cs_, register JWTSimpleServer services, defining one refresh token store (Optional: By default we register [NoRefreshTokenStore](https://github.com/Xabaril/JWTSimpleServer/blob/c5aeca936105942b96a56419b56c42159896881d/src/JWTSimpleServer/JwtSimpleServerServiceCollectionExtensions.cs#L24) implementation).\n\n    ```csharp\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services\n            .AddSingleton\u003cIAuthenticationProvider, CustomAuthenticationProvider\u003e()\n            .AddJwtSimpleServer(setup =\u003e\n            {\n                setup.IssuerSigningKey = SigningKey;\n            })\n            .AddJwtInMemoryRefreshTokenStore();\n    }\n    ```\n\n4.  In the _Configure_ method, add the middleware to the server exposing the token endpoint and handling it's requests.\n\n    ```csharp\n    public void Configure(IApplicationBuilder app, IHostingEnvironment env)\n    {\n          app.UseJwtSimpleServer(setup =\u003e\n          {\n              setup.IssuerSigningKey = SigningKey;\n          });\n    }\n    ```\n\n5.  Two grant types are supported right now by the server: **_password_** and **_refresh_token_**\n\n        \tA **_password_** grant type request will require username and password parameters and will allow you to obtain an **_access token_**.\n\n        \tSample request:\n        \t```html\n        \tPOST https://localhost:44305/Token HTTP/1.1\n        \tHost: localhost:44305\n        \tUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0\n        \tAccept: */*\n        \tContent-Type: application/x-www-form-urlencoded; charset=UTF-8\n        \tX-Requested-With: XMLHttpRequest\n        \tReferer: https://localhost:44305/\n        \tContent-Length: 68\n\n        \tgrant_type=password\u0026username=demo\u0026password=demo\n        \t```\n        \tHTTP Response\n\n        \t```json\n        \t{\n        \t\t\"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....\",\n        \t\t\"expires_in\": 900,\n        \t\t\"refresh_token\": \"77e248a4a3814308931d63b10fb1e7f7\"\n        \t}\n        \t```\n\n    A **_refresh_token_** grant type will allow you to generate a new access token with a new expiry time and obtain a new **_refresh token_**. (The previous refresh token will be invalidated once used).\n\n    The required parameter for this grant type is the refresh token you were previously provided.\n\n        \tSample request:\n        \t```html\n        \tPOST https://localhost:44305/Token HTTP/1.1\n        \tHost: localhost:44305\n        \tUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0\n        \tAccept: */*\n        \tContent-Type: application/x-www-form-urlencoded; charset=UTF-8\n        \tX-Requested-With: XMLHttpRequest\n        \tReferer: https://localhost:44305/\n        \tContent-Length: 68\n\n        \tgrant_type:refresh_token\u0026refresh_token:77e248a4a3814308931d63b10fb1e7f7\n        \t```\n\n        \tHTTP Response\n\n        \t```json\n        \t{\n        \t\t\"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....\",\n        \t\t\"expires_in\": 900,\n        \t\t\"refresh_token\": \"3521442655fc4ec5b41a1b2d9ce846aa\"\n        \t}\n        \t```\n\n## Available stores\n\nJWT Simple Server has four different store implementations:\n\n- In-memory store\n\n```csharp\n   public void ConfigureServices(IServiceCollection services)\n   {\n       services\n           .AddSingleton\u003cIAuthenticationProvider, CustomAuthenticationProvider\u003e()\n           .AddJwtSimpleServer(setup =\u003e\n           {\n               setup.IssuerSigningKey = SigningKey;\n           })\n           .AddJwtInMemoryRefreshTokenStore();\n   }\n```\n\n- Entity framework store\n\n```csharp\n    public void ConfigureServices(IServiceCollection services)\n       {\n           services\n               .AddScoped\u003cIAuthenticationProvider, CustomAuthenticationProvider\u003e()\n               .AddJwtSimpleServer(options =\u003e options.IssuerSigningKey = SigningKey)\n               .AddJwtEntityFrameworkCoreRefreshTokenStore(options =\u003e\n               {\n                   options.ConfigureDbContext = builder =\u003e\n                   {\n                       builder.UseSqlServer(\n                           Configuration[\"ConnectionStrings:DefaultConnection\"],\n                           sqlServerOptions =\u003e sqlServerOptions.MigrationsAssembly(typeof(Startup).Assembly.FullName));\n                   };\n               });\n       }\n```\n\n- Redis store\n\n```csharp\npublic void ConfigureServices(IServiceCollection services)\n      {\n          services.AddSingleton\u003cIAuthenticationProvider, CustomAuthenticationProvider\u003e()\n          .AddJwtSimpleServer(setup =\u003e\n          {\n              setup.IssuerSigningKey = SigningKey;\n          })\n          .AddDistributedRedisRefreshStokenStore( setup =\u003e\n          {\n            setup.Configuration = \"localhost\"; //Provide your redis server configuration\n            setup.InstanceName = \"JwtSimpleServerInstance\";\n          });\n      }\n```\n\n- Message pack binary store\n\n```csharp\npublic void ConfigureServices(IServiceCollection services)\n      {\n          services.AddSingleton\u003cIAuthenticationProvider, CustomAuthenticationProvider\u003e()\n          .AddJwtSimpleServer(setup =\u003e\n          {\n              setup.IssuerSigningKey = SigningKey;\n          })\n          .AddJwtMessagePackRefreshTokenStore(setup =\u003e\n          {\n              setup.Path = \"MyBinaryStore.bin\";\n          });\n      }\n```\n\nYou can create your own store service by implementing **IRefreshTokenStore** interface and registering it in the inversion of control container.\n\n## Pipeline configuration\n\nIf you need to register middlewares in the JwtSimpleServer branch, you can use configurePipeline action parameter in UseJwtSimpleServer extension method:\n\nSample to register CORS middleware within the pipeline:\n\n```csharp\napp.UseJwtSimpleServer(setup =\u003e\n {\n   setup.IssuerSigningKey = SigningKey;\n }, pipeline =\u003e {\n   pipeline.UseCors(setup =\u003e\n  {\n    setup.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();\n  });\n});\n```\n\n## Samples\n\nWe have some samples with different store configurations available [here](https://github.com/Xabaril/JWTSimpleServer/tree/master/samples).\n\nIf you launch the projects you can try a simple playground to get access tokens and try the refresh token renewal service.\n\n![JWTSimpleServer playground](https://preview.ibb.co/mkhSAn/playground.png)\n\n## Typescript library\n\nThe typescript library will allow you to easily interact will the token endpoint.\n\nFollow this steps to create your client if you are using the **browser** bundled library:\n\n**NPM - Installing the library**\n\n```\nnpm install jwt-simpleserver-client --save\n```\n\n**1. Create the client options**\n\n```javascript\nvar defaultServerOptions = new JwtSimpleServer.ClientOptions();\n```\n\nClient options parameters have default values listed in this table:\n\n|     Parameter | default value          |\n| ------------: | ---------------------- |\n| tokenEndpoint | \"/token\"               |\n|          host | window.location.origin |\n|    httpClient | XMLHttpRequestClient   |\n\nNOTE: You can implement your own **HttpClient** by implementing our HttpClient abstract class\n\n**2. Creat the client providing the options object:**\n\n```javascript\nvar simpleServerClient = new JwtSimpleServer.ServerClient(defaultServerOptions);\n```\n\n3.  Request an access token by executing _requestAccessToken_ method:\n\n```javascript\nsimpleServerClient.requestAccessToken({ userName: \"demo\", password: \"demo\" })\n\t.then(token =\u003e {\n  // your token object will have the access token and expiral, and if configured: the refresh token\n   }):\n```\n\n\\*_Client events_\n\nJWT client have several observables you can subscribe to:\n\n|                   Observable | return value | description                                                                   |\n| ---------------------------: | -----------: | ----------------------------------------------------------------------------- |\n|   onBeforeRequestAccessToken |         void | Will notify observers before starting the token request to the server         |\n|  onRequestAccessTokenSuccess |        Token | Will notify observers passing the retrieved token as parameter                |\n|  onBeforeRequestRefreshToken |         void | Will notify observers before starting the refresh token request to the server |\n| onRequestRefreshTokenSuccess |        Token | Will notify observers passing the retrieved refresh token as parameter        |\n\n**4. Optional: If you want the library to request new access tokens given an interval you can configure the **RefreshTokenService\\*\\*\\*\\*\n\n```javascript\nvar refreshService = new JwtSimpleServer.RefreshTokenService(\n  simpleServerClient\n);\n\nlet onTokenRefreshedFunction = token =\u003e {\n  console.log(\"Refresh token service:\", token);\n};\n\n//Start the renewal service\nrefreshService.start({\n  intervalSeconds: 10,\n  refreshToken,\n  onRefreshTokenSuccessCallback: onTokenRefreshedFunction\n});\n\n//Stop the renewal service\nrefreshService.stop();\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FXabaril%2FJWTSimpleServer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FXabaril%2FJWTSimpleServer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FXabaril%2FJWTSimpleServer/lists"}