using System; using System.Linq; using Microsoft.AspNet.Mvc; using System.IdentityModel.Tokens; using System.Security.Claims; using Microsoft.AspNet.Authorization; using System.Security.Principal; using Microsoft.AspNet.Authentication.JwtBearer; using System.IdentityModel.Tokens.Jwt; using Microsoft.Extensions.Logging; using Microsoft.Extensions.OptionsModel; using Yavsc.Auth; using Microsoft.AspNet.Identity; using Yavsc.Models; using System.Threading.Tasks; namespace Yavsc.Controllers { [Produces("application/json"),AllowAnonymous] public class TokenController : Controller { private readonly TokenAuthOptions tokenOptions; private ILogger logger; UserManager manager; SignInManager signInManager; public class TokenResponse {  public string access_token { get; set; } public int expires_in { get; set; } public string grant_type { get; set; } public int entity_id { get; set; } } UserTokenProvider tokenProvider; public TokenController( UserManager userManager, SignInManager signInManager, IOptions token_options, ILoggerFactory loggerFactory, UserTokenProvider tokenProvider) { this.manager = userManager; this.tokenOptions = token_options.Value; this.signInManager = signInManager; this.tokenProvider = tokenProvider; //this.bearerOptions = options.Value; //this.signingCredentials = signingCredentials; logger = loggerFactory.CreateLogger(); } /// /// Check if currently authenticated. Will throw an exception of some sort which shoudl be caught by a general /// exception handler and returned to the user as a 401, if not authenticated. Will return a fresh token if /// the user is authenticated, which will reset the expiry. /// /// [HttpGet,HttpPost,Authorize] [Route("~/api/token/get")] public async Task Get() { bool authenticated = false; string user = null; int entityId = -1; string token = null; DateTime? tokenExpires = default(DateTime?); var currentUser = User; if (currentUser != null) { authenticated = currentUser.Identity.IsAuthenticated; if (authenticated) { user = User.GetUserId(); logger.LogInformation($"authenticated user:{user}"); foreach (Claim c in currentUser.Claims) if (c.Type == "EntityID") entityId = Convert.ToInt32(c.Value); tokenExpires = DateTime.UtcNow.AddMinutes(2); token = await GetToken("id_token", user, tokenExpires); return new TokenResponse { access_token = token, expires_in = 3400, entity_id = entityId }; } } return new { authenticated = false }; } public class AuthRequest { public string username { get; set; } public string password { get; set; } } /// /// Request a new token for a given username/password pair. /// /// /// [HttpPost,Route("~/api/token/post")] public async Task Post(AuthRequest req) { if (!ModelState.IsValid) return new BadRequestObjectResult(ModelState); // Obviously, at this point you need to validate the username and password against whatever system you wish. var signResult = await signInManager.PasswordSignInAsync(req.username, req.password,false,true); if (signResult.Succeeded) { DateTime? expires = DateTime.UtcNow.AddMinutes(tokenOptions.ExpiresIn); var token = await GetToken("id_token",User.GetUserId(), expires); return Ok(new TokenResponse {access_token = token, expires_in = 3400, grant_type="id_token" }); } return new BadRequestObjectResult(new { authenticated = false } ) ; } private async Task GetToken(string purpose, string userid, DateTime? expires) { // Here, you should create or look up an identity for the user which is being authenticated. // For now, just creating a simple generic identity. var identuser = await manager.FindByIdAsync(userid); return await tokenProvider.GenerateAsync(purpose,manager,identuser); } } }