diff --git a/Controllers/AuthController.cs b/Controllers/AuthController.cs new file mode 100644 index 0000000..e166520 --- /dev/null +++ b/Controllers/AuthController.cs @@ -0,0 +1,46 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; +using Microsoft.AspNetCore.Mvc; +using Microsoft.IdentityModel.Tokens; + +namespace backend.Controllers; + +[ApiController] +[Route("[controller]")] +public class AuthController : ControllerBase +{ + public IConfiguration _configuration; + public AuthController(IConfiguration configuration) + { + _configuration = configuration; + } + + [HttpPost("login")] + public async Task Login(string username, string password) + { + if (username == "" || password == "") + { + return BadRequest("Invalid username or password"); + } + + if (username == "test" && password == "test") + { + var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:secret"])); + var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256); + + var tokeOptions = new JwtSecurityToken( + issuer: _configuration["Jwt:Issuer"], + audience: _configuration["Jwt:Audience"], + claims: new List(), + expires: DateTime.Now.AddDays(1), + signingCredentials: signinCredentials + ); + + var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions); + return Ok(new { Token = tokenString }); + } + + return BadRequest("Invalid username or password"); + } +} \ No newline at end of file diff --git a/Controllers/BlogPostController.cs b/Controllers/BlogPostController.cs index dc2f0e2..b0ccf97 100644 --- a/Controllers/BlogPostController.cs +++ b/Controllers/BlogPostController.cs @@ -1,5 +1,6 @@ using backend.Models; using backend.Services; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace backend.Controllers; @@ -26,6 +27,7 @@ public class BlogPostController: ControllerBase public async Task> GetLast(int n) => await _blogPostService.GetLastNPostsAsync(n); + [Authorize] [HttpPost] public async Task Post([FromBody]BlogPost post) { diff --git a/Program.cs b/Program.cs index 5344603..c429b82 100644 --- a/Program.cs +++ b/Program.cs @@ -3,6 +3,7 @@ using backend.Models; using backend.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; var builder = WebApplication.CreateBuilder(args); @@ -10,18 +11,62 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.Configure(builder.Configuration.GetSection("BlogDatabase")); -//Authentication -builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddControllers(); +//Authentication +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer( + options => + { + options.RequireHttpsMetadata = false; + options.SaveToken = false; + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + ValidIssuer = builder.Configuration["Jwt:Issuer"], + ValidAudience = builder.Configuration["Jwt:Audience"], + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:secret"])) + }; + }); // 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 = "WebServer", Version = "v1" }); + + // We need to tell swagger that we want to support authentication + c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() + { + Name = "Authorization", + Type = SecuritySchemeType.Http, + Scheme = "Bearer", + In = ParameterLocation.Header, + BearerFormat = "Bearer", + Description = "The Bearer token needed to access the initial part of the api.", + }); + + // And again since once is not enough? + c.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = "Bearer", + }, + }, + Array.Empty() + }, + }); +}); var app = builder.Build(); diff --git a/appsettings.json b/appsettings.json index dc833af..49d0010 100644 --- a/appsettings.json +++ b/appsettings.json @@ -1,4 +1,10 @@ { + "Jwt": { + "secret": "s6v9y$B&E)H@McQf", + "Issuer": "http://www.olivierboeren.nl", + "Audience": "http://www.olivierboeren.nl", + + }, "BlogDatabase": { "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "Blog",