From 4a9a81a8d22fde9619ef8c53da5778dab6998b6a Mon Sep 17 00:00:00 2001 From: Steven Knox Date: Thu, 13 Feb 2020 14:31:27 +0000 Subject: [PATCH 1/2] Update sample.http to support user creation then token generation from the new users --- TodoBasicWithAuth/AuthApi.cs | 10 +++--- TodoBasicWithAuth/CreateUser.cs | 19 ++++++++++++ TodoBasicWithAuth/sample.http | 54 ++++++++++++++++++++++++--------- 3 files changed, 64 insertions(+), 19 deletions(-) create mode 100644 TodoBasicWithAuth/CreateUser.cs diff --git a/TodoBasicWithAuth/AuthApi.cs b/TodoBasicWithAuth/AuthApi.cs index b7cc213..59a6e8b 100644 --- a/TodoBasicWithAuth/AuthApi.cs +++ b/TodoBasicWithAuth/AuthApi.cs @@ -30,9 +30,9 @@ public AuthApi(JwtSettings jwtSettings) public async Task CreateUser(UserManager userManager, HttpContext context) { - var loginInfo = await JsonSerializer.DeserializeAsync(context.Request.Body, _options); + var loginInfo = await JsonSerializer.DeserializeAsync(context.Request.Body, _options); - var result = await userManager.CreateAsync(new TodoUser { UserName = loginInfo.UserName }, loginInfo.Password); + var result = await userManager.CreateAsync(new TodoUser { UserName = loginInfo.UserName, IsAdmin = loginInfo.IsAdmin }, loginInfo.Password); if (result.Succeeded) { @@ -55,13 +55,15 @@ public async Task GenerateTokenAsync(UserManager userManager, HttpCont } var claims = new List(); - + claims.Add(new Claim("can_view", "true")); + if (user.IsAdmin) { claims.Add(new Claim("can_delete", "true")); - claims.Add(new Claim("can_view", "true")); } + + var key = new SymmetricSecurityKey(_jwtSettings.Key); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( diff --git a/TodoBasicWithAuth/CreateUser.cs b/TodoBasicWithAuth/CreateUser.cs new file mode 100644 index 0000000..e27a735 --- /dev/null +++ b/TodoBasicWithAuth/CreateUser.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Todos +{ + public class CreateUser + { + [Required] + public string UserName { get; set; } + + [Required] + public string Password { get; set; } + + public bool IsAdmin { get; set; } + } +} diff --git a/TodoBasicWithAuth/sample.http b/TodoBasicWithAuth/sample.http index 9dd7ff4..2d24897 100644 --- a/TodoBasicWithAuth/sample.http +++ b/TodoBasicWithAuth/sample.http @@ -1,32 +1,54 @@ -@token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjYW5fZGVsZXRlIjoidHJ1ZSIsImNhbl92aWV3IjoidHJ1ZSIsImV4cCI6MTU4MTU2NTU2MiwiaXNzIjoiZGVmYXVsdGlzc3VlciIsImF1ZCI6ImRlZmF1bHRhdWRpZW5jZSJ9.XJyk0vIcuy1x4Kdk2O6N9I3Ibg3Qs4dOlFiiQOle2pk @todo_id = 1 ### // Needs https://marketplace.visualstudio.com/items?itemName=humao.rest-client -// Get all todos (no authentication) -GET http://localhost:5000/api/todos +### + +//Create regular user +POST http://localhost:5000/api/auth +Content-Type: application/json + +{ + "username" : "user", + "password" : "Hunter2!" +} ### -// Authenticate as Admin -POST http://localhost:5000/api/auth/token +// Create admin user +POST http://localhost:5000/api/auth Content-Type: application/json { "username" : "admin", - "password" : "123456" + "password" : "Pass123456!", + "isAdmin" : true } ### // Authenticate as regular user +# @name LoginRegularUser POST http://localhost:5000/api/auth/token Content-Type: application/json { "username" : "user", - "password" : "hunter2" + "password" : "Hunter2!" +} + +@token = {{LoginRegularUser.response.body.token}} +### + +// New Todo +POST http://localhost:5000/api/todos +Authorization: Bearer {{token}} +Content-Type: application/json + +{ + "Name" : "Write unit tests.", + "IsComplete" : false } ### @@ -43,21 +65,23 @@ Authorization: Bearer {{token}} GET http://localhost:5000/api/todos/{{todo_id}} Authorization: Bearer {{token}} - ### -// New Todo -POST http://localhost:5000/api/todos -Authorization: Bearer {{token}} +// Authenticate as an admin user +# @name LoginAdminUser +POST http://localhost:5000/api/auth/token Content-Type: application/json { - "Name" : "Write unit tests.", - "IsComplete" : false + "username" : "admin", + "password" : "Pass123456!" } ### -// Delete Todo +// Delete Todo. must be authenticated as admim + +@admintoken = {{LoginAdminUser.response.body.token}} + DELETE http://localhost:5000/api/todos/{{todo_id}} -Authorization: Bearer {{token}} +Authorization: Bearer {{admintoken}} From 3eb21a04543313f29e4505b2f9aea30a38ca1925 Mon Sep 17 00:00:00 2001 From: Steven Knox Date: Mon, 17 Feb 2020 12:47:30 +0000 Subject: [PATCH 2/2] Seed admin user on startup --- TodoBasicWithAuth/AuthApi.cs | 6 ++---- TodoBasicWithAuth/CreateUser.cs | 19 ------------------- TodoBasicWithAuth/Program.cs | 7 +++++++ TodoBasicWithAuth/sample.http | 12 ------------ 4 files changed, 9 insertions(+), 35 deletions(-) delete mode 100644 TodoBasicWithAuth/CreateUser.cs diff --git a/TodoBasicWithAuth/AuthApi.cs b/TodoBasicWithAuth/AuthApi.cs index 59a6e8b..f7589d6 100644 --- a/TodoBasicWithAuth/AuthApi.cs +++ b/TodoBasicWithAuth/AuthApi.cs @@ -30,9 +30,9 @@ public AuthApi(JwtSettings jwtSettings) public async Task CreateUser(UserManager userManager, HttpContext context) { - var loginInfo = await JsonSerializer.DeserializeAsync(context.Request.Body, _options); + var loginInfo = await JsonSerializer.DeserializeAsync(context.Request.Body, _options); - var result = await userManager.CreateAsync(new TodoUser { UserName = loginInfo.UserName, IsAdmin = loginInfo.IsAdmin }, loginInfo.Password); + var result = await userManager.CreateAsync(new TodoUser { UserName = loginInfo.UserName }, loginInfo.Password); if (result.Succeeded) { @@ -62,8 +62,6 @@ public async Task GenerateTokenAsync(UserManager userManager, HttpCont claims.Add(new Claim("can_delete", "true")); } - - var key = new SymmetricSecurityKey(_jwtSettings.Key); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( diff --git a/TodoBasicWithAuth/CreateUser.cs b/TodoBasicWithAuth/CreateUser.cs deleted file mode 100644 index e27a735..0000000 --- a/TodoBasicWithAuth/CreateUser.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Todos -{ - public class CreateUser - { - [Required] - public string UserName { get; set; } - - [Required] - public string Password { get; set; } - - public bool IsAdmin { get; set; } - } -} diff --git a/TodoBasicWithAuth/Program.cs b/TodoBasicWithAuth/Program.cs index 2f2f001..bc79668 100644 --- a/TodoBasicWithAuth/Program.cs +++ b/TodoBasicWithAuth/Program.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; @@ -31,6 +32,12 @@ static async Task Main(string[] args) var app = builder.Build(); + using (var scope = app.Services.CreateScope()) + { + var userManager = scope.ServiceProvider.GetService>(); + await userManager.CreateAsync(new TodoUser { UserName = "admin", IsAdmin = true }, "Pass123456!" ); + } + app.UseAuthentication(); app.UseAuthorization(); diff --git a/TodoBasicWithAuth/sample.http b/TodoBasicWithAuth/sample.http index 2d24897..54a57ab 100644 --- a/TodoBasicWithAuth/sample.http +++ b/TodoBasicWithAuth/sample.http @@ -16,18 +16,6 @@ Content-Type: application/json ### -// Create admin user -POST http://localhost:5000/api/auth -Content-Type: application/json - -{ - "username" : "admin", - "password" : "Pass123456!", - "isAdmin" : true -} - -### - // Authenticate as regular user # @name LoginRegularUser POST http://localhost:5000/api/auth/token