Created
August 22, 2019 08:41
-
-
Save pradeepn/89646bd37de3bb3535de5582f0959610 to your computer and use it in GitHub Desktop.
JWT Token Generation, Validation and Refresh Token in .NET Core
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IdentityModel.Tokens.Jwt; | |
using System.Linq; | |
using System.Security.Claims; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Authorization; | |
using Microsoft.AspNetCore.Http; | |
using Microsoft.AspNetCore.Identity; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.Extensions.Configuration; | |
using Microsoft.IdentityModel.Tokens; | |
namespace web_api_jwt.Controllers | |
{ | |
[Route("api/[controller]")] | |
[ApiController] | |
public class AccountsController : ControllerBase | |
{ | |
private readonly IConfiguration _configuration; | |
private readonly AppDbContext _db; | |
public AccountsController(IConfiguration configuration, AppDbContext db) | |
{ | |
_configuration = configuration; | |
_db = db; | |
} | |
[AllowAnonymous] | |
[HttpPost] | |
public IActionResult Login([FromBody] LoginInfo request) | |
{ | |
if (request.Username == "Jane" && request.Password == "Password!") | |
{ | |
var userclaim= new[] { new Claim(ClaimTypes.Name, request.Username)}; | |
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecretKey"])); | |
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); | |
var token = new JwtSecurityToken( | |
issuer: "https://localhost:5001", | |
audience: "https://localhost:5001", | |
claims: userclaim, | |
expires: DateTime.Now.AddMinutes(1), | |
signingCredentials: creds); | |
var _refreshTokenObj = new RefreshToken | |
{ | |
Username = request.Username, | |
Refreshtoken = Guid.NewGuid().ToString() | |
}; | |
_db.RefreshTokens.Add(_refreshTokenObj); | |
_db.SaveChanges(); | |
return Ok(new { | |
token = new JwtSecurityTokenHandler().WriteToken(token), | |
refreshToken = _refreshTokenObj.Refreshtoken | |
}); | |
} | |
return BadRequest("Could not verify username and password"); | |
} | |
[HttpPost("{refreshToken}/refresh")] | |
public IActionResult RefreshToken([FromRoute]string refreshToken) | |
{ | |
var _refreshToken = _db.RefreshTokens.SingleOrDefault(m => m.Refreshtoken == refreshToken); | |
if (_refreshToken == null) | |
{ | |
return NotFound("Refresh token not found"); | |
} | |
var userclaim = new[] { new Claim(ClaimTypes.Name, _refreshToken.Username) }; | |
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecretKey"])); | |
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); | |
var token = new JwtSecurityToken( | |
issuer: "https://localhost:5001", | |
audience: "https://localhost:5001", | |
claims: userclaim, | |
expires: DateTime.Now.AddMinutes(10), | |
signingCredentials: creds); | |
_refreshToken.Refreshtoken = Guid.NewGuid().ToString(); | |
_db.RefreshTokens.Update(_refreshToken); | |
_db.SaveChanges(); | |
return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token), refToken = _refreshToken.Refreshtoken }); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
namespace web_api_jwt | |
{ | |
public class RefreshToken | |
{ | |
public int Id { get; set; } | |
public string Username { get; set; } | |
public string Refreshtoken { get; set; } | |
public bool Revoked { get; set; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Authentication.JwtBearer; | |
using Microsoft.AspNetCore.Builder; | |
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.AspNetCore.HttpsPolicy; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.EntityFrameworkCore; | |
using Microsoft.Extensions.Configuration; | |
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Extensions.Logging; | |
using Microsoft.Extensions.Options; | |
using Microsoft.IdentityModel.Tokens; | |
namespace web_api_jwt | |
{ | |
public class Startup | |
{ | |
public Startup(IConfiguration configuration) | |
{ | |
Configuration = configuration; | |
} | |
public IConfiguration Configuration { get; } | |
// This method gets called by the runtime. Use this method to add services to the container. | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) | |
.AddJwtBearer(options => { | |
options.TokenValidationParameters = new TokenValidationParameters | |
{ | |
ValidateIssuer = true, | |
ValidateAudience = true, | |
ValidateLifetime = true, | |
ValidateIssuerSigningKey = true, | |
ValidIssuer = "https://localhost:5001", | |
ValidAudience = "https://localhost:5001", | |
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecretKey"])) | |
}; | |
}); | |
services.AddDbContext<AppDbContext>(options => | |
options.UseInMemoryDatabase("webAPIjwtDb") | |
); | |
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); | |
services.AddSwaggerGen(c => { | |
c.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info | |
{ | |
Title = "Testing JWT with Web API", | |
Version = "v1", | |
}); | |
}); | |
} | |
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |
public void Configure(IApplicationBuilder app, IHostingEnvironment env) | |
{ | |
if (env.IsDevelopment()) | |
{ | |
app.UseDeveloperExceptionPage(); | |
} | |
else | |
{ | |
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. | |
app.UseHsts(); | |
} | |
app.UseSwagger(); | |
app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Web API JWT v1"); }); | |
app.UseHttpsRedirection(); | |
app.UseAuthentication(); | |
app.UseMvc(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment