// ======================================================================== // // Copyright (C) 2017-2018 MARC CHEVALDONNE // marc.chevaldonne.free.fr // // Module : TokenController.cs // Author : Marc Chevaldonné // Creation date : 2018-02-12 // // ======================================================================== using AlertWebAPI.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using System; using System.Diagnostics; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Text; namespace AlertWebAPI.Controllers { /// /// allows to create a token on the alert database by authenticating /// [Route("api/token")] public class TokenController : Controller { private IConfiguration _config; /// /// context allowing to access the database containing the logins and passwords /// private readonly UserDbContext context; /// /// constructor /// /// public TokenController(IConfiguration config) { _config = config; //creates the context to the Users database this.context = new UserDbContext(); //if the users database is empty, creates a fake user and adds it to the database StubData(); } [Conditional("DEBUG")] private void StubData() { if (context.Users.Count() == 0) { InitializeData(context); context.SaveChanges(); } } /// /// creates stub data for the users database /// /// private void InitializeData(UserDbContext context) { context.Users.Add(new User { Name = "Dwight Schrute", UserName = "dwight", Password = "boss", Email = "dwight.schrute@dundlermifflin.com" }); } /// /// creates a token for accessing the alert database /// [AllowAnonymous] authorizes anonymous access to this method /// /// username/password of the user asking for a token /// a token to access the alert database [AllowAnonymous] [HttpPost] public IActionResult CreateToken([FromBody]Login login) { IActionResult response = Unauthorized(); //tries to authenticate with the login data var user = Authenticate(login); //if authentication succeeds, builds a token and returns it if (user != null) { var tokenString = BuildToken(user); response = Ok(new { token = tokenString }); } //else, returns a Status401Unauthorized response return response; } /// /// builds the token with the user data /// note that it uses the config file (Key and Issuer), defined in appsettings.json /// /// the user who will get the token /// the token built private string BuildToken(User user) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"])); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken(_config["Jwt:Issuer"], _config["Jwt:Issuer"], expires: DateTime.Now.AddMinutes(30), signingCredentials: creds); return new JwtSecurityTokenHandler().WriteToken(token); } /// /// authenticates the login/password /// /// login/password to authenticate /// the user if authentication succeeds, null if not private User Authenticate(Login login) { User user = null; //retrieves the first user in the database with the given login and password user = context.Users.FirstOrDefault(u => u.UserName == login.Username && u.Password == login.Password); //methods without users database and hard-saved login/password //if (login.Username == "dwight" && login.Password == "boss") //{ // user = new User { Name = "Dwight Schrute", Email = "dwight.schrute@dundlermifflin.com" }; //} return user; } } }