From a2c90f80d556d2b5447db563b4c205b4ba41d1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Zieli=C5=84ski?= Date: Fri, 9 Dec 2022 00:14:05 +0100 Subject: [PATCH] Backend authentication --- Frontend/src/app/app.module.ts | 6 ++ Frontend/src/app/auth/auth.service.ts | 5 +- .../login-page/login-page.component.ts | 5 +- .../src/app/interceptors/auth.interceptor.ts | 26 +++++++++ Frontend/src/environments/environment.ts | 4 +- WebAPI/Controllers/AuthController.cs | 34 +++++------ WebAPI/Program.cs | 57 +++++++++---------- WebAPI/WebAPI.csproj | 6 +- 8 files changed, 83 insertions(+), 60 deletions(-) create mode 100644 Frontend/src/app/interceptors/auth.interceptor.ts diff --git a/Frontend/src/app/app.module.ts b/Frontend/src/app/app.module.ts index 3fd2b5e..26511ec 100644 --- a/Frontend/src/app/app.module.ts +++ b/Frontend/src/app/app.module.ts @@ -10,6 +10,7 @@ import { LoginPageComponent } from './components/login-page/login-page.component import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { ServiceWorkerModule } from '@angular/service-worker'; import { LoaderInterceptor } from './interceptors/loader.interceptor'; +import { AuthInterceptor } from './interceptors/auth.interceptor'; @NgModule({ @@ -37,6 +38,11 @@ import { LoaderInterceptor } from './interceptors/loader.interceptor'; useClass: LoaderInterceptor, multi: true }, + { + provide: HTTP_INTERCEPTORS, + useClass: AuthInterceptor, + multi: true + }, ], bootstrap: [AppComponent] }) diff --git a/Frontend/src/app/auth/auth.service.ts b/Frontend/src/app/auth/auth.service.ts index 6379cd2..19399d7 100644 --- a/Frontend/src/app/auth/auth.service.ts +++ b/Frontend/src/app/auth/auth.service.ts @@ -15,10 +15,9 @@ export class AuthService { private http$: HttpClient ) { } - loadDbUser() { + ping() { return new Promise((resolve, reject) => { const headers = new HttpHeaders({ - // 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiToken}` }) this.http$.get(`${environment.api.url}/ping/ping`, { @@ -43,7 +42,7 @@ export class AuthService { const header = new HttpHeaders().set('Content-type', 'application/json'); this.http$.post(`${environment.api.url}/auth/apiToken`, JSON.stringify(credentials), { headers: header }).subscribe({ next: (data) => { - console.log('apiToken', data); + if (this.user) { this.user.id = data.id } this.apiToken = data.token; resolve(data); }, diff --git a/Frontend/src/app/components/login-page/login-page.component.ts b/Frontend/src/app/components/login-page/login-page.component.ts index 90d1796..ad7bb38 100644 --- a/Frontend/src/app/components/login-page/login-page.component.ts +++ b/Frontend/src/app/components/login-page/login-page.component.ts @@ -43,7 +43,6 @@ export class LoginPageComponent implements OnInit { async handleCredentialResponse(response: any) { try { - console.log("Google Response", response); const responsePayload: any = jwt_decode(response.credential); this.data$.currentUser = new User({ googleCredentials: response.credential, @@ -51,10 +50,8 @@ export class LoginPageComponent implements OnInit { email: responsePayload.email, avatar: responsePayload.picture }); - // this.auth$.loadDbUser(); - console.log("USer", this.data$.currentUser); await this.auth$.getAPIToken(response.credential); - // this.auth$.loadDbUser(); + this.auth$.ping(); this.ngZone$.run(() => { this.router$.navigate(['/app']); }); diff --git a/Frontend/src/app/interceptors/auth.interceptor.ts b/Frontend/src/app/interceptors/auth.interceptor.ts new file mode 100644 index 0000000..10e724e --- /dev/null +++ b/Frontend/src/app/interceptors/auth.interceptor.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@angular/core'; +import { + HttpRequest, + HttpHandler, + HttpEvent, + HttpInterceptor +} from '@angular/common/http'; +import { AuthService } from '../auth/auth.service'; +import { Observable } from 'rxjs'; + +@Injectable() +export class AuthInterceptor implements HttpInterceptor { + constructor( + private auth$: AuthService + ) { } + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + if (!request.url.includes('/auth/apiToken')) { + return next.handle(request.clone({ + headers: request.headers.set('Authorization', `Bearer ${this.auth$.apiToken}`), + })); + } else { + return next.handle(request); + } + } +} diff --git a/Frontend/src/environments/environment.ts b/Frontend/src/environments/environment.ts index ebde33f..06438ce 100644 --- a/Frontend/src/environments/environment.ts +++ b/Frontend/src/environments/environment.ts @@ -5,8 +5,8 @@ export const environment = { production: false, api: { - //url: "http://localhost:5183/api" - url: "https://diuna.bim-it.pl/api" + url: "http://localhost:5400/api" + //url: "https://diuna.bim-it.pl/api" }, google: { clientId: "107631825312-bkfe438ehr9k9ecb2h76g802tj6advma.apps.googleusercontent.com" diff --git a/WebAPI/Controllers/AuthController.cs b/WebAPI/Controllers/AuthController.cs index 6f80498..b5fefaa 100644 --- a/WebAPI/Controllers/AuthController.cs +++ b/WebAPI/Controllers/AuthController.cs @@ -1,5 +1,6 @@ using Google.Apis.Auth; using Google.Apis.Http; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Identity.Client.Platforms.Features.DesktopOs.Kerberos; @@ -14,6 +15,7 @@ namespace WebAPI.Controllers { [ApiController] [Route("api/[controller]")] + // [Authorize] public class AuthController : Controller { private readonly AppDbContext db; @@ -44,29 +46,27 @@ namespace WebAPI.Controllers private dynamic JWTGenerator(User user) { - var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(configuration.GetValue("Secret")); var tokenDescriptor = new SecurityTokenDescriptor { - Subject = new ClaimsIdentity(new[] { new Claim("username", user.UserName) }), - Expires = DateTime.UtcNow.AddDays(7), - SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature) + Subject = new ClaimsIdentity(new[] + { + new Claim("Id", Guid.NewGuid().ToString()), + new Claim(JwtRegisteredClaimNames.Sub, user.UserName), + new Claim(JwtRegisteredClaimNames.Jti, + Guid.NewGuid().ToString()) + }), + Expires = DateTime.UtcNow.AddMinutes(5), + SigningCredentials = new SigningCredentials + (new SymmetricSecurityKey(key), + SecurityAlgorithms.HmacSha512Signature) }; + var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); - var encrypterToken = tokenHandler.WriteToken(token); - - HttpContext.Response.Cookies.Append("token", encrypterToken, - new CookieOptions - { - Expires = DateTime.Now.AddDays(7), - HttpOnly = true, - Secure = true, - IsEssential = true, - SameSite = SameSiteMode.None - }); - - return new { token = encrypterToken, username = user.UserName }; + var jwtToken = tokenHandler.WriteToken(token); + var stringToken = tokenHandler.WriteToken(token); + return new { token = stringToken, id = user.Id }; } } } \ No newline at end of file diff --git a/WebAPI/Program.cs b/WebAPI/Program.cs index 523f4a5..c30e6b1 100644 --- a/WebAPI/Program.cs +++ b/WebAPI/Program.cs @@ -25,44 +25,39 @@ builder.Services.AddCors(options => }); }); -builder.Services.AddAuthentication(x => -{ - x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; -}).AddCookie(x => -{ - x.Cookie.Name = "token"; - -}).AddJwtBearer(x => -{ - x.RequireHttpsMetadata = false; - x.SaveToken = true; - x.TokenValidationParameters = new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration.GetValue("Secret"))), - ValidateIssuer = false, - ValidateAudience = false - }; - x.Events = new JwtBearerEvents - { - OnMessageReceived = context => - { - //context.Token = context.Request.Cookies["token"]; - context.Token = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Ik1pY2hhbCBaaWVsaW5za2kiLCJuYmYiOjE2NzAyODk3NTAsImV4cCI6MTY3MDg5NDU1MCwiaWF0IjoxNjcwMjg5NzUwfQ.XZ1lE_Jio9N5aetvY8qX8rS2xoIcPw3GJWGSatPh1VokQkrILOowvvibdGViQOOi39qGBOFKa8JC61XcaL-1qw"; - return Task.CompletedTask; - } - }; - -}); - builder.Services.AddControllers(); + +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, + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Secret"])) + }; +}); +builder.Services.AddAuthorization(); + + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); +app.Use(async (context, next) => +{ + context.Request.Headers.TryGetValue("Authorization", out var auth); + await next(context); +}); + // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { diff --git a/WebAPI/WebAPI.csproj b/WebAPI/WebAPI.csproj index d644760..f2a2ba6 100644 --- a/WebAPI/WebAPI.csproj +++ b/WebAPI/WebAPI.csproj @@ -1,14 +1,14 @@ - + - net6.0 + net7.0 enable enable - +