Skip to content

Instantly share code, notes, and snippets.

@pradeepn
Created August 22, 2019 08:41
Show Gist options
  • Save pradeepn/89646bd37de3bb3535de5582f0959610 to your computer and use it in GitHub Desktop.
Save pradeepn/89646bd37de3bb3535de5582f0959610 to your computer and use it in GitHub Desktop.
JWT Token Generation, Validation and Refresh Token in .NET Core
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 });
}
}
}
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; }
}
}
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