Skip to content

Instantly share code, notes, and snippets.

@jimschubert
Created May 16, 2017 04:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimschubert/3b1622d89a68a6c92bc2d9eca7c52eb1 to your computer and use it in GitHub Desktop.
Save jimschubert/3b1622d89a68a6c92bc2d9eca7c52eb1 to your computer and use it in GitHub Desktop.
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using Snaggy.Auth;
using Snaggy.Models;
using Snaggy.Models.TokenAuthViewModels;
namespace Snaggy.Controllers
{
[Route("api/[controller]")]
[Produces("application/json")]
public class TokenAuthController
{
private readonly UserManager<User> _userManager;
private readonly SignInManager<User> _signInManager;
private readonly IConfiguration _configuration;
/// <summary>
/// Constructs a new instance of <see cref="TokenAuthController"/>
/// </summary>
/// <param name="userManager"></param>
/// <param name="signInManager"></param>
/// <param name="configuration"></param>
public TokenAuthController(UserManager<User> userManager, SignInManager<User> signInManager, IConfiguration configuration)
{
_userManager = userManager;
_signInManager = signInManager;
_configuration = configuration;
}
/// <summary>
/// Provides for generation of a JWT bearer token for a given user/pass
/// </summary>
/// <param name="tokenRequest">The information required to generate a token</param>
/// <response code="200">Token details, or null</response>
[HttpPost]
public async Task<TokenResult> GetAuthToken([FromBody]LoginModel tokenRequest)
{
var user = await _userManager.FindByNameAsync(tokenRequest.Username);
var result = await _signInManager.CheckPasswordSignInAsync(user, tokenRequest.Password, lockoutOnFailure: false);
if (result.Succeeded)
{
var now = DateTime.Now;
var expires = now + TimeSpan.FromDays(5);
var principal = await _signInManager.CreateUserPrincipalAsync(user);
var identity = new ClaimsIdentity(principal.Identity, principal.Claims);
return new TokenResult
{
Expires = expires,
Requested = now,
Token = GenerateToken(identity, expires),
TokenType = "Bearer"
};
}
// Ideally, we'd use content negotiation here, and expose a problem detail object.
return null;
}
private string GenerateToken(ClaimsIdentity identity, DateTime expires)
{
var handler = new JwtSecurityTokenHandler();
var tokenDetails = new TokenDetails(_configuration);
var securityToken = handler.CreateToken(new SecurityTokenDescriptor
{
Issuer = tokenDetails.Issuer,
Audience = tokenDetails.Audience,
SigningCredentials = tokenDetails.SigningCredentials,
Subject = identity,
Expires = expires
});
return handler.WriteToken(securityToken);
}
}
}
using System.Text;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
namespace Snaggy.Auth
{
internal class TokenDetails
{
internal string Path { get; set; }
internal string Issuer { get; set; }
internal string Audience { get; set; }
internal SymmetricSecurityKey SigningKey { get; set; }
internal SigningCredentials SigningCredentials { get; set; }
internal TokenDetails(IConfiguration configuration)
{
Path = configuration.GetSection("jwt:path").Value;
Audience = configuration.GetSection("jwt:audience").Value;
Issuer = configuration.GetSection("jwt:issuer").Value;
SigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(configuration.GetSection("jwt:secret").Value));
SigningCredentials = new SigningCredentials(SigningKey, SecurityAlgorithms.HmacSha256);
}
}
}
using System;
namespace Snaggy.Models.TokenAuthViewModels
{
public class TokenResult
{
public DateTime Requested { get; set; }
public DateTime Expires { get; set; }
public string TokenType { get; set; }
public string Token { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment