{"id":24141411,"url":"https://github.com/aerosonik/nsv.security.jwt","last_synced_at":"2025-08-09T16:24:20.325Z","repository":{"id":143217671,"uuid":"229704281","full_name":"aerosonik/NSV.Security.Jwt","owner":"aerosonik","description":"Simple library for issue and refresh Jwt tokens ","archived":false,"fork":false,"pushed_at":"2024-01-09T19:24:30.000Z","size":86,"stargazers_count":2,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-02T11:51:31.401Z","etag":null,"topics":["csharp","jwt","jwt-auth","jwt-authentication","jwt-bearer-tokens","netcore"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aerosonik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-23T07:55:01.000Z","updated_at":"2021-02-16T16:09:13.000Z","dependencies_parsed_at":"2025-01-12T04:09:56.170Z","dependency_job_id":"b7156cb4-120f-4d98-9c22-c3af00abfd8c","html_url":"https://github.com/aerosonik/NSV.Security.Jwt","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aerosonik/NSV.Security.Jwt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aerosonik%2FNSV.Security.Jwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aerosonik%2FNSV.Security.Jwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aerosonik%2FNSV.Security.Jwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aerosonik%2FNSV.Security.Jwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aerosonik","download_url":"https://codeload.github.com/aerosonik/NSV.Security.Jwt/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aerosonik%2FNSV.Security.Jwt/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262647372,"owners_count":23342639,"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":["csharp","jwt","jwt-auth","jwt-authentication","jwt-bearer-tokens","netcore"],"created_at":"2025-01-12T04:09:49.663Z","updated_at":"2025-06-29T18:32:20.743Z","avatar_url":"https://github.com/aerosonik.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://raw.githubusercontent.com/aerosonik/ValidationPipe/f5997cdfaff661d36939c45823e93bb613a3767d/icon.png\" alt=\"nsv\" height=\"80\" /\u003e\n\n# NSV.Security.Jwt\nLightwiweigth JWT library. It can issue tokens and validate with refresing both - access/refresh tokens.\n\n[![NuGet](https://img.shields.io/nuget/v/NSV.Security.Jwt.svg)](https://www.nuget.org/packages/NSV.Security.Jwt) \n[![Build status](https://ci.appveyor.com/api/projects/status/7hj4a9agnvplu2qq?svg=true)](https://ci.appveyor.com/project/aerosonik/nsv-security-jwt)\n\n## Installation\n\nGet latest stable version from [NuGet](https://www.nuget.org/packages/NSV.Security.Jwt).\n\n## Features\n\n* Issue access token\n* Issue \"refresh\" token (use it to refresh access token)\n* Refresh token - verification and creating new tokens \n* Fully configurable\n* Asp .Net Core pipeline ready\n\n## How to use it:\n\n### Configuration\n\nAdd to appsettinegs.json file new configure section, like this:\n```js\n\"JwtOptions\": {\n    \"ValidIssuer\": \"aerosonik.identity.nsv.pub\",\n    \"ValidAudience\": \"aerosonik.identity.nsv.pub\",\n    \"AccessSecurityKey\": \"4f3026ab-3f9f-4190-b4e8-83ab7ae2df74@identity.nsv.pub/defaultAcessSecurityKey\",\n    \"AccessTokenExpiry\": \"00.00:30:00.000\", //DD.HH:mm:ss:ms\n    \"RefreshSecurityKey\": \"11bda118-9f48-426e-aedb-ff4a9ee12f1c@identity.nsv.pub/defaultRefreshSecurityKey\",\n    \"RefreshTokenExpiry\": \"00.00:24:00.000\", //DD.HH:mm:ss:ms\n    \"UpdateRefreshTokenBeforeExpired\": \"00.00:01:00.000\" //DD.HH:mm:ss:ms\n  },\n```\n\n* `ValidIssuer`, `ValidAudience` - standatd jwt configuration.\n* `AccessSecurityKey` - secret seqcurity key for access token.\n* `AccessTokenExpiry` - access token lifetime.\n* `RefreshSecurityKey` - secret seqcurity key for \"refresh\" token.\n* `RefreshTokenExpiry` - \"refresh\" token lifetime, must be greater then `AccessTokenExpiry`.\n* `UpdateRefreshTokenBeforeExpired` - this field indicate when \"refresh\" token should be re created when `RefreshAccessToken(..)` called\n\n\nAdd `JwtService` it to asp .net core pipeline by using extensions method \n`IServiceCollection AddJwt(...)`\nIt will look's similar to\n```csharp\npublic void ConfigureServices(IServiceCollection services)\n{\n  services.AddOptions();\n  services.AddJwt(Configuration);\n  .......\n```\n\nOr, you can configure Jwt directly in code\n```csharp\npublic void ConfigureServices(IServiceCollection services)\n{\n  services.AddOptions();\n  services.AddJwt(conf =\u003e\n  {\n    conf.ValidIssuer = \"sequrity.nsv.pub\";\n    conf.ValidAudience = \"sequrity.nsv.pub\";\n    conf.AccessSecurityKey = \"c12477f1-c84e-4a82-aa4d-7574ee08e592@identity.nsv.pub/defaultAcessSecurityKey\";\n    conf.RefreshSecurityKey = \"c16455f1-c88e-4b92-bb4d-79749e989592@identity.nsv.pub/defaultRefreshSecurityKey\";\n    conf.AccessTokenExpiry = TimeSpan.FromMinutes(30);\n    conf.RefreshTokenExpiry = TimeSpan.FromDays(5);\n    conf.UpdateRefreshTokenBeforeExpired = TimeSpan.FromMinutes(30);\n  });\n  .......\n```\n\nIf you need to use it with Asp .Net Core Authentication/authorization mechanism, just propogade to it our jwt configuration:\n```csharp\nservices.AddAuthentication(options =\u003e\n{\n  options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;\n  options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;\n  options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;\n}).AddJwtBearer(options =\u003e\n{\n  options.RequireHttpsMetadata = false;\n  options.TokenValidationParameters = JwtSettings.TokenValidationParameters();\n});\n```\n### Use it in your code\n\nInject registered IJwtService in your Authentication service\n```csharp\npublic class AuthService\n{\n  private readonly IJwtService _jwtService;\n  ...\n  public Auth(IJwtService jwtService, ...)\n  {\n    _jwtService = jwtService;\n    ...\n  }\n```\nLogin/signin case:\n\n```csharp\npublic async Task\u003cWebApiResult\u003cTokensModel\u003e\u003e Signin(LogInModel model)\n{\n  var userResult = await _authRepository.GetUserByLogin(model.Login);\n  if (userResult.Result == DataBaseResultEnum.Error) // handle 500\n    return ... \n\n  if (userResult.Result == DataBaseResultEnum.NotFound) // handle 404\n    return ...\n  \n  var validateResult = _passwordService.Validate(model.Password, userResult.Value.Password);\n  if (validateResult.Result != PasswordValidateResult.ValidateResult.Ok) // handle 401\n    return ...\n            \n  // Create Issue/Refresh tokens\n  var jwtResult = _jwtService.IssueAccessToken(\n      userResult.Value.Id.ToString(),\n      userResult.Value.UserName,\n      userResult.Value.Roles);\n\n  return new WebApiResult\u003cTokensModel\u003e(\n      HttpStatusCode.OK,\n      new TokensModel\n      {\n        AccessToken = jwtResult.Tokens.AccessToken.Value,\n        RefreshToken = jwtResult.Tokens.RefreshToken.Value\n      });\n}\n```\nRefresh case:\n\n```csharp\npublic async Task\u003cWebApiResult\u003cTokensModel\u003e\u003e Refresh(TokensModel model)\n{\n  //try refresh\n  var validatedResult = _jwtService\n    .RefreshAccessToken(model.AccessToken, model.RefreshToken);\n  if(validatedResult.Result != JwtTokenResult.TokenResult.Ok)// handle 401\n    return ...\n  return new WebApiResult\u003cTokensModel\u003e(\n    HttpStatusCode.OK, \n    new TokensModel\n    {\n       AccessToken = validatedResult.Tokens.AccessToken.Value,\n       RefreshToken = validatedResult.Tokens.RefreshToken?.Value // can be null? when accessToken refreshed only\n    });\n}\n```\n### JwtService returns `JwtTokenResult` in both cases (issue and refresh):\n\n```csharp\npublic struct JwtTokenResult\n{ \n    public TokenModel Tokens { get; }\n    public TokenResult Result { get; }\n    public string RefreshTokenJti { get; }\n    ...\n```\n* `TokenModel` - contains Access and Refresh token and theirs expiration dates.\n* `TokenResult` - enum, it can be : `Ok`, `RefreshTokenInvalid`, `AccessTokenInvalid`, `TokensMismatch`, `RefreshTokenExpired`. When we call method `jwtService.IssueAccessToken`,  only `Ok` can be returned.\n* `RefreshTokenJti` - it's a string representation of GUID, property contains current \"RefeshToken\" JTI claim. It can be used in case when you shouold store every access token in DB and refer to related \"RefreshToken\".\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faerosonik%2Fnsv.security.jwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faerosonik%2Fnsv.security.jwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faerosonik%2Fnsv.security.jwt/lists"}