mirror of
https://github.com/hubHarmony/Csharp-API-Template.git
synced 2024-11-17 21:40:31 +00:00
{V0.4} Added Authentication, easily settable for all routes.
This commit is contained in:
parent
77a34a878d
commit
fd6860d102
119
Controllers/Default.cs
Normal file
119
Controllers/Default.cs
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Simple_API.Controllers
|
||||||
|
{
|
||||||
|
|
||||||
|
[Route("auth/")]
|
||||||
|
[ApiController]
|
||||||
|
public class Default(IConfiguration configuration) : ControllerBase
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public class AuthPayload
|
||||||
|
{
|
||||||
|
[DataType(DataType.EmailAddress)]
|
||||||
|
[EmailAddress(ErrorMessage = "Invalid Email Address.")]
|
||||||
|
[Required(ErrorMessage = "Email address is required.")]
|
||||||
|
public string? Email { get; init; } = string.Empty;
|
||||||
|
|
||||||
|
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Required(ErrorMessage = "Password is required.")]
|
||||||
|
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$",
|
||||||
|
ErrorMessage = "Password must be at least 8 characters long and contain at least one uppercase letter,"
|
||||||
|
+ " one lowercase letter, one number, and one special character.")]
|
||||||
|
public string? Password { get; init; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("register")]
|
||||||
|
public IActionResult Register([FromBody] AuthPayload authPayload)
|
||||||
|
{
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("login")]
|
||||||
|
public IActionResult Login([FromBody] AuthPayload authPayload)
|
||||||
|
{
|
||||||
|
// Here, you would typically validate the user's credentials against a database.
|
||||||
|
if (authPayload.Email == "test@example.com" && authPayload.Password == "Password123!")
|
||||||
|
{
|
||||||
|
var claims = new[]
|
||||||
|
{
|
||||||
|
new Claim(ClaimTypes.Email, authPayload.Email),
|
||||||
|
new Claim(ClaimTypes.Role, "Admin"),
|
||||||
|
new Claim(ClaimTypes.GivenName, "Test_ID"),
|
||||||
|
};
|
||||||
|
|
||||||
|
var configKey = configuration["Jwt:Key"];
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(configKey))
|
||||||
|
{
|
||||||
|
return StatusCode(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configKey));
|
||||||
|
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
||||||
|
|
||||||
|
var token = new JwtSecurityToken(
|
||||||
|
issuer: configuration["Jwt:Issuer"],
|
||||||
|
audience: configuration["Jwt:Audience"],
|
||||||
|
claims: claims,
|
||||||
|
expires: DateTime.Now.AddMinutes(190),
|
||||||
|
signingCredentials: credentials);
|
||||||
|
|
||||||
|
return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) });
|
||||||
|
}
|
||||||
|
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Route("test/")]
|
||||||
|
[ApiController]
|
||||||
|
public class Test : ControllerBase
|
||||||
|
{
|
||||||
|
public class TestPayload
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "Data field is required.")]
|
||||||
|
public string? Data { get; init; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private const string ProtocolOk = "Protocol tested successfully.";
|
||||||
|
|
||||||
|
// GET: test/get
|
||||||
|
[Authorize]
|
||||||
|
[HttpGet("get")]
|
||||||
|
public IActionResult TestGet()
|
||||||
|
{
|
||||||
|
return Ok($"GET: {ProtocolOk}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: test/post
|
||||||
|
[HttpPost("post")]
|
||||||
|
public IActionResult TestPost([FromBody] TestPayload testPayload)
|
||||||
|
{
|
||||||
|
return Ok($"POST: {ProtocolOk} Received: {testPayload.Data}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT: test/put
|
||||||
|
[HttpPut("put")]
|
||||||
|
public IActionResult TestPut([FromBody] TestPayload testPayload)
|
||||||
|
{
|
||||||
|
return Ok($"PUT: {ProtocolOk} Updated: {testPayload.Data}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE: test/delete
|
||||||
|
[HttpDelete("delete")]
|
||||||
|
public IActionResult TestDelete([FromBody] TestPayload testPayload)
|
||||||
|
{
|
||||||
|
return Ok($"DELETE: {ProtocolOk} Deleted: {testPayload.Data}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
Controllers/Delete.cs
Normal file
6
Controllers/Delete.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace Simple_API.Controllers;
|
||||||
|
|
||||||
|
public class Delete
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
6
Controllers/Get.cs
Normal file
6
Controllers/Get.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace Simple_API.Controllers;
|
||||||
|
|
||||||
|
public class Get
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
6
Controllers/Post.cs
Normal file
6
Controllers/Post.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace Simple_API.Controllers;
|
||||||
|
|
||||||
|
public class Post
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
6
Controllers/Put.cs
Normal file
6
Controllers/Put.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace Simple_API.Controllers;
|
||||||
|
|
||||||
|
public class Put
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
67
Program.cs
67
Program.cs
@ -1,8 +1,15 @@
|
|||||||
|
using System.Text;
|
||||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
|
||||||
|
//Builder configuration
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen();
|
builder.Services.AddSwaggerGen();
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
builder.Services.AddControllersWithViews();
|
||||||
builder.Services.AddCors(options =>
|
builder.Services.AddCors(options =>
|
||||||
{
|
{
|
||||||
options.AddPolicy("AllowAllOrigins", corsBuilder =>
|
options.AddPolicy("AllowAllOrigins", corsBuilder =>
|
||||||
@ -13,9 +20,44 @@ builder.Services.AddCors(options =>
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// JWT Configuration
|
||||||
|
var jwtSettings = builder.Configuration.GetSection("Jwt");
|
||||||
|
var key = jwtSettings["Key"];
|
||||||
|
var issuer = jwtSettings["Issuer"];
|
||||||
|
var audience = jwtSettings["Audience"];
|
||||||
|
if (string.IsNullOrEmpty(key))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
builder.Services.AddAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
})
|
||||||
|
.AddJwtBearer(options =>
|
||||||
|
{
|
||||||
|
options.TokenValidationParameters = new TokenValidationParameters
|
||||||
|
{
|
||||||
|
ValidateIssuer = true,
|
||||||
|
ValidateAudience = true,
|
||||||
|
ValidateLifetime = true,
|
||||||
|
ValidateIssuerSigningKey = true,
|
||||||
|
ValidIssuer = issuer,
|
||||||
|
ValidAudience = audience,
|
||||||
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key))
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Build
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// App configuration
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
if (app.Environment.IsDevelopment())
|
if (app.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
@ -23,31 +65,10 @@ if (app.Environment.IsDevelopment())
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
|
app.UseAuthentication();
|
||||||
|
app.UseAuthorization();
|
||||||
app.UseCors("AllowAllOrigins");
|
app.UseCors("AllowAllOrigins");
|
||||||
|
|
||||||
var summaries = new[]
|
|
||||||
{
|
|
||||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
|
||||||
};
|
|
||||||
|
|
||||||
app.MapGet("/weatherforecast", () =>
|
|
||||||
{
|
|
||||||
var forecast = Enumerable.Range(1, 5).Select(index =>
|
|
||||||
new WeatherForecast
|
|
||||||
(
|
|
||||||
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
|
|
||||||
Random.Shared.Next(-20, 55),
|
|
||||||
summaries[Random.Shared.Next(summaries.Length)]
|
|
||||||
))
|
|
||||||
.ToArray();
|
|
||||||
return forecast;
|
|
||||||
})
|
|
||||||
.WithName("GetWeatherForecast")
|
|
||||||
.WithOpenApi();
|
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|
||||||
internal record WeatherForecast (DateOnly Date, int TemperatureC, string? Summary)
|
|
||||||
{
|
|
||||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
|
||||||
}
|
|
@ -8,6 +8,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8"/>
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8"/>
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0"/>
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -4,3 +4,7 @@ GET {{Simple_API_HostAddress}}/weatherforecast/
|
|||||||
Accept: application/json
|
Accept: application/json
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
|
GET {{Simple_API_HostAddress}}/test/get
|
||||||
|
Authorization: Bearer 1
|
||||||
|
###
|
@ -5,5 +5,10 @@
|
|||||||
"Microsoft.AspNetCore": "Warning"
|
"Microsoft.AspNetCore": "Warning"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*"
|
"AllowedHosts": "*",
|
||||||
|
"Jwt": {
|
||||||
|
"Key": "9831A382FD7395DD4D4F64B554962^&6@Vw1qR!Lg$+Pz",
|
||||||
|
"Issuer": "HubHarmonyApiTemplate",
|
||||||
|
"Audience": "HubHarmonyApiTemplate"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user