You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.9 KiB
144 lines
4.9 KiB
// ========================================================================
|
|
//
|
|
// 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
|
|
{
|
|
/// <summary>
|
|
/// allows to create a token on the alert database by authenticating
|
|
/// </summary>
|
|
[Route("api/token")]
|
|
public class TokenController : Controller
|
|
{
|
|
private IConfiguration _config;
|
|
|
|
/// <summary>
|
|
/// context allowing to access the database containing the logins and passwords
|
|
/// </summary>
|
|
private readonly UserDbContext context;
|
|
|
|
/// <summary>
|
|
/// constructor
|
|
/// </summary>
|
|
/// <param name="config"></param>
|
|
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();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// creates stub data for the users database
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
private void InitializeData(UserDbContext context)
|
|
{
|
|
context.Users.Add(new User
|
|
{
|
|
Name = "Dwight Schrute",
|
|
UserName = "dwight",
|
|
Password = "boss",
|
|
Email = "dwight.schrute@dundlermifflin.com"
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// creates a token for accessing the alert database
|
|
/// [AllowAnonymous] authorizes anonymous access to this method
|
|
/// </summary>
|
|
/// <param name="login">username/password of the user asking for a token</param>
|
|
/// <returns>a token to access the alert database</returns>
|
|
[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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// builds the token with the user data
|
|
/// note that it uses the config file (Key and Issuer), defined in appsettings.json
|
|
/// </summary>
|
|
/// <param name="user">the user who will get the token</param>
|
|
/// <returns>the token built</returns>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// authenticates the login/password
|
|
/// </summary>
|
|
/// <param name="login">login/password to authenticate</param>
|
|
/// <returns>the user if authentication succeeds, null if not</returns>
|
|
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;
|
|
}
|
|
}
|
|
}
|