Skip to content

Commit

Permalink
Set up authorization and token handling
Browse files Browse the repository at this point in the history
  • Loading branch information
marvac committed Jan 8, 2019
1 parent 34d0d28 commit 4f2ae4f
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 27 deletions.
57 changes: 50 additions & 7 deletions Controllers/AuthController.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
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 Friendster.Controllers.Resources;
using Friendster.Data;
using Friendster.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;

namespace Friendster.Controllers
{
Expand All @@ -14,33 +19,71 @@ namespace Friendster.Controllers
public class AuthController : ControllerBase
{
private IAuthRepository _repo;
private IConfiguration _config;

public AuthController(IAuthRepository repo)
public AuthController(IAuthRepository repo, IConfiguration config)
{
_repo = repo;
_config = config;
}

[HttpPost]
public async Task<IActionResult> Register([FromBody] UserResource userResource)
[HttpPost("register")]
public async Task<IActionResult> Register(RegisterUserResource userResource)
{
if (string.IsNullOrWhiteSpace(userResource?.UserName) || string.IsNullOrWhiteSpace(userResource?.Password))
if (!ModelState.IsValid)
{
return BadRequest("Username or password cannot be blank");
return BadRequest();
}

if (await _repo.UserExists(userResource.UserName))
if (await _repo.UserExists(userResource.Username))
{
return BadRequest("Username already exists");
}

User user = new User
{
Username = userResource.UserName
Username = userResource.Username
};

var registeredUser = await _repo.Register(user, userResource.Password);

return StatusCode(201);
}

[HttpPost("login")]
public async Task<IActionResult> Login(LoginUserResource userResource)
{
var user = await _repo.Login(userResource.Username, userResource.Password);
if (user == null)
{
return Unauthorized();
}

/* User is authenticated */

var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, $"{user.Id}"),
new Claim(ClaimTypes.Name, user.Username)
};

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config.GetSection("AppSettings:Token").Value));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);

var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.Now.AddDays(1),
SigningCredentials = credentials
};

var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);

return Ok(new
{
token = tokenHandler.WriteToken(token)
});
}
}
}
22 changes: 22 additions & 0 deletions Controllers/Resources/LoginUserResource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace Friendster.Controllers.Resources
{
public class LoginUserResource
{
private string _username;

[Required]
public string Username
{
get { return _username; }
set { _username = value?.ToLower(); }
}

public string Password { get; set; }
}
}
23 changes: 23 additions & 0 deletions Controllers/Resources/RegisterUserResource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace Friendster.Controllers.Resources
{
public class RegisterUserResource
{
private string _username;

[Required]
public string Username
{
get { return _username; }
set { _username = value?.ToLower(); }
}

[Required, StringLength(20, MinimumLength = 1, ErrorMessage = "Password must be 1-20 characters")]
public string Password { get; set; }
}
}
20 changes: 0 additions & 20 deletions Controllers/Resources/UserResource.cs

This file was deleted.

4 changes: 4 additions & 0 deletions Controllers/ValuesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
using System.Threading.Tasks;
using Friendster.Data;
using Friendster.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Friendster.Controllers
{
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
Expand All @@ -26,6 +28,8 @@ public async Task<ActionResult<IEnumerable<Value>>> Get()
return Ok(values);
}


[AllowAnonymous]
[HttpGet("{id}")]
public async Task<ActionResult<Value>> Get(int id)
{
Expand Down
15 changes: 15 additions & 0 deletions Startup.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Friendster.Data;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -11,6 +13,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;

namespace Friendster
{
Expand All @@ -33,6 +36,17 @@ public void ConfigureServices(IServiceCollection services)

services.AddScoped<IDataRepository, DataRepository>();
services.AddScoped<IAuthRepository, AuthRepository>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false
};
});

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

Expand All @@ -54,6 +68,7 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env)
config.AllowAnyHeader();
});

app.UseAuthentication();
app.UseMvc();
}
}
Expand Down
3 changes: 3 additions & 0 deletions appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\MSSQLLocalDb;Database=FriendsterDb;Trusted_Connection=true;MultipleActiveResultSets=true;"
},
"AppSettings": {
"Token": "super duper secret key"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
Expand Down

0 comments on commit 4f2ae4f

Please sign in to comment.