summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHombreLaser <sebastian-440@live.com>2022-11-15 21:52:57 -0600
committerHombreLaser <sebastian-440@live.com>2022-11-15 21:52:57 -0600
commit00acb66e39f7b178d58f3f0ec298aec73d7aced9 (patch)
treeb2340ca37d815a4da9870c3ecd483e8dbcf95a44
parent820c3a882c60127338293c1eee4059b2dfd535df (diff)
Añadida autenticación
-rw-r--r--.vscode/launch.json46
-rw-r--r--.vscode/tasks.json41
-rw-r--r--Controllers/MessageController.cs17
-rw-r--r--Controllers/UsersController.cs49
-rw-r--r--Controllers/WeatherForecastController.cs3
-rw-r--r--DTOs/LoginRequest.cs8
-rw-r--r--DTOs/UserDTO.cs8
-rw-r--r--Program.cs54
-rw-r--r--appsettings.Development.json4
9 files changed, 201 insertions, 29 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..d055f55
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,46 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": ".NET Core Launch (console)",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build",
+ "program": "${workspaceFolder}/bin/Debug/net7.0/IdentityAPI.dll",
+ "args": [],
+ "cwd": "${workspaceFolder}",
+ "stopAtEntry": false,
+ "console": "integratedTerminal"
+ },
+ {
+ // Use IntelliSense to find out which attributes exist for C# debugging
+ // Use hover for the description of the existing attributes
+ // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
+ "name": ".NET Core Launch (web)",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build",
+ // If you have changed target frameworks, make sure to update the program path.
+ "program": "${workspaceFolder}/bin/Debug/net7.0/IdentityAPI.dll",
+ "args": [],
+ "cwd": "${workspaceFolder}",
+ "stopAtEntry": false,
+ // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
+ "serverReadyAction": {
+ "action": "openExternally",
+ "pattern": "\\bNow listening on:\\s+(https?://\\S+)"
+ },
+ "env": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "sourceFileMap": {
+ "/Views": "${workspaceFolder}/Views"
+ }
+ },
+ {
+ "name": ".NET Core Attach",
+ "type": "coreclr",
+ "request": "attach"
+ }
+ ]
+} \ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..5e018c1
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,41 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "build",
+ "command": "dotnet",
+ "type": "process",
+ "args": [
+ "build",
+ "${workspaceFolder}/IdentityAPI.csproj",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "problemMatcher": "$msCompile"
+ },
+ {
+ "label": "publish",
+ "command": "dotnet",
+ "type": "process",
+ "args": [
+ "publish",
+ "${workspaceFolder}/IdentityAPI.csproj",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "problemMatcher": "$msCompile"
+ },
+ {
+ "label": "watch",
+ "command": "dotnet",
+ "type": "process",
+ "args": [
+ "watch",
+ "run",
+ "--project",
+ "${workspaceFolder}/IdentityAPI.csproj"
+ ],
+ "problemMatcher": "$msCompile"
+ }
+ ]
+} \ No newline at end of file
diff --git a/Controllers/MessageController.cs b/Controllers/MessageController.cs
new file mode 100644
index 0000000..bacaf5c
--- /dev/null
+++ b/Controllers/MessageController.cs
@@ -0,0 +1,17 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authorization;
+
+namespace IdentityAPI.Controllers {
+ [ApiController]
+ [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
+ [Route("api/message")]
+ public class MessageController : ControllerBase {
+ public MessageController() {}
+
+ [HttpGet]
+ public async Task<IActionResult> Show() {
+ return Ok(new { message = "Authentication succesful" });
+ }
+ }
+} \ No newline at end of file
diff --git a/Controllers/UsersController.cs b/Controllers/UsersController.cs
index 52c9105..d5dded5 100644
--- a/Controllers/UsersController.cs
+++ b/Controllers/UsersController.cs
@@ -8,7 +8,7 @@ using Microsoft.EntityFrameworkCore;
using System.Text;
using System.Security.Claims;
using IdentityAPI.Models;
-using IdentityAPI.DTO;
+using IdentityAPI.DTOs;
namespace IdentityAPI.Controllers {
[Route("api/users")]
@@ -24,30 +24,49 @@ namespace IdentityAPI.Controllers {
_manager = manager;
}
- [HttpPost("signup")]
- public async Task<IActionResult> PostUser(UserDTO data) {
- var user = new IdentityUser { UserName = data.UserName, Email = data.Email };
- var result = await _manager.CreateAsync(user, data.Password);
+ [HttpPost("signup")]
+ public async Task<IActionResult> SignUp(UserDTO data) {
+ var user = new IdentityUser { UserName = data.UserName, Email = data.Email };
+ var result = await _manager.CreateAsync(user, data.Password);
- if(result.Succeeded)
- return Ok(new { Token = GenerateToken(user) });
+ if(result.Succeeded)
+ return Ok(new { Token = GenerateToken(user) });
return StatusCode(422, new { error = "The provided user is invalid" });
}
- private string GenerateToken(IdentityUser user) {
+ [HttpPost("login")]
+ public async Task<IActionResult> Login(LoginRequest data) {
+ if(data != null && data.Email != null && data.Password != null) {
+ var user = await _manager.FindByEmailAsync(data.Email);
+
+ if(user == null)
+ return StatusCode(404, new { error = "Nonexistent user" });
+
+ var result = await _manager.CheckPasswordAsync(user, data.Password);
+
+ if(result)
+ return Ok(new { Token = GenerateToken(user)} );
+
+ return StatusCode(401, new { error = "Wrong credentials" });
+ }
+
+ return StatusCode(400, new { error = "Invalid request body" });
+ }
+
+ private string GenerateToken(IdentityUser user) {
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
- var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
+ var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expiration = DateTime.UtcNow.AddMinutes(30);
- var issuer = _configuration["Jwt:Issuer"];
+ //var issuer = _configuration["Jwt:Issuer"];
var claims = new List<Claim> {
- new Claim("sid", user.Id),
- new Claim("username", user.UserName),
- new Claim("email", user.Email)
- };
+ new Claim("sid", user.Id),
+ new Claim("username", user.UserName),
+ new Claim("email", user.Email)
+ };
var descriptor = new JwtSecurityToken(issuer: null, audience: null, claims: claims, expires: expiration, signingCredentials: creds);
return new JwtSecurityTokenHandler().WriteToken(descriptor);
}
}
-}
+} \ No newline at end of file
diff --git a/Controllers/WeatherForecastController.cs b/Controllers/WeatherForecastController.cs
index 801ee5e..f7fdcdf 100644
--- a/Controllers/WeatherForecastController.cs
+++ b/Controllers/WeatherForecastController.cs
@@ -1,8 +1,11 @@
using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authorization;
namespace IdentityAPI.Controllers;
[ApiController]
+[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
diff --git a/DTOs/LoginRequest.cs b/DTOs/LoginRequest.cs
new file mode 100644
index 0000000..9bbef43
--- /dev/null
+++ b/DTOs/LoginRequest.cs
@@ -0,0 +1,8 @@
+namespace IdentityAPI.DTOs {
+ public class LoginRequest {
+ #nullable enable
+ public string? Email { get; set; }
+ public string? Password { get; set; }
+ #nullable disable
+ }
+} \ No newline at end of file
diff --git a/DTOs/UserDTO.cs b/DTOs/UserDTO.cs
index 9336817..963c3fe 100644
--- a/DTOs/UserDTO.cs
+++ b/DTOs/UserDTO.cs
@@ -1,9 +1,9 @@
-namespace IdentityAPI.DTO {
+namespace IdentityAPI.DTOs {
public class UserDTO {
- #nullable enable
+ #nullable enable
public string? UserName { get; set; }
- public string? Email { get; set; }
+ public string? Email { get; set; }
public string? Password { get; set; }
- #nullable disable
+ #nullable disable
}
}
diff --git a/Program.cs b/Program.cs
index 28b00d9..a69992d 100644
--- a/Program.cs
+++ b/Program.cs
@@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
+using Microsoft.OpenApi.Models;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
@@ -15,19 +16,52 @@ builder.Services.AddControllers();
builder.Services.AddDbContext<ApplicationDbContext>(o => o.UseNpgsql(builder.Configuration.GetConnectionString("ApplicationDbContext")));
builder.Services.AddIdentity<IdentityUser, IdentityRole>()
// .AddRoles<IdentityRole>()
- .AddEntityFrameworkStores<ApplicationDbContext>();
+ .AddEntityFrameworkStores<ApplicationDbContext>()
+ .AddDefaultTokenProviders();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
-builder.Services.AddSwaggerGen();
+builder.Services.AddSwaggerGen(c => {
+ c.SwaggerDoc("v1", new OpenApiInfo { Title = "IdentityAPI", Version = "v1" });
+
+ c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
+ {
+ Name = "Authorization",
+ Type = SecuritySchemeType.ApiKey,
+ Scheme = "Bearer",
+ BearerFormat = "JWT",
+ In = ParameterLocation.Header
+ });
+
+ c.AddSecurityRequirement(new OpenApiSecurityRequirement
+ {
+ {
+ new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference
+ {
+ Type = ReferenceType.SecurityScheme,
+ Id = "Bearer"
+ }
+ },
+ new String[]{}
+ }
+ });
+ });
// Autenticación con JSON web tokens.
-builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
- .AddJwtBearer(options => {
- options.TokenValidationParameters = new TokenValidationParameters {
- ValidateLifetime = true,
- ValidateIssuer = true,
- ValidIssuer = builder.Configuration["Jwt:Issuer"],
- IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
- };
+builder.Services.AddAuthorization();
+builder.Services.AddAuthentication(options => {
+ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
+ })
+ .AddJwtBearer(options => {
+ options.TokenValidationParameters = new TokenValidationParameters {
+ ValidateIssuer = false,
+ ValidateAudience = false,
+ ValidateLifetime = true,
+ IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])),
+ ClockSkew = TimeSpan.Zero
+ };
});
builder.Services.Configure<IdentityOptions>(options =>
{
diff --git a/appsettings.Development.json b/appsettings.Development.json
index 0c208ae..588f258 100644
--- a/appsettings.Development.json
+++ b/appsettings.Development.json
@@ -4,5 +4,9 @@
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
+ },
+ "Jwt": {
+ "Key": "3aa68fb64d638cd66a0485fce8fcdb49",
+ "Issuer": "jwtissuer.com"
}
}