diff --git a/authentication-service/Controllers/AuthenticationController.cs b/authentication-service/Controllers/AuthenticationController.cs new file mode 100644 index 0000000..ddbb2e7 --- /dev/null +++ b/authentication-service/Controllers/AuthenticationController.cs @@ -0,0 +1,87 @@ +using authentication_service.Models; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; + +namespace authentication_service.Controllers +{ + public class AuthenticationController : Controller + { + private readonly DataContext db; + readonly TokenController TC = new(); + public AuthenticationController(DataContext db) + { + this.db = db; + } + + [HttpPost] + [Route("/api/[controller]/login")] + public object login([FromBody] Person p) + { + Person person = (from Person in db.Person + where Person.Email == p.Email && Person.Password == p.Password + select Person).FirstOrDefault(); + + return person == null ? Unauthorized() : TC.GenerateToken(p.Email, Convert.ToString(person.Role)); + } + + [Route("/api/[controller]/register")] + [HttpPost] + public object register() + { + var x = TC.GenerateToken(null, null); + return x; + } + + [HttpGet] + [Route("/api/[controller]/auth")] + [Authorize] + public string authorize([FromHeader] string Authorization) + { + string[] token = Authorization.Split(' '); + var handler = new JwtSecurityTokenHandler(); + var jwtSecurityToken = handler.ReadJwtToken(token[1]); + string email = ""; + int role = 0; + foreach (Claim c in jwtSecurityToken.Claims) + { + if (c.Type == "email") + { + email = c.Value; + } + else if (ClaimTypes.Role == c.Type) + { + role = Convert.ToInt32(c.Value); + } + } + UserResponse userResponse = new UserResponse(email, role); + string jSonObject = JsonConvert.SerializeObject(userResponse); + return jSonObject; + } + + [HttpGet] + [Route("/api/[controller]/singleUser")] + [Authorize] + public Person GetUser([FromHeader] string Authorization) + { + string[] token = Authorization.Split(' '); + var handler = new JwtSecurityTokenHandler(); + var jwtSecurityToken = handler.ReadJwtToken(token[1]); + string email = ""; + foreach (Claim c in jwtSecurityToken.Claims) + { + if (c.Type == "email") + { + email = c.Value; + } + } + Person p = (from Person in db.Person + where Person.Email == email + select Person).FirstOrDefault(); + return p; + } + } +} diff --git a/authentication-service/Controllers/TokenController.cs b/authentication-service/Controllers/TokenController.cs new file mode 100644 index 0000000..3c740e6 --- /dev/null +++ b/authentication-service/Controllers/TokenController.cs @@ -0,0 +1,29 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; + +namespace authentication_service.Controllers +{ + public class TokenController + { + + private const string SECRET_KEY = "this is my custom Secret key for authnetication"; + public static readonly SymmetricSecurityKey SIGNING_KEY = new(Encoding.UTF8.GetBytes(SECRET_KEY)); + + public object GenerateToken(string email, string role) + { + var token = new JwtSecurityToken( + claims: new Claim[] + { + new("email", email), + new(ClaimTypes.Role, role) + }, + notBefore: DateTime.Now, + expires: DateTime.Now.AddMinutes(60), + signingCredentials: new SigningCredentials(SIGNING_KEY, SecurityAlgorithms.HmacSha256) + ); + + return new JwtSecurityTokenHandler().WriteToken(token); + } + } +} diff --git a/authentication-service/Controllers/WeatherForecastController.cs b/authentication-service/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..13edd7f --- /dev/null +++ b/authentication-service/Controllers/WeatherForecastController.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace authentication_service.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet] + public IEnumerable Get() + { + var rng = new Random(); + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = rng.Next(-20, 55), + Summary = Summaries[rng.Next(Summaries.Length)] + }) + .ToArray(); + } + } +} diff --git a/authentication-service/Data/DataContext.cs b/authentication-service/Data/DataContext.cs new file mode 100644 index 0000000..da337c0 --- /dev/null +++ b/authentication-service/Data/DataContext.cs @@ -0,0 +1,20 @@ +using authentication_service.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace authentication_service.Data +{ + public class DataContext : DbContext + { + public DataContext() + { + } + public DataContext(DbContextOptions options) : base(options) { } + public DbSet Person { get; set; } + + + } +} diff --git a/authentication-service/GlobalUsing.cs b/authentication-service/GlobalUsing.cs new file mode 100644 index 0000000..92e29e5 --- /dev/null +++ b/authentication-service/GlobalUsing.cs @@ -0,0 +1,9 @@ +global using authentication_service.Controllers; +global using authentication_service.Data; +global using Microsoft.AspNetCore.Authentication.JwtBearer; +global using Microsoft.AspNetCore.Builder; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Hosting; +global using Microsoft.IdentityModel.Tokens; +global using System; \ No newline at end of file diff --git a/authentication-service/Migrations/20211117124245_InitialMigration.Designer.cs b/authentication-service/Migrations/20211117124245_InitialMigration.Designer.cs new file mode 100644 index 0000000..713edb4 --- /dev/null +++ b/authentication-service/Migrations/20211117124245_InitialMigration.Designer.cs @@ -0,0 +1,49 @@ +// +using authentication_service.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace authentication_service.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20211117124245_InitialMigration")] + partial class InitialMigration + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.11") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("authentication_service.Models.User", b => + { + b.Property("userId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("email") + .HasColumnType("nvarchar(max)"); + + b.Property("name") + .HasColumnType("nvarchar(max)"); + + b.Property("password") + .HasColumnType("nvarchar(max)"); + + b.Property("role") + .HasColumnType("int"); + + b.HasKey("userId"); + + b.ToTable("Users"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/authentication-service/Migrations/20211117124245_InitialMigration.cs b/authentication-service/Migrations/20211117124245_InitialMigration.cs new file mode 100644 index 0000000..94aecbd --- /dev/null +++ b/authentication-service/Migrations/20211117124245_InitialMigration.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace authentication_service.Migrations +{ + public partial class InitialMigration : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + userId = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + name = table.Column(type: "nvarchar(max)", nullable: true), + email = table.Column(type: "nvarchar(max)", nullable: true), + password = table.Column(type: "nvarchar(max)", nullable: true), + role = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.userId); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/authentication-service/Migrations/20211216124828_ChangedPersonModel.Designer.cs b/authentication-service/Migrations/20211216124828_ChangedPersonModel.Designer.cs new file mode 100644 index 0000000..2bcb98e --- /dev/null +++ b/authentication-service/Migrations/20211216124828_ChangedPersonModel.Designer.cs @@ -0,0 +1,52 @@ +// +using authentication_service.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace authentication_service.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20211216124828_ChangedPersonModel")] + partial class ChangedPersonModel + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.11") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("authentication_service.Models.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("FontysId") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .HasColumnType("nvarchar(max)"); + + b.Property("Role") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Person"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/authentication-service/Migrations/20211216124828_ChangedPersonModel.cs b/authentication-service/Migrations/20211216124828_ChangedPersonModel.cs new file mode 100644 index 0000000..56ffbc6 --- /dev/null +++ b/authentication-service/Migrations/20211216124828_ChangedPersonModel.cs @@ -0,0 +1,52 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace authentication_service.Migrations +{ + public partial class ChangedPersonModel : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Users"); + + migrationBuilder.CreateTable( + name: "Person", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: true), + Email = table.Column(type: "nvarchar(max)", nullable: true), + Password = table.Column(type: "nvarchar(max)", nullable: true), + Role = table.Column(type: "int", nullable: false), + FontysId = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Person", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Person"); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + userId = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + email = table.Column(type: "nvarchar(max)", nullable: true), + name = table.Column(type: "nvarchar(max)", nullable: true), + password = table.Column(type: "nvarchar(max)", nullable: true), + role = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.userId); + }); + } + } +} diff --git a/authentication-service/Migrations/DataContextModelSnapshot.cs b/authentication-service/Migrations/DataContextModelSnapshot.cs new file mode 100644 index 0000000..d330873 --- /dev/null +++ b/authentication-service/Migrations/DataContextModelSnapshot.cs @@ -0,0 +1,50 @@ +// +using authentication_service.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace authentication_service.Migrations +{ + [DbContext(typeof(DataContext))] + partial class DataContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.11") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("authentication_service.Models.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("FontysId") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .HasColumnType("nvarchar(max)"); + + b.Property("Role") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Person"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/authentication-service/Models/Person.cs b/authentication-service/Models/Person.cs new file mode 100644 index 0000000..a660be8 --- /dev/null +++ b/authentication-service/Models/Person.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace authentication_service.Models +{ + public class Person + { + public int Id { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public string Password { get; set; } + public int Role { get; set; } + public string FontysId { get; set; } + + + + } +} diff --git a/authentication-service/Models/User.cs b/authentication-service/Models/User.cs new file mode 100644 index 0000000..82b29fa --- /dev/null +++ b/authentication-service/Models/User.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace authentication_service.Models +{ + public class User + { + [Key] + public int userId { get; set; } + public string name { get; set; } + public string email { get; set; } + public string password { get; set; } + public int role { get; set; } + } +} diff --git a/authentication-service/Models/UserResponse.cs b/authentication-service/Models/UserResponse.cs new file mode 100644 index 0000000..8aa519b --- /dev/null +++ b/authentication-service/Models/UserResponse.cs @@ -0,0 +1,14 @@ +namespace authentication_service.Models +{ + public class UserResponse + { + public string email { get; set; } + public int role { get; set; } + + public UserResponse(string email, int role) + { + this.email = email; + this.role = role; + } + } +} diff --git a/authentication-service/Program.cs b/authentication-service/Program.cs new file mode 100644 index 0000000..d4ac047 --- /dev/null +++ b/authentication-service/Program.cs @@ -0,0 +1,49 @@ +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration["ConnectionString"])); +builder.Services.AddControllers(); + +builder.Services.AddCors(options => +{ + options.AddPolicy("AllowAll", + builder => + { + builder + .AllowAnyOrigin() + .AllowAnyMethod() + .AllowAnyHeader(); + }); +}); + +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(jwtOptions => + { + jwtOptions.TokenValidationParameters = new TokenValidationParameters() + { + IssuerSigningKey = TokenController.SIGNING_KEY, + ValidateIssuer = false, + ValidateAudience = false, + ValidateIssuerSigningKey = false, + ValidateLifetime = true, + ClockSkew = TimeSpan.FromMinutes(5) + }; + }); + +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) app.UseDeveloperExceptionPage(); + +app.UseCors("AllowAll"); + +app.UseHttpsRedirection(); + +app.UseRouting(); + +app.UseAuthentication(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); \ No newline at end of file diff --git a/authentication-service/Properties/launchSettings.json b/authentication-service/Properties/launchSettings.json new file mode 100644 index 0000000..47f39c2 --- /dev/null +++ b/authentication-service/Properties/launchSettings.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:46282", + "sslPort": 44369 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/authentication-service/WeatherForecast.cs b/authentication-service/WeatherForecast.cs new file mode 100644 index 0000000..99ba8ae --- /dev/null +++ b/authentication-service/WeatherForecast.cs @@ -0,0 +1,15 @@ +using System; + +namespace authentication_service +{ + public class WeatherForecast + { + public DateTime Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string Summary { get; set; } + } +} diff --git a/authentication-service/appsettings.Development.json b/authentication-service/appsettings.Development.json new file mode 100644 index 0000000..1bb6069 --- /dev/null +++ b/authentication-service/appsettings.Development.json @@ -0,0 +1,11 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*", + "ConnectionString": "Server=localhost,1433;Database=master;User Id=sa;Password=Ipost11%;" +} diff --git a/authentication-service/appsettings.json b/authentication-service/appsettings.json new file mode 100644 index 0000000..8983e0f --- /dev/null +++ b/authentication-service/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/authentication-service/authentication-service.csproj b/authentication-service/authentication-service.csproj new file mode 100644 index 0000000..1f82167 --- /dev/null +++ b/authentication-service/authentication-service.csproj @@ -0,0 +1,26 @@ + + + + net6.0 + authentication_service + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + +