From e28787d29bee1cfbb38463010e2d2b7c80c448c5 Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Tue, 5 Jan 2021 11:37:52 +0100 Subject: [PATCH 01/11] added new lines to gitignore --- quartz-manager-parent/.gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/quartz-manager-parent/.gitignore b/quartz-manager-parent/.gitignore index 0c2b833..d6593c5 100644 --- a/quartz-manager-parent/.gitignore +++ b/quartz-manager-parent/.gitignore @@ -1,2 +1,5 @@ -/.settings/ +/**/.settings/ /.project +/**/target +.classpath +.project From d374be5eee47899d6f11ebe78c579b9ea02880f6 Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Tue, 5 Jan 2021 20:59:20 +0100 Subject: [PATCH 02/11] #22 added a maven sub-module to create a webjar for the frontend --- quartz-manager-frontend/angular.json | 2 +- quartz-manager-parent/pom.xml | 1 + .../quartz-manager-fe-builder/pom.xml | 135 ++++++++++++++++++ 3 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 quartz-manager-parent/quartz-manager-fe-builder/pom.xml diff --git a/quartz-manager-frontend/angular.json b/quartz-manager-frontend/angular.json index ce967bd..7ebabad 100644 --- a/quartz-manager-frontend/angular.json +++ b/quartz-manager-frontend/angular.json @@ -12,7 +12,7 @@ "builder": "@angular-devkit/build-angular:browser", "options": { "aot": true, - "outputPath": "../server/src/main/resources/static", + "outputPath": "dist", "index": "src/index.html", "main": "src/main.ts", "tsConfig": "src/tsconfig.app.json", diff --git a/quartz-manager-parent/pom.xml b/quartz-manager-parent/pom.xml index 8ff19a3..7f55372 100644 --- a/quartz-manager-parent/pom.xml +++ b/quartz-manager-parent/pom.xml @@ -18,6 +18,7 @@ quartz-manager-api quartz-manager-web + quartz-manager-fe-builder diff --git a/quartz-manager-parent/quartz-manager-fe-builder/pom.xml b/quartz-manager-parent/quartz-manager-fe-builder/pom.xml new file mode 100644 index 0000000..6591064 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-fe-builder/pom.xml @@ -0,0 +1,135 @@ + + + 4.0.0 + + it.fabioformosa.quartz-manager + quartz-manager-parent + 2.2.2-SNAPSHOT + + + quartz-manager-fe-builder + + Quartz Manager FE Builder + Builder for frontend + + https://github.com/fabioformosa/quartz-manager + + ${basedir}/../.. + UTF-8 + UTF-8 + 1.8 + quartz-manager-frontend + v10.16.3 + 6.9.0 + + + + + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.6 + + + copy-resources + generate-resources + + copy-resources + + + ${basedir}/target/tmp + + + ../../${frontend.folderName} + + static/** + dist/** + node_modules/** + + + + + + + + + + + com.github.eirslett + frontend-maven-plugin + 1.11.0 + + target/tmp + + + + + install node and npm + + install-node-and-npm + + generate-resources + + ${node.version} + ${npm.version} + + + + + npm install + + npm + + process-resources + + install + + + + + npm run build + + npm + + process-resources + + run build + + + + + + + + + maven-antrun-plugin + 1.8 + + + clean build files + process-resources + + + + + + + + + + + run + + + + + + + + From 382fe244c5c1a94c393e8cd54c4da66f39d023dc Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Sat, 30 Jan 2021 15:20:30 +0100 Subject: [PATCH 03/11] #22 Adapted frontend to be wrapped into a webjar --- quartz-manager-frontend/package.json | 2 +- quartz-manager-frontend/src/app/app.module.ts | 24 ++++++++++++------- .../src/app/services/config.service.ts | 23 +++++++++++++++++- .../app/services/logs.websocket.service.ts | 6 ++--- .../services/progress.websocket.service.ts | 6 ++--- .../src/app/services/scheduler.service.ts | 15 ++++++------ quartz-manager-frontend/src/index.html | 1 - quartz-manager-parent/pom.xml | 2 +- .../pom.xml | 6 ++--- 9 files changed, 57 insertions(+), 28 deletions(-) rename quartz-manager-parent/{quartz-manager-fe-builder => quartz-manager-ui-webjar}/pom.xml (94%) diff --git a/quartz-manager-frontend/package.json b/quartz-manager-frontend/package.json index 8e7cf69..d416c60 100644 --- a/quartz-manager-frontend/package.json +++ b/quartz-manager-frontend/package.json @@ -5,7 +5,7 @@ "scripts": { "ng": "ng", "start": "ng serve --proxy-config proxy.conf.json", - "build": "ng build", + "build": "ng build --prod", "test": "jest", "lint": "ng lint", "e2e": "ng e2e" diff --git a/quartz-manager-frontend/src/app/app.module.ts b/quartz-manager-frontend/src/app/app.module.ts index 90e0d34..5274d28 100644 --- a/quartz-manager-frontend/src/app/app.module.ts +++ b/quartz-manager-frontend/src/app/app.module.ts @@ -45,15 +45,19 @@ import { SchedulerService, ConfigService, ProgressWebsocketService, - LogsWebsocketService + LogsWebsocketService, + getHtmlBaseUrl } from './services'; import { ChangePasswordComponent } from './views/change-password/change-password.component'; import { ForbiddenComponent } from './views/forbidden/forbidden.component'; +import { APP_BASE_HREF } from '@angular/common'; +import { environment } from '../environments/environment'; export function initUserFactory(userService: UserService) { return () => userService.jsessionInitUser(); } + // const stompConfig: StompConfig = { // // Which server? // url: 'ws://localhost:8080/quartz-manager/progress', @@ -131,6 +135,16 @@ export function jwtOptionsFactory(apiService: ApiService) { FlexLayoutModule ], providers: [ + { + provide: APP_BASE_HREF, + useValue: getHtmlBaseUrl() + }, + { + 'provide': APP_INITIALIZER, + 'useFactory': initUserFactory, + 'deps': [UserService], + 'multi': true + }, LoginGuard, GuestGuard, AdminGuard, @@ -141,13 +155,7 @@ export function jwtOptionsFactory(apiService: ApiService) { ApiService, UserService, ConfigService, - MatIconRegistry, - { - 'provide': APP_INITIALIZER, - 'useFactory': initUserFactory, - 'deps': [UserService], - 'multi': true - } + MatIconRegistry // StompService, // ServerSocket // { diff --git a/quartz-manager-frontend/src/app/services/config.service.ts b/quartz-manager-frontend/src/app/services/config.service.ts index 28ad1f5..9294bec 100644 --- a/quartz-manager-frontend/src/app/services/config.service.ts +++ b/quartz-manager-frontend/src/app/services/config.service.ts @@ -1,9 +1,30 @@ import { Injectable } from '@angular/core'; +import { environment } from '../../environments/environment'; + + +const WEBJAR_PATH = '/quartz-manager-ui/'; + +export function getHtmlBaseUrl(){ + const baseUrl = getBaseUrl() || '/'; + return environment.production ? getBaseUrl() + WEBJAR_PATH: '/'; + } + +export function getBaseUrl(){ + if(environment.production){ + let contextPath: string = window.location.pathname.split('/')[1] || ''; + if(contextPath && ('/' + contextPath + '/') === WEBJAR_PATH) + return ''; + if(contextPath) + contextPath = '/' + contextPath; + return contextPath; + } + return ''; +} @Injectable() export class ConfigService { - private _api_url = '/quartz-manager/api' + private _api_url = getBaseUrl() + '/quartz-manager/api' private _refresh_token_url = this._api_url + '/refresh'; diff --git a/quartz-manager-frontend/src/app/services/logs.websocket.service.ts b/quartz-manager-frontend/src/app/services/logs.websocket.service.ts index fe2cd06..989269c 100644 --- a/quartz-manager-frontend/src/app/services/logs.websocket.service.ts +++ b/quartz-manager-frontend/src/app/services/logs.websocket.service.ts @@ -1,12 +1,12 @@ -import { Injectable, OnInit } from '@angular/core'; -import { WebsocketService, ApiService } from '.'; +import { Injectable } from '@angular/core'; +import { WebsocketService, ApiService, getBaseUrl } from '.'; import { SocketOption } from '../model/SocketOption.model'; @Injectable() export class LogsWebsocketService extends WebsocketService { constructor(private apiService: ApiService){ - super(new SocketOption('/quartz-manager/logs', '/topic/logs', apiService.getToken)) + super(new SocketOption( getBaseUrl() +'/quartz-manager/logs', '/topic/logs', apiService.getToken)) } } \ No newline at end of file diff --git a/quartz-manager-frontend/src/app/services/progress.websocket.service.ts b/quartz-manager-frontend/src/app/services/progress.websocket.service.ts index 173428b..f81c627 100644 --- a/quartz-manager-frontend/src/app/services/progress.websocket.service.ts +++ b/quartz-manager-frontend/src/app/services/progress.websocket.service.ts @@ -1,12 +1,12 @@ -import { Injectable, OnInit } from '@angular/core'; -import { WebsocketService, ApiService } from '.'; +import { Injectable } from '@angular/core'; +import { WebsocketService, ApiService, getBaseUrl } from '.'; import { SocketOption } from '../model/SocketOption.model'; @Injectable() export class ProgressWebsocketService extends WebsocketService { constructor(private apiService: ApiService){ - super(new SocketOption('/quartz-manager/progress', '/topic/progress', apiService.getToken)) + super(new SocketOption(getBaseUrl() + '/quartz-manager/progress', '/topic/progress', apiService.getToken)) } } \ No newline at end of file diff --git a/quartz-manager-frontend/src/app/services/scheduler.service.ts b/quartz-manager-frontend/src/app/services/scheduler.service.ts index f2b351b..a4b4251 100644 --- a/quartz-manager-frontend/src/app/services/scheduler.service.ts +++ b/quartz-manager-frontend/src/app/services/scheduler.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { getBaseUrl } from '.'; import { ApiService } from './api.service'; @Injectable() @@ -9,30 +10,30 @@ export class SchedulerService { ) { } startScheduler = () => { - return this.apiService.get('/quartz-manager/scheduler/run') + return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/run') } stopScheduler = () => { - return this.apiService.get('/quartz-manager/scheduler/stop') + return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/stop') } pauseScheduler = () => { - return this.apiService.get('/quartz-manager/scheduler/pause') + return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/pause') } resumeScheduler = () => { - return this.apiService.get('/quartz-manager/scheduler/resume') + return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/resume') } getStatus = () => { - return this.apiService.get('/quartz-manager/scheduler') + return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler') } getConfig = () => { - return this.apiService.get('/quartz-manager/scheduler/config') + return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/config') } updateConfig = (config: Object) => { - return this.apiService.post('/quartz-manager/scheduler/config', config) + return this.apiService.post(getBaseUrl() + '/quartz-manager/scheduler/config', config) } } diff --git a/quartz-manager-frontend/src/index.html b/quartz-manager-frontend/src/index.html index 8b9f67a..bd33166 100644 --- a/quartz-manager-frontend/src/index.html +++ b/quartz-manager-frontend/src/index.html @@ -3,7 +3,6 @@ Quartz Manager - diff --git a/quartz-manager-parent/pom.xml b/quartz-manager-parent/pom.xml index 7f55372..7be66d9 100644 --- a/quartz-manager-parent/pom.xml +++ b/quartz-manager-parent/pom.xml @@ -18,7 +18,7 @@ quartz-manager-api quartz-manager-web - quartz-manager-fe-builder + quartz-manager-ui-webjar diff --git a/quartz-manager-parent/quartz-manager-fe-builder/pom.xml b/quartz-manager-parent/quartz-manager-ui-webjar/pom.xml similarity index 94% rename from quartz-manager-parent/quartz-manager-fe-builder/pom.xml rename to quartz-manager-parent/quartz-manager-ui-webjar/pom.xml index 6591064..fb3f625 100644 --- a/quartz-manager-parent/quartz-manager-fe-builder/pom.xml +++ b/quartz-manager-parent/quartz-manager-ui-webjar/pom.xml @@ -7,10 +7,10 @@ 2.2.2-SNAPSHOT - quartz-manager-fe-builder + quartz-manager-ui-webjar - Quartz Manager FE Builder - Builder for frontend + Quartz Manager UI webjar + webjar builder for quartz-manager frontend https://github.com/fabioformosa/quartz-manager From ef4ffca2bd82c6dab6767b2d1681023cb905177f Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Sat, 30 Jan 2021 15:42:37 +0100 Subject: [PATCH 04/11] #22 Adapted frontend to be wrapped into a webjar --- quartz-manager-parent/quartz-manager-web/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/quartz-manager-parent/quartz-manager-web/pom.xml b/quartz-manager-parent/quartz-manager-web/pom.xml index d651cd5..1650716 100644 --- a/quartz-manager-parent/quartz-manager-web/pom.xml +++ b/quartz-manager-parent/quartz-manager-web/pom.xml @@ -28,6 +28,12 @@ it.fabioformosa.quartz-manager quartz-manager-api + + + + + + From e23343d7ed0a196d501fb8810973c3d89140be4c Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Sat, 30 Jan 2021 17:16:07 +0100 Subject: [PATCH 05/11] #30 renamed module quartz-manager-web-showcase --- quartz-manager-parent/pom.xml | 2 +- .../.gitignore | 0 .../pom.xml | 15 +++++++-------- .../it/fabioformosa/QuartManagerApplication.java | 0 .../java/it/fabioformosa/ServletInitializer.java | 0 .../configuration/WebSecurityConfigJWT.java | 0 .../properties/InMemoryAccountProperties.java | 0 .../properties/JwtSecurityProperties.java | 0 .../controllers/AuthenticationController.java | 0 .../controllers/QuartzManagerController.java | 0 .../controllers/SessionController.java | 0 .../controllers/UserController.java | 0 .../quartzmanager/jobs/myjobs/SampleJob.java | 0 .../quartzmanager/jobs/tests/MisfireTestJob.java | 0 .../security/helpers/LoginConfigurer.java | 0 .../helpers/impl/AjaxAuthenticationFilter.java | 0 .../helpers/impl/AnonAuthentication.java | 0 .../impl/AuthenticationFailureHandler.java | 0 .../impl/AuthenticationSuccessHandler.java | 0 .../security/helpers/impl/ComboEntryPoint.java | 0 .../security/helpers/impl/FormLoginConfig.java | 0 .../helpers/impl/JwtAuthenticationFilter.java | 0 .../impl/JwtAuthenticationSuccessHandler.java | 0 .../JwtAuthenticationSuccessHandlerImpl.java | 0 .../impl/JwtTokenAuthenticationFilter.java | 0 .../impl/JwtTokenBasedAuthentication.java | 0 .../security/helpers/impl/JwtTokenHelper.java | 0 .../JwtUsernamePasswordFiterLoginConfig.java | 0 .../security/helpers/impl/LogoutSuccess.java | 0 .../helpers/impl/QuartzManagerHttpSecurity.java | 0 .../helpers/impl/RESTRequestMatcher.java | 0 .../impl/RestAuthenticationEntryPoint.java | 0 .../helpers/impl/WebsocketRequestMatcher.java | 0 .../quartzmanager/security/model/Authority.java | 0 .../quartzmanager/security/model/User.java | 0 .../security/model/UserRequest.java | 0 .../security/model/UserTokenState.java | 0 .../security/repository/AuthorityRepository.java | 0 .../security/repository/UserRepository.java | 0 .../security/service/AuthorityService.java | 0 .../security/service/UserService.java | 0 .../service/impl/AuthorityServiceImpl.java | 0 .../service/impl/CustomUserDetailsService.java | 0 .../security/service/impl/UserServiceImpl.java | 0 .../src/main/resources/_disabled_import.sql_off | 0 .../src/main/resources/application.yml | 0 .../src/main/resources/banner.txt | 0 .../src/main/resources/logback.xml | 0 .../quartz-manager-2-screenshot_800.PNG | Bin .../src/main/resources/quartz.properties | 0 .../QuartManagerApplicationTests.java | 0 51 files changed, 8 insertions(+), 9 deletions(-) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/.gitignore (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/pom.xml (90%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/QuartManagerApplication.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/ServletInitializer.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/InMemoryAccountProperties.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/JwtSecurityProperties.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/controllers/QuartzManagerController.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/controllers/SessionController.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/jobs/myjobs/SampleJob.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/jobs/tests/MisfireTestJob.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/model/UserRequest.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/repository/AuthorityRepository.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/service/AuthorityService.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/resources/_disabled_import.sql_off (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/resources/application.yml (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/resources/banner.txt (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/resources/logback.xml (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/resources/quartz-manager-2-screenshot_800.PNG (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/main/resources/quartz.properties (100%) rename quartz-manager-parent/{quartz-manager-web => quartz-manager-web-showcase}/src/test/java/it/fabioformosa/QuartManagerApplicationTests.java (100%) diff --git a/quartz-manager-parent/pom.xml b/quartz-manager-parent/pom.xml index 7be66d9..8fe58c4 100644 --- a/quartz-manager-parent/pom.xml +++ b/quartz-manager-parent/pom.xml @@ -17,8 +17,8 @@ quartz-manager-api - quartz-manager-web quartz-manager-ui-webjar + quartz-manager-web-showcase diff --git a/quartz-manager-parent/quartz-manager-web/.gitignore b/quartz-manager-parent/quartz-manager-web-showcase/.gitignore similarity index 100% rename from quartz-manager-parent/quartz-manager-web/.gitignore rename to quartz-manager-parent/quartz-manager-web-showcase/.gitignore diff --git a/quartz-manager-parent/quartz-manager-web/pom.xml b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml similarity index 90% rename from quartz-manager-parent/quartz-manager-web/pom.xml rename to quartz-manager-parent/quartz-manager-web-showcase/pom.xml index 1650716..0a83c7e 100644 --- a/quartz-manager-parent/quartz-manager-web/pom.xml +++ b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml @@ -9,12 +9,12 @@ 2.2.2-SNAPSHOT - quartz-manager-web + quartz-manager-web-showcase war - Quartz Manager Web - A webapp that imports Quartz Manager API lib + Quartz Manager Web Showcase + A webapp that imports Quartz Manager API lib and the frontend webjar UTF-8 @@ -29,11 +29,10 @@ quartz-manager-api - - - - - + + it.fabioformosa.quartz-manager + quartz-manager-ui-webjar + diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/QuartManagerApplication.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/QuartManagerApplication.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/QuartManagerApplication.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/QuartManagerApplication.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/ServletInitializer.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/ServletInitializer.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/ServletInitializer.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/ServletInitializer.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/InMemoryAccountProperties.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/InMemoryAccountProperties.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/InMemoryAccountProperties.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/InMemoryAccountProperties.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/JwtSecurityProperties.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/JwtSecurityProperties.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/JwtSecurityProperties.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/JwtSecurityProperties.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/controllers/QuartzManagerController.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/QuartzManagerController.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/controllers/QuartzManagerController.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/QuartzManagerController.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/controllers/SessionController.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/SessionController.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/controllers/SessionController.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/SessionController.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/jobs/myjobs/SampleJob.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/jobs/myjobs/SampleJob.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/jobs/myjobs/SampleJob.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/jobs/myjobs/SampleJob.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/jobs/tests/MisfireTestJob.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/jobs/tests/MisfireTestJob.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/jobs/tests/MisfireTestJob.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/jobs/tests/MisfireTestJob.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/model/UserRequest.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserRequest.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/model/UserRequest.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserRequest.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/repository/AuthorityRepository.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/AuthorityRepository.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/repository/AuthorityRepository.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/AuthorityRepository.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/service/AuthorityService.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/AuthorityService.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/service/AuthorityService.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/AuthorityService.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java diff --git a/quartz-manager-parent/quartz-manager-web/src/main/resources/_disabled_import.sql_off b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/_disabled_import.sql_off similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/resources/_disabled_import.sql_off rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/_disabled_import.sql_off diff --git a/quartz-manager-parent/quartz-manager-web/src/main/resources/application.yml b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/application.yml similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/resources/application.yml rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/application.yml diff --git a/quartz-manager-parent/quartz-manager-web/src/main/resources/banner.txt b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/banner.txt similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/resources/banner.txt rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/banner.txt diff --git a/quartz-manager-parent/quartz-manager-web/src/main/resources/logback.xml b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/logback.xml similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/resources/logback.xml rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/logback.xml diff --git a/quartz-manager-parent/quartz-manager-web/src/main/resources/quartz-manager-2-screenshot_800.PNG b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz-manager-2-screenshot_800.PNG similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/resources/quartz-manager-2-screenshot_800.PNG rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz-manager-2-screenshot_800.PNG diff --git a/quartz-manager-parent/quartz-manager-web/src/main/resources/quartz.properties b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/main/resources/quartz.properties rename to quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties diff --git a/quartz-manager-parent/quartz-manager-web/src/test/java/it/fabioformosa/QuartManagerApplicationTests.java b/quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/QuartManagerApplicationTests.java similarity index 100% rename from quartz-manager-parent/quartz-manager-web/src/test/java/it/fabioformosa/QuartManagerApplicationTests.java rename to quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/QuartManagerApplicationTests.java From 6f50f45aa8847dae71fa30c002702f011015a283 Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Sun, 31 Jan 2021 20:50:41 +0100 Subject: [PATCH 06/11] #30 added new module with all config for a security layer --- .../src/app/services/api.service.ts | 6 - quartz-manager-parent/pom.xml | 2 +- .../quartz-manager-security/pom.xml | 57 +++++ .../configuration/WebSecurityConfigJWT.java | 194 +++++++++++++++++ .../properties/InMemoryAccountProperties.java | 24 ++ .../properties/JwtSecurityProperties.java | 33 +++ .../security/helpers/LoginConfigurer.java | 21 ++ .../impl/AjaxAuthenticationFilter.java | 55 +++++ .../helpers/impl/AnonAuthentication.java | 45 ++++ .../impl/AuthenticationFailureHandler.java | 20 ++ .../impl/AuthenticationSuccessHandler.java | 35 +++ .../helpers/impl/ComboEntryPoint.java | 33 +++ .../helpers/impl/FormLoginConfig.java | 75 +++++++ .../helpers/impl/JwtAuthenticationFilter.java | 34 +++ .../impl/JwtAuthenticationSuccessHandler.java | 14 ++ .../JwtAuthenticationSuccessHandlerImpl.java | 78 +++++++ .../impl/JwtTokenAuthenticationFilter.java | 105 +++++++++ .../impl/JwtTokenBasedAuthentication.java | 42 ++++ .../security/helpers/impl/JwtTokenHelper.java | 163 ++++++++++++++ .../JwtUsernamePasswordFiterLoginConfig.java | 46 ++++ .../security/helpers/impl/LogoutSuccess.java | 36 +++ .../impl/QuartzManagerHttpSecurity.java | 57 +++++ .../helpers/impl/RESTRequestMatcher.java | 26 +++ .../impl/RestAuthenticationEntryPoint.java | 23 ++ .../helpers/impl/WebsocketRequestMatcher.java | 18 ++ .../security/models/Authority.java | 53 +++++ .../quartzmanager/security/models/User.java | 133 +++++++++++ .../security/models/UserRequest.java | 56 +++++ .../security/models/UserTokenState.java | 32 +++ .../repositories/AuthorityRepository.java | 13 ++ .../security/repositories/UserRepository.java | 11 + .../security/services/AuthorityService.java | 13 ++ .../security/services/UserService.java | 18 ++ .../services/impl/AuthorityServiceImpl.java | 33 +++ .../impl/CustomUserDetailsService.java | 67 ++++++ .../services/impl/UserServiceImpl.java | 79 +++++++ .../main/resources/META-INF/spring.factories | 4 + .../quartz-manager-ui-webjar/pom.xml | 206 +++++++++--------- .../quartz-manager-web-showcase/pom.xml | 8 +- 39 files changed, 1856 insertions(+), 112 deletions(-) create mode 100644 quartz-manager-parent/quartz-manager-security/pom.xml create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/WebSecurityConfigJWT.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/properties/InMemoryAccountProperties.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/properties/JwtSecurityProperties.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/Authority.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/User.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/UserRequest.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/UserTokenState.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/repositories/AuthorityRepository.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/repositories/UserRepository.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/AuthorityService.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/UserService.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/AuthorityServiceImpl.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/CustomUserDetailsService.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/UserServiceImpl.java create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/resources/META-INF/spring.factories diff --git a/quartz-manager-frontend/src/app/services/api.service.ts b/quartz-manager-frontend/src/app/services/api.service.ts index d89a780..c7fde7c 100644 --- a/quartz-manager-frontend/src/app/services/api.service.ts +++ b/quartz-manager-frontend/src/app/services/api.service.ts @@ -53,9 +53,6 @@ export class ApiService { if (args) options['params'] = serialize(args); - // if(this.jwtToken) - // options.headers = options.headers.set('Authorization', `Bearer ${this.jwtToken}`); - return this.http.get(path, options) .pipe(catchError(this.checkError.bind(this))); } @@ -78,9 +75,6 @@ export class ApiService { withCredentials: true } - // if(this.jwtToken) - // options.headers = options.headers.append('Authorization', `Bearer ${this.jwtToken}`); - const req = new HttpRequest(method, path, body, options); return this.http.request(req) diff --git a/quartz-manager-parent/pom.xml b/quartz-manager-parent/pom.xml index 8fe58c4..a6213f7 100644 --- a/quartz-manager-parent/pom.xml +++ b/quartz-manager-parent/pom.xml @@ -19,7 +19,7 @@ quartz-manager-api quartz-manager-ui-webjar quartz-manager-web-showcase - + quartz-manager-security diff --git a/quartz-manager-parent/quartz-manager-security/pom.xml b/quartz-manager-parent/quartz-manager-security/pom.xml new file mode 100644 index 0000000..d8945a3 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + + it.fabioformosa.quartz-manager + quartz-manager-parent + 2.2.2-SNAPSHOT + + + quartz-manager-security + + Quartz Manager Security + Security Layer for Quartz Manager + + https://github.com/fabioformosa/quartz-manager + + ${basedir}/../.. + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-configuration-processor + true + + + io.jsonwebtoken + jjwt + 0.9.0 + + + org.apache.commons + commons-lang3 + + + org.projectlombok + lombok + provided + + + javax.servlet + javax.servlet-api + provided + + + + \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/WebSecurityConfigJWT.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/WebSecurityConfigJWT.java new file mode 100644 index 0000000..c5bcb07 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/WebSecurityConfigJWT.java @@ -0,0 +1,194 @@ +package it.fabioformosa.quartzmanager.security.configuration; + +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.HttpStatusEntryPoint; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import it.fabioformosa.quartzmanager.security.configuration.properties.InMemoryAccountProperties; +import it.fabioformosa.quartzmanager.security.configuration.properties.JwtSecurityProperties; +import it.fabioformosa.quartzmanager.security.helpers.LoginConfigurer; +import it.fabioformosa.quartzmanager.security.helpers.impl.AuthenticationFailureHandler; +import it.fabioformosa.quartzmanager.security.helpers.impl.AuthenticationSuccessHandler; +import it.fabioformosa.quartzmanager.security.helpers.impl.FormLoginConfig; +import it.fabioformosa.quartzmanager.security.helpers.impl.JwtAuthenticationSuccessHandler; +import it.fabioformosa.quartzmanager.security.helpers.impl.JwtAuthenticationSuccessHandlerImpl; +import it.fabioformosa.quartzmanager.security.helpers.impl.JwtTokenAuthenticationFilter; +import it.fabioformosa.quartzmanager.security.helpers.impl.JwtTokenHelper; +import it.fabioformosa.quartzmanager.security.helpers.impl.JwtUsernamePasswordFiterLoginConfig; +import it.fabioformosa.quartzmanager.security.helpers.impl.LogoutSuccess; +import it.fabioformosa.quartzmanager.security.helpers.impl.QuartzManagerHttpSecurity; + +/** + * + * @author Fabio.Formosa + * + */ +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter { + + private static final String[] PATTERNS_SWAGGER_UI = {"/swagger-ui.html", "/v2/api-docs", "/swagger-resources/**", "/webjars/**"}; + + private static final String LOGIN_PATH = "/quartz-manager/api/login"; + private static final String LOGOUT_PATH = "/quartz-manager/api/logout"; + + private static final String WEBJAR_PATH = "/quartz-manager-ui"; + + @Value("${server.servlet.context-path:/}") + private String contextPath; + + @Value("${app.name:quartz-manager}") + private String APP_NAME; + + @Value("${quartz-manager.security.login-model.form-login-enabled}") + private Boolean formLoginEnabled; + @Value("${quartz-manager.security.login-model.userpwd-filter-enabled}") + private Boolean userpwdFilterEnabled; + + @Autowired + private JwtSecurityProperties jwtSecurityProps; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private UserDetailsService userDetailsService; + + @Autowired + private InMemoryAccountProperties inMemoryAccountProps; + + + @Override + public void configure(AuthenticationManagerBuilder authenticationManagerBuilder)throws Exception { + configureInMemoryAuthentication(authenticationManagerBuilder); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable() // + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() // + .exceptionHandling().authenticationEntryPoint(restAuthEntryPoint()).and() // + .addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class) // + .authorizeRequests().anyRequest().authenticated(); + + QuartzManagerHttpSecurity.from(http).withLoginConfigurer(loginConfigurer(), logoutConfigurer()) // + .login(LOGIN_PATH, authenticationManager()).logout(LOGOUT_PATH); + + // temporary disabled csfr + // http.csrf().ignoringAntMatchers("/api/login", "/api/signup") // + // .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // + } + + @Override + public void configure(WebSecurity web) throws Exception { + web.ignoring()// + .antMatchers(HttpMethod.GET, PATTERNS_SWAGGER_UI) // + .antMatchers(HttpMethod.GET, WEBJAR_PATH + "/css/**", WEBJAR_PATH + "/js/**", WEBJAR_PATH + "/img/**", WEBJAR_PATH + "/lib/**", WEBJAR_PATH + "/assets/**"); + } + + private void configureInMemoryAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { + PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); + if(inMemoryAccountProps.isEnabled() && inMemoryAccountProps.getUsers() != null && !inMemoryAccountProps.getUsers().isEmpty()) { + InMemoryUserDetailsManagerConfigurer inMemoryAuth = authenticationManagerBuilder.inMemoryAuthentication(); + inMemoryAccountProps.getUsers() + .forEach(u -> inMemoryAuth + .withUser(u.getName()) + .password(encoder.encode(u.getPassword())) + .roles(u.getRoles().toArray(new String[0]))); + } + } + + @Bean + CorsConfigurationSource corsConfigurationSource() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues()); + return source; + } + + @Bean + public LoginConfigurer formLoginConfigurer() { + JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler(); + AuthenticationSuccessHandler authenticationSuccessHandler = new AuthenticationSuccessHandler(jwtAuthenticationSuccessHandler); + AuthenticationFailureHandler authenticationFailureHandler = new AuthenticationFailureHandler(); + LoginConfigurer loginConfigurer = new FormLoginConfig(authenticationSuccessHandler, authenticationFailureHandler); + return loginConfigurer; + } + + @Bean + public JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler() { + JwtTokenHelper jwtTokenHelper = jwtTokenHelper(); + JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler = new JwtAuthenticationSuccessHandlerImpl(contextPath, jwtSecurityProps, jwtTokenHelper, objectMapper); + return jwtAuthenticationSuccessHandler; + } + + @Bean + public JwtTokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception { + return new JwtTokenAuthenticationFilter(jwtTokenHelper(), userDetailsService); + } + + @Bean + public JwtTokenHelper jwtTokenHelper() { + return new JwtTokenHelper(APP_NAME, jwtSecurityProps); + } + + @Bean + public LoginConfigurer loginConfigurer() { + if(BooleanUtils.isTrue(userpwdFilterEnabled)) + return userpwdFilterLoginConfigurer(); + if(BooleanUtils.isNotFalse(formLoginEnabled)) + return formLoginConfigurer(); + throw new RuntimeException("No login configurer enabled!"); + } + + @Bean + public LogoutSuccess logoutConfigurer() { + return new LogoutSuccess(objectMapper); + } + + @Bean + public AuthenticationEntryPoint restAuthEntryPoint() { + return new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED); + } + + @Bean + @Override + public UserDetailsService userDetailsServiceBean() throws Exception { + return super.userDetailsServiceBean(); + } + + @Bean + public LoginConfigurer userpwdFilterLoginConfigurer() { + LoginConfigurer loginConfigurer = new JwtUsernamePasswordFiterLoginConfig(jwtAuthenticationSuccessHandler()); + return loginConfigurer; + } + + // @Bean + // public PasswordEncoder passwordEncoder() { + // return new BCryptPasswordEncoder(); + // } + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/properties/InMemoryAccountProperties.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/properties/InMemoryAccountProperties.java new file mode 100644 index 0000000..279a079 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/properties/InMemoryAccountProperties.java @@ -0,0 +1,24 @@ +package it.fabioformosa.quartzmanager.security.configuration.properties; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.List; + +@Configuration +@ConfigurationProperties(prefix = "quartz-manager.accounts.in-memory") +@Getter @Setter +public class InMemoryAccountProperties { + private boolean enabled; + private List users; + + @Getter @Setter + public static class User { + private String name; + private String password; + private List roles = new ArrayList<>(); + } +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/properties/JwtSecurityProperties.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/properties/JwtSecurityProperties.java new file mode 100644 index 0000000..1afec00 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/configuration/properties/JwtSecurityProperties.java @@ -0,0 +1,33 @@ +package it.fabioformosa.quartzmanager.security.configuration.properties; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + + +@Configuration +@ConfigurationProperties(prefix = "quartz-manager.security.jwt") +@Getter @Setter +public class JwtSecurityProperties { + private boolean enabled; + private String secret; + private long expirationInSec; + + private CookieStrategy cookieStrategy; + private HeaderStrategy headerStrategy; + + @Data + public static class CookieStrategy { + private boolean enabled; + private String cookie; + } + + @Data + public static class HeaderStrategy { + private boolean enabled; + private String header; + } + +} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java new file mode 100644 index 0000000..4446087 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java @@ -0,0 +1,21 @@ +package it.fabioformosa.quartzmanager.security.helpers; + +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; + +/** + * It configures filters to authenticate credentials sent by client or to set authenticationSuccessHandler + * + * Implement this interface for a login strategy + * + */ +public interface LoginConfigurer { + + /** + * If the authentication is based on cookie, it returns the name of cookie to be erased at the logout + */ + String cookieMustBeDeletedAtLogout(); + + HttpSecurity login(String loginPath, HttpSecurity http, AuthenticationManager authenticationManager) throws Exception; + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java new file mode 100644 index 0000000..0c4e0b3 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java @@ -0,0 +1,55 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.WebAttributes; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +public class AjaxAuthenticationFilter extends UsernamePasswordAuthenticationFilter { + + public class AjaxLoginAuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler + implements AuthenticationSuccessHandler { + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws IOException, ServletException { + response.setStatus(HttpServletResponse.SC_OK); + clearAuthenticationAttributes(request); + return; + } + + } + + public AjaxAuthenticationFilter(AuthenticationManager authenticationManager) { + setAuthenticationManager(authenticationManager); + setUsernameParameter("ajaxUsername"); + setPasswordParameter("ajaxPassword"); + setPostOnly(true); + setFilterProcessesUrl("/ajaxLogin"); + + setAuthenticationSuccessHandler(new AjaxLoginAuthSuccessHandler()); + } + + /** + * Removes temporary authentication-related data which may have been stored + * in the session during the authentication process. + */ + protected final void clearAuthenticationAttributes(HttpServletRequest request) { + HttpSession session = request.getSession(false); + + if (session == null) + return; + + session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION); + } + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java new file mode 100644 index 0000000..f1c266f --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java @@ -0,0 +1,45 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import org.springframework.security.authentication.AbstractAuthenticationToken; + +public class AnonAuthentication extends AbstractAuthenticationToken { + private static final long serialVersionUID = 1L; + + public AnonAuthentication() { + super( null ); + } + + @Override + public boolean equals( Object obj ) { + if ( this == obj ) + return true; + if ( obj == null ) + return false; + if ( getClass() != obj.getClass() ) + return false; + return true; + } + + @Override + public Object getCredentials() { + return null; + } + + @Override + public Object getPrincipal() { + return null; + } + + @Override + public int hashCode() { + int hash = 7; + return hash; + } + + @Override + public boolean isAuthenticated() { + return true; + } + + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java new file mode 100644 index 0000000..08bb8b4 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java @@ -0,0 +1,20 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; + +public class AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { + + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException exception) throws IOException, ServletException { + + super.onAuthenticationFailure(request, response, exception); + } +} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java new file mode 100644 index 0000000..6634870 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java @@ -0,0 +1,35 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; + +//@Component +//@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "form-login-enabled", havingValue = "true", matchIfMissing = true) +public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { + + private final JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler; + + // @Autowired + public AuthenticationSuccessHandler(JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler) { + super(); + this.jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler; + } + + public String cookieMustBeDeletedAtLogout() { + return jwtAuthenticationSuccessHandler.cookieMustBeDeletedAtLogout(); + } + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication ) throws IOException, ServletException { + clearAuthenticationAttributes(request); + jwtAuthenticationSuccessHandler.onLoginSuccess(authentication, response); + } + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java new file mode 100644 index 0000000..7ab933d --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java @@ -0,0 +1,33 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +@Component +public class ComboEntryPoint extends LoginUrlAuthenticationEntryPoint { + + private static final String LOGIN_FORM_URL = "/login"; + + public ComboEntryPoint() { + super(LOGIN_FORM_URL); + } + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException, ServletException { + + if (RESTRequestMatcher.isRestRequest(request) + || WebsocketRequestMatcher.isWebsocketConnectionRequest(request)) + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + else + super.commence(request, response, authException); + } + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java new file mode 100644 index 0000000..206f969 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java @@ -0,0 +1,75 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer; + +import it.fabioformosa.quartzmanager.security.helpers.LoginConfigurer; + +/** + * It delegates form to @FormLoginConfigurer of the httpSecurity. + * + */ +public class FormLoginConfig implements LoginConfigurer { + + private static final Logger log = LoggerFactory.getLogger(FormLoginConfig.class); + + private final AuthenticationSuccessHandler authenticationSuccessHandler; + + private final AuthenticationFailureHandler authenticationFailureHandler; + + + public FormLoginConfig() { + super(); + authenticationSuccessHandler = null; + authenticationFailureHandler = null; + } + + public FormLoginConfig(AuthenticationFailureHandler authenticationFailureHandler) { + super(); + authenticationSuccessHandler = null; + this.authenticationFailureHandler = authenticationFailureHandler; + } + + public FormLoginConfig(AuthenticationSuccessHandler authenticationSuccessHandler) { + super(); + this.authenticationSuccessHandler = authenticationSuccessHandler; + authenticationFailureHandler = null; + } + + public FormLoginConfig(AuthenticationSuccessHandler authenticationSuccessHandler, + AuthenticationFailureHandler authenticationFailureHandler) { + super(); + this.authenticationSuccessHandler = authenticationSuccessHandler; + this.authenticationFailureHandler = authenticationFailureHandler; + } + + @Override + public String cookieMustBeDeletedAtLogout() { + return authenticationSuccessHandler.cookieMustBeDeletedAtLogout(); + } + + @Override + public HttpSecurity login(String loginPath, + HttpSecurity http, AuthenticationManager authenticationManager) throws Exception { + log.debug("Configuring login through FormLoginConfigurer..."); + + FormLoginConfigurer login = http.formLogin().loginPage(loginPath); + + if(authenticationSuccessHandler != null) { + log.debug("Setting an authenticationSuccessHandler"); + login = login.successHandler(authenticationSuccessHandler); + } + + if(authenticationFailureHandler != null) { + log.debug("Setting an authenticationFailureHandler"); + login = login.failureHandler(authenticationFailureHandler); + } + + HttpSecurity httpSecurity = login.and(); + return httpSecurity; + } + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java new file mode 100644 index 0000000..c15c0ac --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java @@ -0,0 +1,34 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import javax.servlet.FilterChain; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import lombok.SneakyThrows; + +/** + * It extends the @UsernamePasswordAuthenticationFilter and it overrides the successfulAuthentication method to put jwtToken in the response + * + */ +public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { + + private JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler; + + public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler) { + this.jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler; + setAuthenticationManager(authenticationManager); + } + + @SneakyThrows + @Override + protected void successfulAuthentication(HttpServletRequest req, + HttpServletResponse res, + FilterChain chain, + Authentication auth) { + jwtAuthenticationSuccessHandler.onLoginSuccess(auth, res); + } +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java new file mode 100644 index 0000000..6a956c9 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java @@ -0,0 +1,14 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import java.io.IOException; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.Authentication; + +public interface JwtAuthenticationSuccessHandler { + + String cookieMustBeDeletedAtLogout(); + + void onLoginSuccess(Authentication authentication, HttpServletResponse response) throws IOException; +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java new file mode 100644 index 0000000..ca5de80 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java @@ -0,0 +1,78 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import java.io.IOException; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.User; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import it.fabioformosa.quartzmanager.security.configuration.properties.JwtSecurityProperties; +import it.fabioformosa.quartzmanager.security.models.UserTokenState; + +/** + * It depends on @JwtTokenHelper to generate the jwtToken. + * On login success, it generates the jwtToken and it returns it to the login according to possible strategies: cookie, response header. + * You can choice the strategy through @JwtSecurityProperties + * + */ +public class JwtAuthenticationSuccessHandlerImpl implements JwtAuthenticationSuccessHandler { + + private static final Logger log = LoggerFactory.getLogger(JwtAuthenticationSuccessHandlerImpl.class); + + private final JwtSecurityProperties jwtSecurityProps; + + private final JwtTokenHelper jwtTokenHelper; + + private final ObjectMapper objectMapper; + + private final String contextPath; + + @Autowired + public JwtAuthenticationSuccessHandlerImpl(String contextPath, JwtSecurityProperties jwtSecurityProps, JwtTokenHelper jwtTokenHelper, ObjectMapper objectMapper) { + this.contextPath = contextPath; + this.jwtSecurityProps = jwtSecurityProps; + this.jwtTokenHelper = jwtTokenHelper; + this.objectMapper = objectMapper; + } + + @Override + public String cookieMustBeDeletedAtLogout() { + if(!jwtSecurityProps.getCookieStrategy().isEnabled()) + return null; + return jwtSecurityProps.getCookieStrategy().getCookie(); + } + + @Override + public void onLoginSuccess(Authentication authentication, HttpServletResponse response) throws IOException { + log.debug("Login successed, generating jwtToken..."); + + User user = (User) authentication.getPrincipal(); + String jwtToken = jwtTokenHelper.generateToken(user.getUsername()); + + if(jwtSecurityProps.getCookieStrategy().isEnabled()) { + Cookie authCookie = new Cookie(jwtSecurityProps.getCookieStrategy().getCookie(), jwtToken); + authCookie.setHttpOnly(true); + authCookie.setMaxAge((int) jwtSecurityProps.getExpirationInSec()); + authCookie.setPath(contextPath); + response.addCookie(authCookie); + log.debug("Set jwtToken into the cookie {}", jwtSecurityProps.getCookieStrategy().getCookie()); + } + + if(jwtSecurityProps.getHeaderStrategy().isEnabled()) { + jwtTokenHelper.setHeader(response, jwtToken); + log.debug("Set jwtToken into the response header {}", jwtSecurityProps.getHeaderStrategy().getHeader()); + } + + UserTokenState userTokenState = new UserTokenState(jwtToken, jwtSecurityProps.getExpirationInSec()); + String jwtResponse = objectMapper.writeValueAsString(userTokenState); + response.setContentType("application/json"); + response.getWriter().write(jwtResponse); + } +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java new file mode 100644 index 0000000..346bb2f --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java @@ -0,0 +1,105 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.OrRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.web.filter.OncePerRequestFilter; + + +/** + * It finds the jwtToken into the request, it validates it and sets an @Authentication into the @SecurityContextHolder. + * If the request has a path included into the paths that must be skipped, it sets an anonymous authentication + * + * It delegates the jwtToken retrieve to the @JwtTokenHelper that applies several strategies. + * + */ +public class JwtTokenAuthenticationFilter extends OncePerRequestFilter { + + private static final Logger log = LoggerFactory.getLogger(JwtTokenAuthenticationFilter.class); + + private static final String ROOT_MATCHER = "/"; + private static final String FAVICON_MATCHER = "/favicon.ico"; + private static final String HTML_MATCHER = "/**/*.html"; + private static final String CSS_MATCHER = "/**/*.css"; + private static final String JS_MATCHER = "/**/*.js"; + private static final String IMG_MATCHER = "/images/*"; + private static final String LOGIN_MATCHER = "/api/login"; + private static final String LOGOUT_MATCHER = "/api/logout"; + + private static List PATH_TO_SKIP = Arrays.asList( + ROOT_MATCHER, + HTML_MATCHER, + FAVICON_MATCHER, + CSS_MATCHER, + JS_MATCHER, + IMG_MATCHER, + LOGIN_MATCHER, + LOGOUT_MATCHER + ); + + private final JwtTokenHelper jwtTokenHelper; + private final UserDetailsService userDetailsService; + + + public JwtTokenAuthenticationFilter(JwtTokenHelper jwtTokenHelper, UserDetailsService userDetailsService) { + super(); + this.jwtTokenHelper = jwtTokenHelper; + this.userDetailsService = userDetailsService; + } + + @Override + public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + + String jwtToken = jwtTokenHelper.retrieveToken(request); + if (jwtToken != null) { + log.debug("Found a jwtToken into the request {}", request.getPathInfo()); + try { + String username = jwtTokenHelper.getUsernameFromToken(jwtToken); + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + + JwtTokenBasedAuthentication authentication = new JwtTokenBasedAuthentication(userDetails); + authentication.setToken(jwtToken); + + SecurityContextHolder.getContext().setAuthentication(authentication); + } catch (Exception e) { + log.error("Authentication failed! an expected error occurred authenticating the request {}", request.getRequestURL()); + // SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication()); + // log.error("Switched to Anonymous Authentication, " + // + "because an error occurred setting authentication in security context holder due to " + e.getMessage(), e); + } + } + else if(skipPathRequest(request, PATH_TO_SKIP)) { + log.debug("Detected a path to be skipped from authentication, so activated anonymous auth for {}", request.getRequestURL()); + SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication()); + } + else + log.debug("Not found any jwtToken and the request hasn't a path to be skipped from auth. Path: {}", request.getRequestURL()); + + chain.doFilter(request, response); + } + + private boolean skipPathRequest(HttpServletRequest request, List pathsToSkip ) { + if(pathsToSkip == null) + pathsToSkip = new ArrayList(); + List matchers = pathsToSkip.stream().map(path -> new AntPathRequestMatcher(path)).collect(Collectors.toList()); + OrRequestMatcher compositeMatchers = new OrRequestMatcher(matchers); + return compositeMatchers.matches(request); + } + +} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java new file mode 100644 index 0000000..904ed07 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java @@ -0,0 +1,42 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.userdetails.UserDetails; + + +public class JwtTokenBasedAuthentication extends AbstractAuthenticationToken { + + private static final long serialVersionUID = 1L; + + private String token; + private final UserDetails principle; + + public JwtTokenBasedAuthentication(UserDetails principle) { + super(principle.getAuthorities()); + this.principle = principle; + } + + @Override + public Object getCredentials() { + return token; + } + + @Override + public UserDetails getPrincipal() { + return principle; + } + + public String getToken() { + return token; + } + + @Override + public boolean isAuthenticated() { + return true; + } + + public void setToken( String token ) { + this.token = token; + } + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java new file mode 100644 index 0000000..679eb57 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java @@ -0,0 +1,163 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Base64; +import java.util.Date; +import java.util.Map; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import it.fabioformosa.quartzmanager.security.configuration.properties.JwtSecurityProperties; + +/** + * + * @author Fabio.Formosa + * + */ + +public class JwtTokenHelper { + + private static final Logger log = LoggerFactory.getLogger(JwtTokenHelper.class); + + private static String base64EncodeSecretKey(String secretKey) { + return Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8)); + } + + // @Value("${app.name}") + private final String appName; + + // @Autowired + private final JwtSecurityProperties jwtSecurityProps; + + private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512; + + // @Autowired + public JwtTokenHelper(String appName, JwtSecurityProperties jwtSecurityProps) { + super(); + this.appName = appName; + this.jwtSecurityProps = jwtSecurityProps; + } + + public Boolean canTokenBeRefreshed(String token) { + try { + final Date expirationDate = getClaimsFromToken(token).getExpiration(); + // String username = getUsernameFromToken(token); + // UserDetails userDetails = userDetailsService.loadUserByUsername(username); + return expirationDate.compareTo(generateCurrentDate()) > 0; + } catch (Exception e) { + return false; + } + } + + private Date generateCurrentDate() { + return new Date(getCurrentTimeMillis()); + } + + private Date generateExpirationDate() { + return new Date(getCurrentTimeMillis() + jwtSecurityProps.getExpirationInSec() * 1000); + } + + private String generateToken(Map claims) { + return Jwts.builder().setClaims(claims).setExpiration(generateExpirationDate()) + .signWith(SIGNATURE_ALGORITHM, base64EncodeSecretKey(jwtSecurityProps.getSecret())).compact(); + } + + public String generateToken(String username) { + return Jwts.builder().setIssuer(appName).setSubject(username).setIssuedAt(generateCurrentDate()) + .setExpiration(generateExpirationDate()) + .signWith(SIGNATURE_ALGORITHM, base64EncodeSecretKey(jwtSecurityProps.getSecret())).compact(); + } + + private Claims getClaimsFromToken(String token) { + Claims claims; + try { + claims = Jwts.parser().setSigningKey(base64EncodeSecretKey(jwtSecurityProps.getSecret())) + .parseClaimsJws(token).getBody(); + } catch (Exception e) { + claims = null; + log.error("Error getting claims from jwt token due to " + e.getMessage(), e); + } + return claims; + } + + /** + * Find a specific HTTP cookie in a request. + * + * @param request + * The HTTP request object. + * @param name + * The cookie name to look for. + * @return The cookie, or null if not found. + */ + public Cookie getCookieValueByName(HttpServletRequest request, String name) { + if (request.getCookies() == null) + return null; + for (int i = 0; i < request.getCookies().length; i++) + if (request.getCookies()[i].getName().equals(name)) + return request.getCookies()[i]; + return null; + } + + private long getCurrentTimeMillis() { + return LocalDateTime.now().atZone(ZoneId.of("Europe/Rome")).toInstant().toEpochMilli(); + } + + public String getUsernameFromToken(String token) { + String username; + try { + final Claims claims = getClaimsFromToken(token); + username = claims.getSubject(); + } catch (Exception e) { + username = null; + log.error("Error getting claims from jwt token due to " + e.getMessage(), e); + throw e; + } + return username; + } + + public String refreshToken(String token) { + String refreshedToken; + try { + final Claims claims = getClaimsFromToken(token); + claims.setIssuedAt(generateCurrentDate()); + refreshedToken = generateToken(claims); + } catch (Exception e) { + log.error("Error refreshing jwt token due to " + e.getMessage(), e); + refreshedToken = null; + } + return refreshedToken; + } + + public String retrieveToken(HttpServletRequest request) { + if (jwtSecurityProps.getCookieStrategy().isEnabled() == true) { + Cookie authCookie = getCookieValueByName(request, jwtSecurityProps.getCookieStrategy().getCookie()); + if (authCookie != null) + return authCookie.getValue(); + } + + if (jwtSecurityProps.getHeaderStrategy().isEnabled()) { + String authHeader = request.getHeader(jwtSecurityProps.getHeaderStrategy().getHeader()); + if (authHeader != null && authHeader.startsWith("Bearer ")) + return authHeader.substring(7); + } + + if(request.getParameter("access_token") != null) + return request.getParameter("access_token"); + + return null; + } + + public void setHeader(HttpServletResponse response, String token) { + response.addHeader(jwtSecurityProps.getHeaderStrategy().getHeader(), "Bearer " + token); + } +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java new file mode 100644 index 0000000..6f6991c --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java @@ -0,0 +1,46 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter; +import org.springframework.security.web.util.matcher.RegexRequestMatcher; +import org.springframework.web.filter.GenericFilterBean; + +import it.fabioformosa.quartzmanager.security.helpers.LoginConfigurer; + +/** + * It adds a new filter @JwtAuthenticationFilter after @AbstractPreAuthenticatedProcessingFilter that match login path + * + */ +public class JwtUsernamePasswordFiterLoginConfig implements LoginConfigurer { + + private static final Logger log = LoggerFactory.getLogger(JwtUsernamePasswordFiterLoginConfig.class); + + private final JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler; + + public JwtUsernamePasswordFiterLoginConfig(JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler) { + super(); + this.jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler; + } + + public GenericFilterBean authenticationProcessingFilter(String loginPath, AuthenticationManager authenticationManager) throws Exception { + JwtAuthenticationFilter authenticationProcessingFilter = new JwtAuthenticationFilter(authenticationManager, jwtAuthenticationSuccessHandler); + authenticationProcessingFilter.setRequiresAuthenticationRequestMatcher(new RegexRequestMatcher(loginPath, HttpMethod.POST.name(), false)); + return authenticationProcessingFilter; + } + + @Override + public String cookieMustBeDeletedAtLogout() { + return jwtAuthenticationSuccessHandler.cookieMustBeDeletedAtLogout(); + } + + @Override + public HttpSecurity login(String loginPath, HttpSecurity http, AuthenticationManager authenticationManager) throws Exception { + log.debug("Configuring login through JwtAuthenticationFilter..."); + return http.addFilterAfter(authenticationProcessingFilter(loginPath, authenticationManager), AbstractPreAuthenticatedProcessingFilter.class); + } + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java new file mode 100644 index 0000000..5f0eaa0 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java @@ -0,0 +1,36 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class LogoutSuccess implements LogoutSuccessHandler { + + private final ObjectMapper objectMapper; + + public LogoutSuccess(ObjectMapper objectMapper) { + super(); + this.objectMapper = objectMapper; + } + + @Override + public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse response, Authentication authentication) + throws IOException, ServletException { + Map result = new HashMap<>(); + result.put( "result", "success" ); + response.setContentType("application/json"); + response.getWriter().write(objectMapper.writeValueAsString(result)); + response.setStatus(HttpServletResponse.SC_OK); + + } + +} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java new file mode 100644 index 0000000..55b9edb --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java @@ -0,0 +1,57 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.SecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.LogoutConfigurer; +import org.springframework.security.web.DefaultSecurityFilterChain; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import it.fabioformosa.quartzmanager.security.helpers.LoginConfigurer; + +/** + * It wraps the httpSecurity to provide new function as login and logout + * + */ +public class QuartzManagerHttpSecurity extends SecurityConfigurerAdapter { + + public static QuartzManagerHttpSecurity from(HttpSecurity httpSecurity){ + QuartzManagerHttpSecurity newInstance = new QuartzManagerHttpSecurity(httpSecurity); + newInstance.setBuilder(httpSecurity); + return newInstance; + } + + private HttpSecurity httpSecurity; + + private LoginConfigurer loginConfigurer; + + private LogoutSuccess logoutSuccess; + + public QuartzManagerHttpSecurity(HttpSecurity httpSecurity) { + this.httpSecurity = httpSecurity; + // applicationContext = httpSecurity.getSharedObject(ApplicationContext.class); + } + + public QuartzManagerHttpSecurity login(String loginPath, AuthenticationManager authenticationManager) throws Exception { + if(loginConfigurer == null || logoutSuccess == null) + throw new IllegalStateException("QuartzManagerHttpSecurity requires to be set loginConfigurer and logoutSuccess!"); + httpSecurity = loginConfigurer.login(loginPath, httpSecurity, authenticationManager); + return this; + } + + + public LogoutConfigurer logout(String logoutPath) throws Exception { + LogoutConfigurer logoutConfigurer = httpSecurity.logout().logoutRequestMatcher(new AntPathRequestMatcher(logoutPath)) + .logoutSuccessHandler(logoutSuccess); + String cookie = loginConfigurer.cookieMustBeDeletedAtLogout(); + if(cookie != null) + logoutConfigurer.deleteCookies(cookie); + return logoutConfigurer; + } + + public QuartzManagerHttpSecurity withLoginConfigurer(LoginConfigurer loginConfigurer, LogoutSuccess logoutSuccess) { + this.loginConfigurer = loginConfigurer; + this.logoutSuccess = logoutSuccess; + return this; + } +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java new file mode 100644 index 0000000..1fb2d2b --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java @@ -0,0 +1,26 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.web.util.matcher.ELRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; + +public class RESTRequestMatcher { + + static private final Logger log = LoggerFactory.getLogger(RESTRequestMatcher.class); + + static public RequestMatcher matcherRequestedWith = new ELRequestMatcher( + "hasHeader('X-Requested-With','XMLHttpRequest')"); + static public RequestMatcher matcherAccept = new ELRequestMatcher( + "hasHeader('accept','application/json, text/plain, */*')"); + + static public boolean isRestRequest(HttpServletRequest request) { + log.trace("Detecting if it's an AJAX Request: " + request.getRequestURL() + " accept: " + + request.getHeader("accept") + " " + " X-Requested-With: " + + request.getHeader("X-Requested-With")); + return matcherRequestedWith.matches(request) || matcherAccept.matches(request); + } + +} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java new file mode 100644 index 0000000..3615a2e --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java @@ -0,0 +1,23 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +@Component +public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, + HttpServletResponse response, + AuthenticationException authException) throws IOException { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); + } +} + diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java new file mode 100644 index 0000000..5b42424 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java @@ -0,0 +1,18 @@ +package it.fabioformosa.quartzmanager.security.helpers.impl; + +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WebsocketRequestMatcher { + + static private final Logger log = LoggerFactory.getLogger(WebsocketRequestMatcher.class); + + static public boolean isWebsocketConnectionRequest(HttpServletRequest request) { + log.trace("Detecting if it's a Websocket Connection Request: " + request.getRequestURL()); + return request.getServletPath().equals("/progress/info") + || request.getServletPath().equals("/logs/info"); + } + +} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/Authority.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/Authority.java new file mode 100644 index 0000000..32a6284 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/Authority.java @@ -0,0 +1,53 @@ +package it.fabioformosa.quartzmanager.security.models; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +import org.springframework.security.core.GrantedAuthority; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * Temporary enabled only inMemoryAuthentication + * + * @author Fabio.Formosa + * + */ +//@Entity +//@Table(name="Authority") +public class Authority implements GrantedAuthority { + + @Id + @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; + + @Column(name="name") + String name; + + @Override + public String getAuthority() { + return name; + } + + @JsonIgnore + public Long getId() { + return id; + } + + @JsonIgnore + public String getName() { + return name; + } + + public void setId(Long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/User.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/User.java new file mode 100644 index 0000000..ba0d58a --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/User.java @@ -0,0 +1,133 @@ +package it.fabioformosa.quartzmanager.security.models; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * Temporary enabled only inMemoryAuthentication + * + * @author Fabio.Formosa + * + */ +//@Entity +//@Table(name = "USER") +public class User implements UserDetails, Serializable { + @Id + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "username") + private String username; + + @JsonIgnore + @Column(name = "password") + private String password; + + @Column(name = "firstname") + private String firstname; + + @Column(name = "lastname") + private String lastname; + + + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinTable(name = "user_authority", + joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), + inverseJoinColumns = @JoinColumn(name = "authority_id", referencedColumnName = "id")) + private List authorities; + + @Override + public Collection getAuthorities() { + return authorities; + } + + public String getFirstname() { + return firstname; + } + + public Long getId() { + return id; + } + + public String getLastname() { + return lastname; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getUsername() { + return username; + } + + // We can add the below fields in the users table. + // For now, they are hardcoded. + @JsonIgnore + @Override + public boolean isAccountNonExpired() { + return true; + } + + @JsonIgnore + @Override + public boolean isAccountNonLocked() { + return true; + } + + @JsonIgnore + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @JsonIgnore + @Override + public boolean isEnabled() { + return true; + } + + public void setAuthorities(List authorities) { + this.authorities = authorities; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public void setId(Long id) { + this.id = id; + } + + public void setLastname(String lastname) { + + this.lastname = lastname; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setUsername(String username) { + this.username = username; + } +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/UserRequest.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/UserRequest.java new file mode 100644 index 0000000..469df73 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/UserRequest.java @@ -0,0 +1,56 @@ +package it.fabioformosa.quartzmanager.security.models; + + +public class UserRequest { + + private Long id; + + private String username; + + private String password; + + private String firstname; + + private String lastname; + + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/UserTokenState.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/UserTokenState.java new file mode 100644 index 0000000..e39cd6b --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/models/UserTokenState.java @@ -0,0 +1,32 @@ +package it.fabioformosa.quartzmanager.security.models; + +public class UserTokenState { + private String access_token; + private Long expires_in_sec; + + public UserTokenState() { + this.access_token = null; + this.expires_in_sec = null; + } + + public UserTokenState(String access_token, long expires_in_sec) { + this.access_token = access_token; + this.expires_in_sec = expires_in_sec; + } + + public String getAccess_token() { + return access_token; + } + + public Long getExpires_in_sec() { + return expires_in_sec; + } + + public void setAccess_token(String access_token) { + this.access_token = access_token; + } + + public void setExpires_in_sec(Long expires_in_sec) { + this.expires_in_sec = expires_in_sec; + } +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/repositories/AuthorityRepository.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/repositories/AuthorityRepository.java new file mode 100644 index 0000000..5d736c1 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/repositories/AuthorityRepository.java @@ -0,0 +1,13 @@ +package it.fabioformosa.quartzmanager.security.repositories; + +/** + * Temporary disabled + * + * @author Fabio + * + */ +//public interface AuthorityRepository extends JpaRepository { +// Authority findByName(String name); +//} +public interface AuthorityRepository { +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/repositories/UserRepository.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/repositories/UserRepository.java new file mode 100644 index 0000000..6ae1804 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/repositories/UserRepository.java @@ -0,0 +1,11 @@ +package it.fabioformosa.quartzmanager.security.repositories; + +import it.fabioformosa.quartzmanager.security.models.User; + +public interface UserRepository { + User findByUsername( String username ); +} +//public interface UserRepository extends JpaRepository { +// User findByUsername( String username ); +//} + diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/AuthorityService.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/AuthorityService.java new file mode 100644 index 0000000..5eca666 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/AuthorityService.java @@ -0,0 +1,13 @@ +package it.fabioformosa.quartzmanager.security.services; + +/** + * temporary disabled + * @author Fabio + * + */ +public interface AuthorityService { + // List findById(Long id); + // + // List findByname(String name); + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/UserService.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/UserService.java new file mode 100644 index 0000000..5b66879 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/UserService.java @@ -0,0 +1,18 @@ +package it.fabioformosa.quartzmanager.security.services; + +import java.util.List; + +import it.fabioformosa.quartzmanager.security.models.User; +import it.fabioformosa.quartzmanager.security.models.UserRequest; + +public interface UserService { + List findAll(); + + User findById(Long id); + + User findByUsername(String username); + + void resetCredentials(); + + User save(UserRequest user); +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/AuthorityServiceImpl.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/AuthorityServiceImpl.java new file mode 100644 index 0000000..78ebaf4 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/AuthorityServiceImpl.java @@ -0,0 +1,33 @@ +package it.fabioformosa.quartzmanager.security.services.impl; + +import it.fabioformosa.quartzmanager.security.services.AuthorityService; + +/** + * Temporary disabled + * @author Fabio + * + */ + +//@Service +public class AuthorityServiceImpl implements AuthorityService { + + // @Autowired + // private AuthorityRepository authorityRepository; + // + // @Override + // public List findById(Long id) { + // Authority auth = this.authorityRepository.getOne(id); + // List auths = new ArrayList<>(); + // auths.add(auth); + // return auths; + // } + // + // @Override + // public List findByname(String name) { + // Authority auth = this.authorityRepository.findByName(name); + // List auths = new ArrayList<>(); + // auths.add(auth); + // return auths; + // } + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/CustomUserDetailsService.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/CustomUserDetailsService.java new file mode 100644 index 0000000..f4b7adc --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/CustomUserDetailsService.java @@ -0,0 +1,67 @@ +package it.fabioformosa.quartzmanager.security.services.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; + +import it.fabioformosa.quartzmanager.security.models.User; +import it.fabioformosa.quartzmanager.security.repositories.UserRepository; + +/** + * Temporary disabled + * @author Fabio + * + */ +//@Service +public class CustomUserDetailsService implements UserDetailsService { + + protected final Log LOGGER = LogFactory.getLog(getClass()); + + @Autowired + private UserRepository userRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private AuthenticationManager authenticationManager; + + public void changePassword(String oldPassword, String newPassword) { + + // Authentication currentUser = SecurityContextHolder.getContext().getAuthentication(); + // String username = currentUser.getName(); + // + // if (authenticationManager != null) { + // LOGGER.debug("Re-authenticating user '"+ username + "' for password change request."); + // + // authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, oldPassword)); + // } else { + // LOGGER.debug("No authentication manager set. can't change Password!"); + // + // return; + // } + // + // LOGGER.debug("Changing password for user '"+ username + "'"); + // + // User user = (User) loadUserByUsername(username); + // + // user.setPassword(passwordEncoder.encode(newPassword)); + // userRepository.save(user); + + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + User user = userRepository.findByUsername(username); + if (user == null) + throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username)); + else + return user; + } + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/UserServiceImpl.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/UserServiceImpl.java new file mode 100644 index 0000000..9831e6e --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/services/impl/UserServiceImpl.java @@ -0,0 +1,79 @@ +package it.fabioformosa.quartzmanager.security.services.impl; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; + +import it.fabioformosa.quartzmanager.security.models.User; +import it.fabioformosa.quartzmanager.security.models.UserRequest; +import it.fabioformosa.quartzmanager.security.repositories.UserRepository; +import it.fabioformosa.quartzmanager.security.services.AuthorityService; +import it.fabioformosa.quartzmanager.security.services.UserService; + +/** + * Temporary disabled + * @author Fabio + * + */ +//@Service +public class UserServiceImpl implements UserService { + + @Autowired + private UserRepository userRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private AuthorityService authService; + + @Override + @PreAuthorize("hasRole('ADMIN')") + public List findAll() throws AccessDeniedException { + // List result = userRepository.findAll(); + // return result; + return null; + } + + @Override + @PreAuthorize("hasRole('ADMIN')") + public User findById(Long id) throws AccessDeniedException { + // User u = userRepository.getOne(id); + // return u; + return null; + } + + @Override + // @PreAuthorize("hasRole('USER')") + public User findByUsername(String username) throws UsernameNotFoundException { + User u = userRepository.findByUsername(username); + return u; + } + + @Override + public void resetCredentials() { + // List users = userRepository.findAll(); + // for (User user : users) { + // user.setPassword(passwordEncoder.encode("123")); + // userRepository.save(user); + // } + } + + @Override + public User save(UserRequest userRequest) { + User user = new User(); + // user.setUsername(userRequest.getUsername()); + // user.setPassword(passwordEncoder.encode(userRequest.getPassword())); + // user.setFirstname(userRequest.getFirstname()); + // user.setLastname(userRequest.getLastname()); + // List auth = authService.findByname("ROLE_USER"); + // user.setAuthorities(auth); + // this.userRepository.save(user); + return user; + } + +} diff --git a/quartz-manager-parent/quartz-manager-security/src/main/resources/META-INF/spring.factories b/quartz-manager-parent/quartz-manager-security/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..9e6be3c --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +it.fabioformosa.quartzmanager.security.configuration.WebSecurityConfigJWT,\ +it.fabioformosa.quartzmanager.security.configuration.properties.JwtSecurityProperties,\ +it.fabioformosa.quartzmanager.security.configuration.properties.InMemoryAccountProperties \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-ui-webjar/pom.xml b/quartz-manager-parent/quartz-manager-ui-webjar/pom.xml index fb3f625..68aeee1 100644 --- a/quartz-manager-parent/quartz-manager-ui-webjar/pom.xml +++ b/quartz-manager-parent/quartz-manager-ui-webjar/pom.xml @@ -26,110 +26,114 @@ - - - - - - - org.apache.maven.plugins - maven-resources-plugin - 2.6 - - - copy-resources - generate-resources - - copy-resources - - - ${basedir}/target/tmp - - - ../../${frontend.folderName} - - static/** - dist/** - node_modules/** - - - - - - - - - - - com.github.eirslett - frontend-maven-plugin - 1.11.0 - - target/tmp - - + + + build-webjar + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.6 + + + copy-resources + generate-resources + + copy-resources + + + ${basedir}/target/tmp + + + ../../${frontend.folderName} + + static/** + dist/** + node_modules/** + + + + + + + - - install node and npm - - install-node-and-npm - - generate-resources + + + com.github.eirslett + frontend-maven-plugin + 1.11.0 - ${node.version} - ${npm.version} + target/tmp - + + + + install node and npm + + install-node-and-npm + + generate-resources + + ${node.version} + ${npm.version} + + + + + npm install + + npm + + process-resources + + install + + + + + npm run build + + npm + + process-resources + + run build + + + + + - - npm install - - npm - - process-resources - - install - - - - - npm run build - - npm - - process-resources - - run build - - - - - - - - - maven-antrun-plugin - 1.8 - - - clean build files - process-resources - - - - - - - - - - - run - - - - - - + + + maven-antrun-plugin + 1.8 + + + clean build files + process-resources + + + + + + + + + + + run + + + + + + + + diff --git a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml index 0a83c7e..1c353c1 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml +++ b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml @@ -29,10 +29,10 @@ quartz-manager-api - - it.fabioformosa.quartz-manager - quartz-manager-ui-webjar - + + + + From 1f631529d9c57501d43454ea52594e573542e935 Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Tue, 2 Feb 2021 20:35:51 +0100 Subject: [PATCH 07/11] #30 moved whoami controller to the quartz-manager-api --- .../quartz-manager-api/pom.xml | 4 ++ .../controllers/UserController.java | 67 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 quartz-manager-parent/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java diff --git a/quartz-manager-parent/quartz-manager-api/pom.xml b/quartz-manager-parent/quartz-manager-api/pom.xml index 83df094..dc931ef 100644 --- a/quartz-manager-parent/quartz-manager-api/pom.xml +++ b/quartz-manager-parent/quartz-manager-api/pom.xml @@ -38,6 +38,10 @@ org.springframework.boot spring-boot-starter-websocket + + + org.springframework.security + spring-security-core org.springframework.boot diff --git a/quartz-manager-parent/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java b/quartz-manager-parent/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java new file mode 100644 index 0000000..5e431ea --- /dev/null +++ b/quartz-manager-parent/quartz-manager-api/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java @@ -0,0 +1,67 @@ +package it.fabioformosa.quartzmanager.controllers; + +import org.springframework.http.MediaType; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(value = "/quartz-manager/api", produces = MediaType.APPLICATION_JSON_VALUE) +public class UserController { + + + @GetMapping("/whoami") + public @ResponseBody Object user() { + SecurityContext context = SecurityContextHolder.getContext(); + if(context != null && context.getAuthentication() != null) + return context.getAuthentication().getPrincipal(); + return "\"NO_AUTH\""; + } + + /** + * JWT Temporary disabled + * + * @author Fabio.Formosa + * + */ + + // @Autowired + // private UserService userService; + + + // @RequestMapping(method = POST, value = "/signup") + // public ResponseEntity addUser(@RequestBody UserRequest userRequest, + // UriComponentsBuilder ucBuilder) { + // + // User existUser = this.userService.findByUsername(userRequest.getUsername()); + // if (existUser != null) + // throw new ResourceConflictException(userRequest.getId(), "Username already exists"); + // User user = this.userService.save(userRequest); + // HttpHeaders headers = new HttpHeaders(); + // headers.setLocation(ucBuilder.path("/api/user/{userId}").buildAndExpand(user.getId()).toUri()); + // return new ResponseEntity<>(user, HttpStatus.CREATED); + // } + // + // @RequestMapping(method = GET, value = "/user/all") + // public List loadAll() { + // return this.userService.findAll(); + // } + // + // @RequestMapping(method = GET, value = "/user/{userId}") + // public User loadById(@PathVariable Long userId) { + // return this.userService.findById(userId); + // } + // + // + // @RequestMapping(method = GET, value = "/user/reset-credentials") + // public ResponseEntity resetCredentials() { + // this.userService.resetCredentials(); + // Map result = new HashMap<>(); + // result.put("result", "success"); + // return ResponseEntity.accepted().body(result); + // } + +} From 8c5b349196abff9773745b4c1fe1eb48ad8c7941 Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Tue, 2 Feb 2021 23:41:19 +0100 Subject: [PATCH 08/11] #30 removed all classed moved in quartz-manager-security --- quartz-manager-parent/pom.xml | 13 +- .../controllers/AuthenticationController.java | 82 ++++++++ .../quartz-manager-web-showcase/pom.xml | 13 +- .../configuration/WebSecurityConfigJWT.java | 192 ------------------ .../properties/InMemoryAccountProperties.java | 24 --- .../properties/JwtSecurityProperties.java | 33 --- .../controllers/AuthenticationController.java | 82 -------- .../controllers/UserController.java | 73 ------- .../security/helpers/LoginConfigurer.java | 21 -- .../impl/AjaxAuthenticationFilter.java | 55 ----- .../helpers/impl/AnonAuthentication.java | 45 ---- .../impl/AuthenticationFailureHandler.java | 20 -- .../impl/AuthenticationSuccessHandler.java | 35 ---- .../helpers/impl/ComboEntryPoint.java | 33 --- .../helpers/impl/FormLoginConfig.java | 75 ------- .../helpers/impl/JwtAuthenticationFilter.java | 34 ---- .../impl/JwtAuthenticationSuccessHandler.java | 14 -- .../JwtAuthenticationSuccessHandlerImpl.java | 78 ------- .../impl/JwtTokenAuthenticationFilter.java | 105 ---------- .../impl/JwtTokenBasedAuthentication.java | 42 ---- .../security/helpers/impl/JwtTokenHelper.java | 163 --------------- .../JwtUsernamePasswordFiterLoginConfig.java | 46 ----- .../security/helpers/impl/LogoutSuccess.java | 36 ---- .../impl/QuartzManagerHttpSecurity.java | 57 ------ .../helpers/impl/RESTRequestMatcher.java | 26 --- .../impl/RestAuthenticationEntryPoint.java | 23 --- .../helpers/impl/WebsocketRequestMatcher.java | 18 -- .../security/model/Authority.java | 53 ----- .../quartzmanager/security/model/User.java | 133 ------------ .../security/model/UserRequest.java | 56 ----- .../security/model/UserTokenState.java | 32 --- .../repository/AuthorityRepository.java | 13 -- .../security/repository/UserRepository.java | 11 - .../security/service/AuthorityService.java | 13 -- .../security/service/UserService.java | 18 -- .../service/impl/AuthorityServiceImpl.java | 33 --- .../impl/CustomUserDetailsService.java | 67 ------ .../service/impl/UserServiceImpl.java | 79 ------- 38 files changed, 102 insertions(+), 1844 deletions(-) create mode 100644 quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/controllers/AuthenticationController.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/InMemoryAccountProperties.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/JwtSecurityProperties.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserRequest.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/AuthorityRepository.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/AuthorityService.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java diff --git a/quartz-manager-parent/pom.xml b/quartz-manager-parent/pom.xml index a6213f7..57c3d5f 100644 --- a/quartz-manager-parent/pom.xml +++ b/quartz-manager-parent/pom.xml @@ -18,8 +18,9 @@ quartz-manager-api quartz-manager-ui-webjar + quartz-manager-security quartz-manager-web-showcase - quartz-manager-security + @@ -28,6 +29,16 @@ quartz-manager-api 2.2.2-SNAPSHOT + + it.fabioformosa.quartz-manager + quartz-manager-security + 2.2.2-SNAPSHOT + + + it.fabioformosa.quartz-manager + quartz-manager-ui-webjar + 2.2.2-SNAPSHOT + diff --git a/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/controllers/AuthenticationController.java b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/controllers/AuthenticationController.java new file mode 100644 index 0000000..ca02749 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-security/src/main/java/it/fabioformosa/quartzmanager/security/controllers/AuthenticationController.java @@ -0,0 +1,82 @@ +package it.fabioformosa.quartzmanager.security.controllers; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import it.fabioformosa.quartzmanager.security.helpers.impl.JwtTokenHelper; +import it.fabioformosa.quartzmanager.security.models.UserTokenState; +import it.fabioformosa.quartzmanager.security.services.impl.CustomUserDetailsService; + +/** + * JWT Temporary disabled + * + * @author Fabio.Formosa + * + */ + +//@RestController +//@RequestMapping( value = "/api", produces = MediaType.APPLICATION_JSON_VALUE ) +public class AuthenticationController { + + static class PasswordChanger { + public String oldPassword; + public String newPassword; + } + + @Autowired + private CustomUserDetailsService userDetailsService; + + @Autowired + JwtTokenHelper tokenHelper; + + @Value("${quartz-manager.security.jwt.expiration-in-sec}") + private int EXPIRES_IN_SEC; + + @Value("${quartz-manager.security.jwt.cookie-strategy-cookie}") + private String TOKEN_COOKIE; + + @RequestMapping(value = "/changePassword", method = RequestMethod.POST) + @PreAuthorize("hasRole('USER')") + public ResponseEntity changePassword(@RequestBody PasswordChanger passwordChanger) { + userDetailsService.changePassword(passwordChanger.oldPassword, passwordChanger.newPassword); + Map result = new HashMap<>(); + result.put( "result", "success" ); + return ResponseEntity.accepted().body(result); + } + + @RequestMapping(value = "/refresh", method = RequestMethod.GET) + public ResponseEntity refreshAuthenticationToken(HttpServletRequest request, HttpServletResponse response) { + + String authToken = tokenHelper.retrieveToken( request ); + if (authToken != null && tokenHelper.canTokenBeRefreshed(authToken)) { + // TODO check user password last update + String refreshedToken = tokenHelper.refreshToken(authToken); + + Cookie authCookie = new Cookie( TOKEN_COOKIE, refreshedToken ); + authCookie.setPath( "/quartz-manager" ); + authCookie.setHttpOnly( true ); + authCookie.setMaxAge( EXPIRES_IN_SEC ); + // Add cookie to response + response.addCookie( authCookie ); + + UserTokenState userTokenState = new UserTokenState(refreshedToken, EXPIRES_IN_SEC); + return ResponseEntity.ok(userTokenState); + } else { + UserTokenState userTokenState = new UserTokenState(); + return ResponseEntity.accepted().body(userTokenState); + } + } + +} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml index 1c353c1..654e9e4 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml +++ b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml @@ -28,11 +28,14 @@ it.fabioformosa.quartz-manager quartz-manager-api - - - - - + + it.fabioformosa.quartz-manager + quartz-manager-ui-webjar + + + it.fabioformosa.quartz-manager + quartz-manager-security + diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java deleted file mode 100644 index c3e2d8c..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java +++ /dev/null @@ -1,192 +0,0 @@ -package it.fabioformosa.quartzmanager.configuration; - -import org.apache.commons.lang3.BooleanUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.factory.PasswordEncoderFactories; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.authentication.HttpStatusEntryPoint; -import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.cors.CorsConfigurationSource; -import org.springframework.web.cors.UrlBasedCorsConfigurationSource; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import it.fabioformosa.quartzmanager.configuration.properties.InMemoryAccountProperties; -import it.fabioformosa.quartzmanager.configuration.properties.JwtSecurityProperties; -import it.fabioformosa.quartzmanager.security.helpers.LoginConfigurer; -import it.fabioformosa.quartzmanager.security.helpers.impl.AuthenticationFailureHandler; -import it.fabioformosa.quartzmanager.security.helpers.impl.AuthenticationSuccessHandler; -import it.fabioformosa.quartzmanager.security.helpers.impl.FormLoginConfig; -import it.fabioformosa.quartzmanager.security.helpers.impl.JwtAuthenticationSuccessHandler; -import it.fabioformosa.quartzmanager.security.helpers.impl.JwtAuthenticationSuccessHandlerImpl; -import it.fabioformosa.quartzmanager.security.helpers.impl.JwtTokenAuthenticationFilter; -import it.fabioformosa.quartzmanager.security.helpers.impl.JwtTokenHelper; -import it.fabioformosa.quartzmanager.security.helpers.impl.JwtUsernamePasswordFiterLoginConfig; -import it.fabioformosa.quartzmanager.security.helpers.impl.LogoutSuccess; -import it.fabioformosa.quartzmanager.security.helpers.impl.QuartzManagerHttpSecurity; - -/** - * - * @author Fabio.Formosa - * - */ -@Configuration -@EnableWebSecurity -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter { - - private static final String[] PATTERNS_SWAGGER_UI = {"/swagger-ui.html", "/v2/api-docs", "/swagger-resources/**", "/webjars/**"}; - - private static final String LOGIN_PATH = "/quartz-manager/api/login"; - private static final String LOGOUT_PATH = "/quartz-manager/api/logout"; - - @Value("${server.servlet.context-path}") - private String contextPath; - - @Value("${app.name}") - private String APP_NAME; - - @Value("${quartz-manager.security.login-model.form-login-enabled}") - private Boolean formLoginEnabled; - @Value("${quartz-manager.security.login-model.userpwd-filter-enabled}") - private Boolean userpwdFilterEnabled; - - @Autowired - private JwtSecurityProperties jwtSecurityProps; - - @Autowired - private ObjectMapper objectMapper; - - @Autowired - private UserDetailsService userDetailsService; - - @Autowired - private InMemoryAccountProperties inMemoryAccountProps; - - - @Override - public void configure(AuthenticationManagerBuilder authenticationManagerBuilder)throws Exception { - configureInMemoryAuthentication(authenticationManagerBuilder); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.csrf().disable() // - .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() // - .exceptionHandling().authenticationEntryPoint(restAuthEntryPoint()).and() // - .addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class) // - .authorizeRequests().anyRequest().authenticated(); - - QuartzManagerHttpSecurity.from(http).withLoginConfigurer(loginConfigurer(), logoutConfigurer()) // - .login(LOGIN_PATH, authenticationManager()).logout(LOGOUT_PATH); - - // temporary disabled csfr - // http.csrf().ignoringAntMatchers("/api/login", "/api/signup") // - // .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // - } - - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring()// - .antMatchers(HttpMethod.GET, PATTERNS_SWAGGER_UI) // - .antMatchers(HttpMethod.GET,"/css/**", "/js/**", "/img/**", "/lib/**"); - } - - private void configureInMemoryAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { - PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); - if(inMemoryAccountProps.isEnabled() && inMemoryAccountProps.getUsers() != null && !inMemoryAccountProps.getUsers().isEmpty()) { - InMemoryUserDetailsManagerConfigurer inMemoryAuth = authenticationManagerBuilder.inMemoryAuthentication(); - inMemoryAccountProps.getUsers() - .forEach(u -> inMemoryAuth - .withUser(u.getName()) - .password(encoder.encode(u.getPassword())) - .roles(u.getRoles().toArray(new String[0]))); - } - } - - @Bean - CorsConfigurationSource corsConfigurationSource() { - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues()); - return source; - } - - @Bean - public LoginConfigurer formLoginConfigurer() { - JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler(); - AuthenticationSuccessHandler authenticationSuccessHandler = new AuthenticationSuccessHandler(jwtAuthenticationSuccessHandler); - AuthenticationFailureHandler authenticationFailureHandler = new AuthenticationFailureHandler(); - LoginConfigurer loginConfigurer = new FormLoginConfig(authenticationSuccessHandler, authenticationFailureHandler); - return loginConfigurer; - } - - @Bean - public JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler() { - JwtTokenHelper jwtTokenHelper = jwtTokenHelper(); - JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler = new JwtAuthenticationSuccessHandlerImpl(contextPath, jwtSecurityProps, jwtTokenHelper, objectMapper); - return jwtAuthenticationSuccessHandler; - } - - @Bean - public JwtTokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception { - return new JwtTokenAuthenticationFilter(jwtTokenHelper(), userDetailsService); - } - - @Bean - public JwtTokenHelper jwtTokenHelper() { - return new JwtTokenHelper(APP_NAME, jwtSecurityProps); - } - - @Bean - public LoginConfigurer loginConfigurer() { - if(BooleanUtils.isTrue(userpwdFilterEnabled)) - return userpwdFilterLoginConfigurer(); - if(BooleanUtils.isNotFalse(formLoginEnabled)) - return formLoginConfigurer(); - throw new RuntimeException("No login configurer enabled!"); - } - - @Bean - public LogoutSuccess logoutConfigurer() { - return new LogoutSuccess(objectMapper); - } - - @Bean - public AuthenticationEntryPoint restAuthEntryPoint() { - return new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED); - } - - @Bean - @Override - public UserDetailsService userDetailsServiceBean() throws Exception { - return super.userDetailsServiceBean(); - } - - @Bean - public LoginConfigurer userpwdFilterLoginConfigurer() { - LoginConfigurer loginConfigurer = new JwtUsernamePasswordFiterLoginConfig(jwtAuthenticationSuccessHandler()); - return loginConfigurer; - } - - // @Bean - // public PasswordEncoder passwordEncoder() { - // return new BCryptPasswordEncoder(); - // } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/InMemoryAccountProperties.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/InMemoryAccountProperties.java deleted file mode 100644 index a6905ba..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/InMemoryAccountProperties.java +++ /dev/null @@ -1,24 +0,0 @@ -package it.fabioformosa.quartzmanager.configuration.properties; - -import lombok.Getter; -import lombok.Setter; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -import java.util.ArrayList; -import java.util.List; - -@Configuration -@ConfigurationProperties(prefix = "quartz-manager.accounts.in-memory") -@Getter @Setter -public class InMemoryAccountProperties { - private boolean enabled; - private List users; - - @Getter @Setter - public static class User { - private String name; - private String password; - private List roles = new ArrayList<>(); - } -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/JwtSecurityProperties.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/JwtSecurityProperties.java deleted file mode 100644 index e33baba..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/configuration/properties/JwtSecurityProperties.java +++ /dev/null @@ -1,33 +0,0 @@ -package it.fabioformosa.quartzmanager.configuration.properties; - -import lombok.Data; -import lombok.Getter; -import lombok.Setter; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - - -@Configuration -@ConfigurationProperties(prefix = "quartz-manager.security.jwt") -@Getter @Setter -public class JwtSecurityProperties { - private boolean enabled; - private String secret; - private long expirationInSec; - - private CookieStrategy cookieStrategy; - private HeaderStrategy headerStrategy; - - @Data - public static class CookieStrategy { - private boolean enabled; - private String cookie; - } - - @Data - public static class HeaderStrategy { - private boolean enabled; - private String header; - } - -} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java deleted file mode 100644 index 4b0d704..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java +++ /dev/null @@ -1,82 +0,0 @@ -package it.fabioformosa.quartzmanager.controllers; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import it.fabioformosa.quartzmanager.security.helpers.impl.JwtTokenHelper; -import it.fabioformosa.quartzmanager.security.model.UserTokenState; -import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService; - -/** - * JWT Temporary disabled - * - * @author Fabio.Formosa - * - */ - -//@RestController -//@RequestMapping( value = "/api", produces = MediaType.APPLICATION_JSON_VALUE ) -public class AuthenticationController { - - static class PasswordChanger { - public String oldPassword; - public String newPassword; - } - - @Autowired - private CustomUserDetailsService userDetailsService; - - @Autowired - JwtTokenHelper tokenHelper; - - @Value("${quartz-manager.security.jwt.expiration-in-sec}") - private int EXPIRES_IN_SEC; - - @Value("${quartz-manager.security.jwt.cookie-strategy-cookie}") - private String TOKEN_COOKIE; - - @RequestMapping(value = "/changePassword", method = RequestMethod.POST) - @PreAuthorize("hasRole('USER')") - public ResponseEntity changePassword(@RequestBody PasswordChanger passwordChanger) { - userDetailsService.changePassword(passwordChanger.oldPassword, passwordChanger.newPassword); - Map result = new HashMap<>(); - result.put( "result", "success" ); - return ResponseEntity.accepted().body(result); - } - - @RequestMapping(value = "/refresh", method = RequestMethod.GET) - public ResponseEntity refreshAuthenticationToken(HttpServletRequest request, HttpServletResponse response) { - - String authToken = tokenHelper.retrieveToken( request ); - if (authToken != null && tokenHelper.canTokenBeRefreshed(authToken)) { - // TODO check user password last update - String refreshedToken = tokenHelper.refreshToken(authToken); - - Cookie authCookie = new Cookie( TOKEN_COOKIE, refreshedToken ); - authCookie.setPath( "/quartz-manager" ); - authCookie.setHttpOnly( true ); - authCookie.setMaxAge( EXPIRES_IN_SEC ); - // Add cookie to response - response.addCookie( authCookie ); - - UserTokenState userTokenState = new UserTokenState(refreshedToken, EXPIRES_IN_SEC); - return ResponseEntity.ok(userTokenState); - } else { - UserTokenState userTokenState = new UserTokenState(); - return ResponseEntity.accepted().body(userTokenState); - } - } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java deleted file mode 100644 index 5df6496..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java +++ /dev/null @@ -1,73 +0,0 @@ -package it.fabioformosa.quartzmanager.controllers; - -import org.springframework.http.MediaType; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping(value = "/quartz-manager/api", produces = MediaType.APPLICATION_JSON_VALUE) -public class UserController { - - /** - * JWT Temporary disabled - * - * @author Fabio.Formosa - * - */ - - // @Autowired - // private UserService userService; - - - // @RequestMapping(method = POST, value = "/signup") - // public ResponseEntity addUser(@RequestBody UserRequest userRequest, - // UriComponentsBuilder ucBuilder) { - // - // User existUser = this.userService.findByUsername(userRequest.getUsername()); - // if (existUser != null) - // throw new ResourceConflictException(userRequest.getId(), "Username already exists"); - // User user = this.userService.save(userRequest); - // HttpHeaders headers = new HttpHeaders(); - // headers.setLocation(ucBuilder.path("/api/user/{userId}").buildAndExpand(user.getId()).toUri()); - // return new ResponseEntity<>(user, HttpStatus.CREATED); - // } - // - // @RequestMapping(method = GET, value = "/user/all") - // public List loadAll() { - // return this.userService.findAll(); - // } - // - // @RequestMapping(method = GET, value = "/user/{userId}") - // public User loadById(@PathVariable Long userId) { - // return this.userService.findById(userId); - // } - // - // - // @RequestMapping(method = GET, value = "/user/reset-credentials") - // public ResponseEntity resetCredentials() { - // this.userService.resetCredentials(); - // Map result = new HashMap<>(); - // result.put("result", "success"); - // return ResponseEntity.accepted().body(result); - // } - - /* - * We are not using userService.findByUsername here(we could), so it is good that we are making - * sure that the user has role "ROLE_USER" to access this endpoint. - */ - // @RequestMapping("/whoami") - // // @PreAuthorize("hasRole('USER')") - // public User user() { - // return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - // } - - @GetMapping("/whoami") - @PreAuthorize("isAuthenticated()") - public Object user() { - return SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java deleted file mode 100644 index 4446087..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/LoginConfigurer.java +++ /dev/null @@ -1,21 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers; - -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; - -/** - * It configures filters to authenticate credentials sent by client or to set authenticationSuccessHandler - * - * Implement this interface for a login strategy - * - */ -public interface LoginConfigurer { - - /** - * If the authentication is based on cookie, it returns the name of cookie to be erased at the logout - */ - String cookieMustBeDeletedAtLogout(); - - HttpSecurity login(String loginPath, HttpSecurity http, AuthenticationManager authenticationManager) throws Exception; - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java deleted file mode 100644 index 0c4e0b3..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AjaxAuthenticationFilter.java +++ /dev/null @@ -1,55 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.WebAttributes; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - -public class AjaxAuthenticationFilter extends UsernamePasswordAuthenticationFilter { - - public class AjaxLoginAuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler - implements AuthenticationSuccessHandler { - - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, - Authentication authentication) throws IOException, ServletException { - response.setStatus(HttpServletResponse.SC_OK); - clearAuthenticationAttributes(request); - return; - } - - } - - public AjaxAuthenticationFilter(AuthenticationManager authenticationManager) { - setAuthenticationManager(authenticationManager); - setUsernameParameter("ajaxUsername"); - setPasswordParameter("ajaxPassword"); - setPostOnly(true); - setFilterProcessesUrl("/ajaxLogin"); - - setAuthenticationSuccessHandler(new AjaxLoginAuthSuccessHandler()); - } - - /** - * Removes temporary authentication-related data which may have been stored - * in the session during the authentication process. - */ - protected final void clearAuthenticationAttributes(HttpServletRequest request) { - HttpSession session = request.getSession(false); - - if (session == null) - return; - - session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION); - } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java deleted file mode 100644 index f1c266f..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AnonAuthentication.java +++ /dev/null @@ -1,45 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import org.springframework.security.authentication.AbstractAuthenticationToken; - -public class AnonAuthentication extends AbstractAuthenticationToken { - private static final long serialVersionUID = 1L; - - public AnonAuthentication() { - super( null ); - } - - @Override - public boolean equals( Object obj ) { - if ( this == obj ) - return true; - if ( obj == null ) - return false; - if ( getClass() != obj.getClass() ) - return false; - return true; - } - - @Override - public Object getCredentials() { - return null; - } - - @Override - public Object getPrincipal() { - return null; - } - - @Override - public int hashCode() { - int hash = 7; - return hash; - } - - @Override - public boolean isAuthenticated() { - return true; - } - - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java deleted file mode 100644 index 08bb8b4..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationFailureHandler.java +++ /dev/null @@ -1,20 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; - -public class AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { - - @Override - public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, - AuthenticationException exception) throws IOException, ServletException { - - super.onAuthenticationFailure(request, response, exception); - } -} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java deleted file mode 100644 index 6634870..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/AuthenticationSuccessHandler.java +++ /dev/null @@ -1,35 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; - -//@Component -//@ConditionalOnProperty(prefix = "quartz-manager.security.login-model", name = "form-login-enabled", havingValue = "true", matchIfMissing = true) -public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { - - private final JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler; - - // @Autowired - public AuthenticationSuccessHandler(JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler) { - super(); - this.jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler; - } - - public String cookieMustBeDeletedAtLogout() { - return jwtAuthenticationSuccessHandler.cookieMustBeDeletedAtLogout(); - } - - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, - Authentication authentication ) throws IOException, ServletException { - clearAuthenticationAttributes(request); - jwtAuthenticationSuccessHandler.onLoginSuccess(authentication, response); - } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java deleted file mode 100644 index 7ab933d..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/ComboEntryPoint.java +++ /dev/null @@ -1,33 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; -import org.springframework.stereotype.Component; - -@Component -public class ComboEntryPoint extends LoginUrlAuthenticationEntryPoint { - - private static final String LOGIN_FORM_URL = "/login"; - - public ComboEntryPoint() { - super(LOGIN_FORM_URL); - } - - @Override - public void commence(HttpServletRequest request, HttpServletResponse response, - AuthenticationException authException) throws IOException, ServletException { - - if (RESTRequestMatcher.isRestRequest(request) - || WebsocketRequestMatcher.isWebsocketConnectionRequest(request)) - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); - else - super.commence(request, response, authException); - } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java deleted file mode 100644 index 206f969..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/FormLoginConfig.java +++ /dev/null @@ -1,75 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer; - -import it.fabioformosa.quartzmanager.security.helpers.LoginConfigurer; - -/** - * It delegates form to @FormLoginConfigurer of the httpSecurity. - * - */ -public class FormLoginConfig implements LoginConfigurer { - - private static final Logger log = LoggerFactory.getLogger(FormLoginConfig.class); - - private final AuthenticationSuccessHandler authenticationSuccessHandler; - - private final AuthenticationFailureHandler authenticationFailureHandler; - - - public FormLoginConfig() { - super(); - authenticationSuccessHandler = null; - authenticationFailureHandler = null; - } - - public FormLoginConfig(AuthenticationFailureHandler authenticationFailureHandler) { - super(); - authenticationSuccessHandler = null; - this.authenticationFailureHandler = authenticationFailureHandler; - } - - public FormLoginConfig(AuthenticationSuccessHandler authenticationSuccessHandler) { - super(); - this.authenticationSuccessHandler = authenticationSuccessHandler; - authenticationFailureHandler = null; - } - - public FormLoginConfig(AuthenticationSuccessHandler authenticationSuccessHandler, - AuthenticationFailureHandler authenticationFailureHandler) { - super(); - this.authenticationSuccessHandler = authenticationSuccessHandler; - this.authenticationFailureHandler = authenticationFailureHandler; - } - - @Override - public String cookieMustBeDeletedAtLogout() { - return authenticationSuccessHandler.cookieMustBeDeletedAtLogout(); - } - - @Override - public HttpSecurity login(String loginPath, - HttpSecurity http, AuthenticationManager authenticationManager) throws Exception { - log.debug("Configuring login through FormLoginConfigurer..."); - - FormLoginConfigurer login = http.formLogin().loginPage(loginPath); - - if(authenticationSuccessHandler != null) { - log.debug("Setting an authenticationSuccessHandler"); - login = login.successHandler(authenticationSuccessHandler); - } - - if(authenticationFailureHandler != null) { - log.debug("Setting an authenticationFailureHandler"); - login = login.failureHandler(authenticationFailureHandler); - } - - HttpSecurity httpSecurity = login.and(); - return httpSecurity; - } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java deleted file mode 100644 index c15c0ac..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationFilter.java +++ /dev/null @@ -1,34 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import javax.servlet.FilterChain; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - -import lombok.SneakyThrows; - -/** - * It extends the @UsernamePasswordAuthenticationFilter and it overrides the successfulAuthentication method to put jwtToken in the response - * - */ -public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { - - private JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler; - - public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler) { - this.jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler; - setAuthenticationManager(authenticationManager); - } - - @SneakyThrows - @Override - protected void successfulAuthentication(HttpServletRequest req, - HttpServletResponse res, - FilterChain chain, - Authentication auth) { - jwtAuthenticationSuccessHandler.onLoginSuccess(auth, res); - } -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java deleted file mode 100644 index 6a956c9..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import java.io.IOException; - -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.core.Authentication; - -public interface JwtAuthenticationSuccessHandler { - - String cookieMustBeDeletedAtLogout(); - - void onLoginSuccess(Authentication authentication, HttpServletResponse response) throws IOException; -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java deleted file mode 100644 index fee0ede..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtAuthenticationSuccessHandlerImpl.java +++ /dev/null @@ -1,78 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import java.io.IOException; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.User; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import it.fabioformosa.quartzmanager.configuration.properties.JwtSecurityProperties; -import it.fabioformosa.quartzmanager.security.model.UserTokenState; - -/** - * It depends on @JwtTokenHelper to generate the jwtToken. - * On login success, it generates the jwtToken and it returns it to the login according to possible strategies: cookie, response header. - * You can choice the strategy through @JwtSecurityProperties - * - */ -public class JwtAuthenticationSuccessHandlerImpl implements JwtAuthenticationSuccessHandler { - - private static final Logger log = LoggerFactory.getLogger(JwtAuthenticationSuccessHandlerImpl.class); - - private final JwtSecurityProperties jwtSecurityProps; - - private final JwtTokenHelper jwtTokenHelper; - - private final ObjectMapper objectMapper; - - private final String contextPath; - - @Autowired - public JwtAuthenticationSuccessHandlerImpl(String contextPath, JwtSecurityProperties jwtSecurityProps, JwtTokenHelper jwtTokenHelper, ObjectMapper objectMapper) { - this.contextPath = contextPath; - this.jwtSecurityProps = jwtSecurityProps; - this.jwtTokenHelper = jwtTokenHelper; - this.objectMapper = objectMapper; - } - - @Override - public String cookieMustBeDeletedAtLogout() { - if(!jwtSecurityProps.getCookieStrategy().isEnabled()) - return null; - return jwtSecurityProps.getCookieStrategy().getCookie(); - } - - @Override - public void onLoginSuccess(Authentication authentication, HttpServletResponse response) throws IOException { - log.debug("Login successed, generating jwtToken..."); - - User user = (User) authentication.getPrincipal(); - String jwtToken = jwtTokenHelper.generateToken(user.getUsername()); - - if(jwtSecurityProps.getCookieStrategy().isEnabled()) { - Cookie authCookie = new Cookie(jwtSecurityProps.getCookieStrategy().getCookie(), jwtToken); - authCookie.setHttpOnly(true); - authCookie.setMaxAge((int) jwtSecurityProps.getExpirationInSec()); - authCookie.setPath(contextPath); - response.addCookie(authCookie); - log.debug("Set jwtToken into the cookie {}", jwtSecurityProps.getCookieStrategy().getCookie()); - } - - if(jwtSecurityProps.getHeaderStrategy().isEnabled()) { - jwtTokenHelper.setHeader(response, jwtToken); - log.debug("Set jwtToken into the response header {}", jwtSecurityProps.getHeaderStrategy().getHeader()); - } - - UserTokenState userTokenState = new UserTokenState(jwtToken, jwtSecurityProps.getExpirationInSec()); - String jwtResponse = objectMapper.writeValueAsString(userTokenState); - response.setContentType("application/json"); - response.getWriter().write(jwtResponse); - } -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java deleted file mode 100644 index 346bb2f..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenAuthenticationFilter.java +++ /dev/null @@ -1,105 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.security.web.util.matcher.OrRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.web.filter.OncePerRequestFilter; - - -/** - * It finds the jwtToken into the request, it validates it and sets an @Authentication into the @SecurityContextHolder. - * If the request has a path included into the paths that must be skipped, it sets an anonymous authentication - * - * It delegates the jwtToken retrieve to the @JwtTokenHelper that applies several strategies. - * - */ -public class JwtTokenAuthenticationFilter extends OncePerRequestFilter { - - private static final Logger log = LoggerFactory.getLogger(JwtTokenAuthenticationFilter.class); - - private static final String ROOT_MATCHER = "/"; - private static final String FAVICON_MATCHER = "/favicon.ico"; - private static final String HTML_MATCHER = "/**/*.html"; - private static final String CSS_MATCHER = "/**/*.css"; - private static final String JS_MATCHER = "/**/*.js"; - private static final String IMG_MATCHER = "/images/*"; - private static final String LOGIN_MATCHER = "/api/login"; - private static final String LOGOUT_MATCHER = "/api/logout"; - - private static List PATH_TO_SKIP = Arrays.asList( - ROOT_MATCHER, - HTML_MATCHER, - FAVICON_MATCHER, - CSS_MATCHER, - JS_MATCHER, - IMG_MATCHER, - LOGIN_MATCHER, - LOGOUT_MATCHER - ); - - private final JwtTokenHelper jwtTokenHelper; - private final UserDetailsService userDetailsService; - - - public JwtTokenAuthenticationFilter(JwtTokenHelper jwtTokenHelper, UserDetailsService userDetailsService) { - super(); - this.jwtTokenHelper = jwtTokenHelper; - this.userDetailsService = userDetailsService; - } - - @Override - public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { - - String jwtToken = jwtTokenHelper.retrieveToken(request); - if (jwtToken != null) { - log.debug("Found a jwtToken into the request {}", request.getPathInfo()); - try { - String username = jwtTokenHelper.getUsernameFromToken(jwtToken); - UserDetails userDetails = userDetailsService.loadUserByUsername(username); - - JwtTokenBasedAuthentication authentication = new JwtTokenBasedAuthentication(userDetails); - authentication.setToken(jwtToken); - - SecurityContextHolder.getContext().setAuthentication(authentication); - } catch (Exception e) { - log.error("Authentication failed! an expected error occurred authenticating the request {}", request.getRequestURL()); - // SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication()); - // log.error("Switched to Anonymous Authentication, " - // + "because an error occurred setting authentication in security context holder due to " + e.getMessage(), e); - } - } - else if(skipPathRequest(request, PATH_TO_SKIP)) { - log.debug("Detected a path to be skipped from authentication, so activated anonymous auth for {}", request.getRequestURL()); - SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication()); - } - else - log.debug("Not found any jwtToken and the request hasn't a path to be skipped from auth. Path: {}", request.getRequestURL()); - - chain.doFilter(request, response); - } - - private boolean skipPathRequest(HttpServletRequest request, List pathsToSkip ) { - if(pathsToSkip == null) - pathsToSkip = new ArrayList(); - List matchers = pathsToSkip.stream().map(path -> new AntPathRequestMatcher(path)).collect(Collectors.toList()); - OrRequestMatcher compositeMatchers = new OrRequestMatcher(matchers); - return compositeMatchers.matches(request); - } - -} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java deleted file mode 100644 index 904ed07..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenBasedAuthentication.java +++ /dev/null @@ -1,42 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.core.userdetails.UserDetails; - - -public class JwtTokenBasedAuthentication extends AbstractAuthenticationToken { - - private static final long serialVersionUID = 1L; - - private String token; - private final UserDetails principle; - - public JwtTokenBasedAuthentication(UserDetails principle) { - super(principle.getAuthorities()); - this.principle = principle; - } - - @Override - public Object getCredentials() { - return token; - } - - @Override - public UserDetails getPrincipal() { - return principle; - } - - public String getToken() { - return token; - } - - @Override - public boolean isAuthenticated() { - return true; - } - - public void setToken( String token ) { - this.token = token; - } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java deleted file mode 100644 index a4bc953..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtTokenHelper.java +++ /dev/null @@ -1,163 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import java.nio.charset.StandardCharsets; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Base64; -import java.util.Date; -import java.util.Map; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; -import it.fabioformosa.quartzmanager.configuration.properties.JwtSecurityProperties; - -/** - * - * @author Fabio.Formosa - * - */ - -public class JwtTokenHelper { - - private static final Logger log = LoggerFactory.getLogger(JwtTokenHelper.class); - - private static String base64EncodeSecretKey(String secretKey) { - return Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8)); - } - - // @Value("${app.name}") - private final String appName; - - // @Autowired - private final JwtSecurityProperties jwtSecurityProps; - - private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512; - - // @Autowired - public JwtTokenHelper(String appName, JwtSecurityProperties jwtSecurityProps) { - super(); - this.appName = appName; - this.jwtSecurityProps = jwtSecurityProps; - } - - public Boolean canTokenBeRefreshed(String token) { - try { - final Date expirationDate = getClaimsFromToken(token).getExpiration(); - // String username = getUsernameFromToken(token); - // UserDetails userDetails = userDetailsService.loadUserByUsername(username); - return expirationDate.compareTo(generateCurrentDate()) > 0; - } catch (Exception e) { - return false; - } - } - - private Date generateCurrentDate() { - return new Date(getCurrentTimeMillis()); - } - - private Date generateExpirationDate() { - return new Date(getCurrentTimeMillis() + jwtSecurityProps.getExpirationInSec() * 1000); - } - - private String generateToken(Map claims) { - return Jwts.builder().setClaims(claims).setExpiration(generateExpirationDate()) - .signWith(SIGNATURE_ALGORITHM, base64EncodeSecretKey(jwtSecurityProps.getSecret())).compact(); - } - - public String generateToken(String username) { - return Jwts.builder().setIssuer(appName).setSubject(username).setIssuedAt(generateCurrentDate()) - .setExpiration(generateExpirationDate()) - .signWith(SIGNATURE_ALGORITHM, base64EncodeSecretKey(jwtSecurityProps.getSecret())).compact(); - } - - private Claims getClaimsFromToken(String token) { - Claims claims; - try { - claims = Jwts.parser().setSigningKey(base64EncodeSecretKey(jwtSecurityProps.getSecret())) - .parseClaimsJws(token).getBody(); - } catch (Exception e) { - claims = null; - log.error("Error getting claims from jwt token due to " + e.getMessage(), e); - } - return claims; - } - - /** - * Find a specific HTTP cookie in a request. - * - * @param request - * The HTTP request object. - * @param name - * The cookie name to look for. - * @return The cookie, or null if not found. - */ - public Cookie getCookieValueByName(HttpServletRequest request, String name) { - if (request.getCookies() == null) - return null; - for (int i = 0; i < request.getCookies().length; i++) - if (request.getCookies()[i].getName().equals(name)) - return request.getCookies()[i]; - return null; - } - - private long getCurrentTimeMillis() { - return LocalDateTime.now().atZone(ZoneId.of("Europe/Rome")).toInstant().toEpochMilli(); - } - - public String getUsernameFromToken(String token) { - String username; - try { - final Claims claims = getClaimsFromToken(token); - username = claims.getSubject(); - } catch (Exception e) { - username = null; - log.error("Error getting claims from jwt token due to " + e.getMessage(), e); - throw e; - } - return username; - } - - public String refreshToken(String token) { - String refreshedToken; - try { - final Claims claims = getClaimsFromToken(token); - claims.setIssuedAt(generateCurrentDate()); - refreshedToken = generateToken(claims); - } catch (Exception e) { - log.error("Error refreshing jwt token due to " + e.getMessage(), e); - refreshedToken = null; - } - return refreshedToken; - } - - public String retrieveToken(HttpServletRequest request) { - if (jwtSecurityProps.getCookieStrategy().isEnabled() == true) { - Cookie authCookie = getCookieValueByName(request, jwtSecurityProps.getCookieStrategy().getCookie()); - if (authCookie != null) - return authCookie.getValue(); - } - - if (jwtSecurityProps.getHeaderStrategy().isEnabled()) { - String authHeader = request.getHeader(jwtSecurityProps.getHeaderStrategy().getHeader()); - if (authHeader != null && authHeader.startsWith("Bearer ")) - return authHeader.substring(7); - } - - if(request.getParameter("access_token") != null) - return request.getParameter("access_token"); - - return null; - } - - public void setHeader(HttpServletResponse response, String token) { - response.addHeader(jwtSecurityProps.getHeaderStrategy().getHeader(), "Bearer " + token); - } -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java deleted file mode 100644 index 6f6991c..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/JwtUsernamePasswordFiterLoginConfig.java +++ /dev/null @@ -1,46 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpMethod; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter; -import org.springframework.security.web.util.matcher.RegexRequestMatcher; -import org.springframework.web.filter.GenericFilterBean; - -import it.fabioformosa.quartzmanager.security.helpers.LoginConfigurer; - -/** - * It adds a new filter @JwtAuthenticationFilter after @AbstractPreAuthenticatedProcessingFilter that match login path - * - */ -public class JwtUsernamePasswordFiterLoginConfig implements LoginConfigurer { - - private static final Logger log = LoggerFactory.getLogger(JwtUsernamePasswordFiterLoginConfig.class); - - private final JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler; - - public JwtUsernamePasswordFiterLoginConfig(JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler) { - super(); - this.jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler; - } - - public GenericFilterBean authenticationProcessingFilter(String loginPath, AuthenticationManager authenticationManager) throws Exception { - JwtAuthenticationFilter authenticationProcessingFilter = new JwtAuthenticationFilter(authenticationManager, jwtAuthenticationSuccessHandler); - authenticationProcessingFilter.setRequiresAuthenticationRequestMatcher(new RegexRequestMatcher(loginPath, HttpMethod.POST.name(), false)); - return authenticationProcessingFilter; - } - - @Override - public String cookieMustBeDeletedAtLogout() { - return jwtAuthenticationSuccessHandler.cookieMustBeDeletedAtLogout(); - } - - @Override - public HttpSecurity login(String loginPath, HttpSecurity http, AuthenticationManager authenticationManager) throws Exception { - log.debug("Configuring login through JwtAuthenticationFilter..."); - return http.addFilterAfter(authenticationProcessingFilter(loginPath, authenticationManager), AbstractPreAuthenticatedProcessingFilter.class); - } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java deleted file mode 100644 index 5f0eaa0..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/LogoutSuccess.java +++ /dev/null @@ -1,36 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; - -import com.fasterxml.jackson.databind.ObjectMapper; - -public class LogoutSuccess implements LogoutSuccessHandler { - - private final ObjectMapper objectMapper; - - public LogoutSuccess(ObjectMapper objectMapper) { - super(); - this.objectMapper = objectMapper; - } - - @Override - public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse response, Authentication authentication) - throws IOException, ServletException { - Map result = new HashMap<>(); - result.put( "result", "success" ); - response.setContentType("application/json"); - response.getWriter().write(objectMapper.writeValueAsString(result)); - response.setStatus(HttpServletResponse.SC_OK); - - } - -} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java deleted file mode 100644 index 55b9edb..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/QuartzManagerHttpSecurity.java +++ /dev/null @@ -1,57 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.SecurityConfigurerAdapter; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configurers.LogoutConfigurer; -import org.springframework.security.web.DefaultSecurityFilterChain; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; - -import it.fabioformosa.quartzmanager.security.helpers.LoginConfigurer; - -/** - * It wraps the httpSecurity to provide new function as login and logout - * - */ -public class QuartzManagerHttpSecurity extends SecurityConfigurerAdapter { - - public static QuartzManagerHttpSecurity from(HttpSecurity httpSecurity){ - QuartzManagerHttpSecurity newInstance = new QuartzManagerHttpSecurity(httpSecurity); - newInstance.setBuilder(httpSecurity); - return newInstance; - } - - private HttpSecurity httpSecurity; - - private LoginConfigurer loginConfigurer; - - private LogoutSuccess logoutSuccess; - - public QuartzManagerHttpSecurity(HttpSecurity httpSecurity) { - this.httpSecurity = httpSecurity; - // applicationContext = httpSecurity.getSharedObject(ApplicationContext.class); - } - - public QuartzManagerHttpSecurity login(String loginPath, AuthenticationManager authenticationManager) throws Exception { - if(loginConfigurer == null || logoutSuccess == null) - throw new IllegalStateException("QuartzManagerHttpSecurity requires to be set loginConfigurer and logoutSuccess!"); - httpSecurity = loginConfigurer.login(loginPath, httpSecurity, authenticationManager); - return this; - } - - - public LogoutConfigurer logout(String logoutPath) throws Exception { - LogoutConfigurer logoutConfigurer = httpSecurity.logout().logoutRequestMatcher(new AntPathRequestMatcher(logoutPath)) - .logoutSuccessHandler(logoutSuccess); - String cookie = loginConfigurer.cookieMustBeDeletedAtLogout(); - if(cookie != null) - logoutConfigurer.deleteCookies(cookie); - return logoutConfigurer; - } - - public QuartzManagerHttpSecurity withLoginConfigurer(LoginConfigurer loginConfigurer, LogoutSuccess logoutSuccess) { - this.loginConfigurer = loginConfigurer; - this.logoutSuccess = logoutSuccess; - return this; - } -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java deleted file mode 100644 index 1fb2d2b..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RESTRequestMatcher.java +++ /dev/null @@ -1,26 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import javax.servlet.http.HttpServletRequest; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.web.util.matcher.ELRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; - -public class RESTRequestMatcher { - - static private final Logger log = LoggerFactory.getLogger(RESTRequestMatcher.class); - - static public RequestMatcher matcherRequestedWith = new ELRequestMatcher( - "hasHeader('X-Requested-With','XMLHttpRequest')"); - static public RequestMatcher matcherAccept = new ELRequestMatcher( - "hasHeader('accept','application/json, text/plain, */*')"); - - static public boolean isRestRequest(HttpServletRequest request) { - log.trace("Detecting if it's an AJAX Request: " + request.getRequestURL() + " accept: " - + request.getHeader("accept") + " " + " X-Requested-With: " - + request.getHeader("X-Requested-With")); - return matcherRequestedWith.matches(request) || matcherAccept.matches(request); - } - -} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java deleted file mode 100644 index 3615a2e..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/RestAuthenticationEntryPoint.java +++ /dev/null @@ -1,23 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - - -import java.io.IOException; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.stereotype.Component; - -@Component -public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { - - @Override - public void commence(HttpServletRequest request, - HttpServletResponse response, - AuthenticationException authException) throws IOException { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); - } -} - diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java deleted file mode 100644 index 5b42424..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/helpers/impl/WebsocketRequestMatcher.java +++ /dev/null @@ -1,18 +0,0 @@ -package it.fabioformosa.quartzmanager.security.helpers.impl; - -import javax.servlet.http.HttpServletRequest; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class WebsocketRequestMatcher { - - static private final Logger log = LoggerFactory.getLogger(WebsocketRequestMatcher.class); - - static public boolean isWebsocketConnectionRequest(HttpServletRequest request) { - log.trace("Detecting if it's a Websocket Connection Request: " + request.getRequestURL()); - return request.getServletPath().equals("/progress/info") - || request.getServletPath().equals("/logs/info"); - } - -} \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java deleted file mode 100644 index f259933..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java +++ /dev/null @@ -1,53 +0,0 @@ -package it.fabioformosa.quartzmanager.security.model; - -import javax.persistence.Column; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -import org.springframework.security.core.GrantedAuthority; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -/** - * Temporary enabled only inMemoryAuthentication - * - * @author Fabio.Formosa - * - */ -//@Entity -//@Table(name="Authority") -public class Authority implements GrantedAuthority { - - @Id - @Column(name="id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - Long id; - - @Column(name="name") - String name; - - @Override - public String getAuthority() { - return name; - } - - @JsonIgnore - public Long getId() { - return id; - } - - @JsonIgnore - public String getName() { - return name; - } - - public void setId(Long id) { - this.id = id; - } - - public void setName(String name) { - this.name = name; - } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java deleted file mode 100644 index a8d2c41..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java +++ /dev/null @@ -1,133 +0,0 @@ -package it.fabioformosa.quartzmanager.security.model; - -import java.io.Serializable; -import java.util.Collection; -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; - -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -/** - * Temporary enabled only inMemoryAuthentication - * - * @author Fabio.Formosa - * - */ -//@Entity -//@Table(name = "USER") -public class User implements UserDetails, Serializable { - @Id - @Column(name = "id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "username") - private String username; - - @JsonIgnore - @Column(name = "password") - private String password; - - @Column(name = "firstname") - private String firstname; - - @Column(name = "lastname") - private String lastname; - - - @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) - @JoinTable(name = "user_authority", - joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), - inverseJoinColumns = @JoinColumn(name = "authority_id", referencedColumnName = "id")) - private List authorities; - - @Override - public Collection getAuthorities() { - return authorities; - } - - public String getFirstname() { - return firstname; - } - - public Long getId() { - return id; - } - - public String getLastname() { - return lastname; - } - - @Override - public String getPassword() { - return password; - } - - @Override - public String getUsername() { - return username; - } - - // We can add the below fields in the users table. - // For now, they are hardcoded. - @JsonIgnore - @Override - public boolean isAccountNonExpired() { - return true; - } - - @JsonIgnore - @Override - public boolean isAccountNonLocked() { - return true; - } - - @JsonIgnore - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - @JsonIgnore - @Override - public boolean isEnabled() { - return true; - } - - public void setAuthorities(List authorities) { - this.authorities = authorities; - } - - public void setFirstname(String firstname) { - this.firstname = firstname; - } - - public void setId(Long id) { - this.id = id; - } - - public void setLastname(String lastname) { - - this.lastname = lastname; - } - - public void setPassword(String password) { - this.password = password; - } - - public void setUsername(String username) { - this.username = username; - } -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserRequest.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserRequest.java deleted file mode 100644 index f89e4fd..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserRequest.java +++ /dev/null @@ -1,56 +0,0 @@ -package it.fabioformosa.quartzmanager.security.model; - - -public class UserRequest { - - private Long id; - - private String username; - - private String password; - - private String firstname; - - private String lastname; - - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getFirstname() { - return firstname; - } - - public void setFirstname(String firstname) { - this.firstname = firstname; - } - - public String getLastname() { - return lastname; - } - - public void setLastname(String lastname) { - this.lastname = lastname; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java deleted file mode 100644 index 39fb1b0..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java +++ /dev/null @@ -1,32 +0,0 @@ -package it.fabioformosa.quartzmanager.security.model; - -public class UserTokenState { - private String access_token; - private Long expires_in_sec; - - public UserTokenState() { - this.access_token = null; - this.expires_in_sec = null; - } - - public UserTokenState(String access_token, long expires_in_sec) { - this.access_token = access_token; - this.expires_in_sec = expires_in_sec; - } - - public String getAccess_token() { - return access_token; - } - - public Long getExpires_in_sec() { - return expires_in_sec; - } - - public void setAccess_token(String access_token) { - this.access_token = access_token; - } - - public void setExpires_in_sec(Long expires_in_sec) { - this.expires_in_sec = expires_in_sec; - } -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/AuthorityRepository.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/AuthorityRepository.java deleted file mode 100644 index 4e41786..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/AuthorityRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package it.fabioformosa.quartzmanager.security.repository; - -/** - * Temporary disabled - * - * @author Fabio - * - */ -//public interface AuthorityRepository extends JpaRepository { -// Authority findByName(String name); -//} -public interface AuthorityRepository { -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java deleted file mode 100644 index 755d323..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package it.fabioformosa.quartzmanager.security.repository; - -import it.fabioformosa.quartzmanager.security.model.User; - -public interface UserRepository { - User findByUsername( String username ); -} -//public interface UserRepository extends JpaRepository { -// User findByUsername( String username ); -//} - diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/AuthorityService.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/AuthorityService.java deleted file mode 100644 index f2d320c..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/AuthorityService.java +++ /dev/null @@ -1,13 +0,0 @@ -package it.fabioformosa.quartzmanager.security.service; - -/** - * temporary disabled - * @author Fabio - * - */ -public interface AuthorityService { - // List findById(Long id); - // - // List findByname(String name); - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java deleted file mode 100644 index 76dc45c..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java +++ /dev/null @@ -1,18 +0,0 @@ -package it.fabioformosa.quartzmanager.security.service; - -import java.util.List; - -import it.fabioformosa.quartzmanager.security.model.User; -import it.fabioformosa.quartzmanager.security.model.UserRequest; - -public interface UserService { - List findAll(); - - User findById(Long id); - - User findByUsername(String username); - - void resetCredentials(); - - User save(UserRequest user); -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java deleted file mode 100644 index 8faff51..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -package it.fabioformosa.quartzmanager.security.service.impl; - -import it.fabioformosa.quartzmanager.security.service.AuthorityService; - -/** - * Temporary disabled - * @author Fabio - * - */ - -//@Service -public class AuthorityServiceImpl implements AuthorityService { - - // @Autowired - // private AuthorityRepository authorityRepository; - // - // @Override - // public List findById(Long id) { - // Authority auth = this.authorityRepository.getOne(id); - // List auths = new ArrayList<>(); - // auths.add(auth); - // return auths; - // } - // - // @Override - // public List findByname(String name) { - // Authority auth = this.authorityRepository.findByName(name); - // List auths = new ArrayList<>(); - // auths.add(auth); - // return auths; - // } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java deleted file mode 100644 index cb8ef9e..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java +++ /dev/null @@ -1,67 +0,0 @@ -package it.fabioformosa.quartzmanager.security.service.impl; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.password.PasswordEncoder; - -import it.fabioformosa.quartzmanager.security.model.User; -import it.fabioformosa.quartzmanager.security.repository.UserRepository; - -/** - * Temporary disabled - * @author Fabio - * - */ -//@Service -public class CustomUserDetailsService implements UserDetailsService { - - protected final Log LOGGER = LogFactory.getLog(getClass()); - - @Autowired - private UserRepository userRepository; - - @Autowired - private PasswordEncoder passwordEncoder; - - @Autowired - private AuthenticationManager authenticationManager; - - public void changePassword(String oldPassword, String newPassword) { - - // Authentication currentUser = SecurityContextHolder.getContext().getAuthentication(); - // String username = currentUser.getName(); - // - // if (authenticationManager != null) { - // LOGGER.debug("Re-authenticating user '"+ username + "' for password change request."); - // - // authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, oldPassword)); - // } else { - // LOGGER.debug("No authentication manager set. can't change Password!"); - // - // return; - // } - // - // LOGGER.debug("Changing password for user '"+ username + "'"); - // - // User user = (User) loadUserByUsername(username); - // - // user.setPassword(passwordEncoder.encode(newPassword)); - // userRepository.save(user); - - } - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - User user = userRepository.findByUsername(username); - if (user == null) - throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username)); - else - return user; - } - -} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java deleted file mode 100644 index 0e2a90c..0000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -package it.fabioformosa.quartzmanager.security.service.impl; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.password.PasswordEncoder; - -import it.fabioformosa.quartzmanager.security.model.User; -import it.fabioformosa.quartzmanager.security.model.UserRequest; -import it.fabioformosa.quartzmanager.security.repository.UserRepository; -import it.fabioformosa.quartzmanager.security.service.AuthorityService; -import it.fabioformosa.quartzmanager.security.service.UserService; - -/** - * Temporary disabled - * @author Fabio - * - */ -//@Service -public class UserServiceImpl implements UserService { - - @Autowired - private UserRepository userRepository; - - @Autowired - private PasswordEncoder passwordEncoder; - - @Autowired - private AuthorityService authService; - - @Override - @PreAuthorize("hasRole('ADMIN')") - public List findAll() throws AccessDeniedException { - // List result = userRepository.findAll(); - // return result; - return null; - } - - @Override - @PreAuthorize("hasRole('ADMIN')") - public User findById(Long id) throws AccessDeniedException { - // User u = userRepository.getOne(id); - // return u; - return null; - } - - @Override - // @PreAuthorize("hasRole('USER')") - public User findByUsername(String username) throws UsernameNotFoundException { - User u = userRepository.findByUsername(username); - return u; - } - - @Override - public void resetCredentials() { - // List users = userRepository.findAll(); - // for (User user : users) { - // user.setPassword(passwordEncoder.encode("123")); - // userRepository.save(user); - // } - } - - @Override - public User save(UserRequest userRequest) { - User user = new User(); - // user.setUsername(userRequest.getUsername()); - // user.setPassword(passwordEncoder.encode(userRequest.getPassword())); - // user.setFirstname(userRequest.getFirstname()); - // user.setLastname(userRequest.getLastname()); - // List auth = authService.findByname("ROLE_USER"); - // user.setAuthorities(auth); - // this.userRepository.save(user); - return user; - } - -} From 56c81caf05d95e012baca9a59e1f0eea35812a5a Mon Sep 17 00:00:00 2001 From: Fabio Formosa Date: Tue, 2 Feb 2021 23:49:20 +0100 Subject: [PATCH 09/11] Update README.md --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d48029a..d22fd45 100644 --- a/README.md +++ b/README.md @@ -24,14 +24,17 @@ The project `quartz-manager-parent/quartz-manager-web` is an example of how-to: ## PROJECT STRUCTURE * **quartz-parent/quartz-manager-api** is the library that can be imported in webapp to have the quartz-manager API. -* **quartz-parent/quartz-manager-web** is an example of webapp that imports quartz-manager-api. It adds a secure layer and a custom job to be scheduled. +* **quartz-parent/quartz-manager-webjar** is a maven module to build and package the angular frontend in a webjar. +* **quartz-parent/quartz-manager-security** is ther library that can be imported in a webapp to have a security layer (login) over the quartz-manager API. +* **quartz-parent/quartz-manager-web-showcase** is an example of webapp that imports quartz-manager-api. Useful to develop the frontend started locally with the webpack dev server. * **quartz-frontend** is the angular app that interacts with the Quartz Manager API. Next steps in the roadmap are: -* to simplify the customization of the job through plugins -* to add CI/CD pipeline to ease the deploy pulling a docker container -* to add a complete setup UI panel for quartz, in term of cronjobs and multiple jobs -* to add a persistent layer to save all job logs. +* to add a persistent layer to save all job setup. +* to add a complete setup UI panel for quartz, in term of cronjobs and multiple jobs. +* to add CI/CD pipeline to ease the deploy pulling a docker container. +* Enabling adapters for integrations: kafka, etc. + ## QUICK START **[requirements]** Make sure you have installed From a7a86f960a6a171f96849a8f5f5a1a9786d1478f Mon Sep 17 00:00:00 2001 From: Fabio Formosa Date: Tue, 2 Feb 2021 23:55:05 +0100 Subject: [PATCH 10/11] Update README.md --- README.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d22fd45..329e15f 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,20 @@ Through this webapp you can launch and control your scheduled job. The UI Consol Open the [Project Roadmap](https://github.com/fabioformosa/quartz-manager/projects) to take a look at the plan of Quartz Manager. Currently this project might be useful to look how to import Quartz Library in a spring boot application. For this purpose, browse the folder `quartz-manager-parent/quartz-manager-api`. We're just working to create a library, from project `quartz-manager-parent/quartz-manager-api`, to be imported in your spring boot where you have your job to be scheduled. -The project `quartz-manager-parent/quartz-manager-web` is an example of how-to: - * import the library +The project [Quartz-Manager Demo](https://github.com/fabioformosa/quartz-manager-demo) is an example of how-to: + * import the quartz-manager-api library + * include the quartz-manager frontend (angular based) through a webjar * set the application.yml - * add secure layer + * add secure layer to allow the API only to logged users * schedule a custom job (a dummy `hello world`) + + **NB**: In few days, we'll release the library jar of quartz-manager into the maven central repo. + +Next steps in the roadmap are: +* to add a persistent layer to save all job setup. +* to add a complete setup UI panel for quartz, in term of cronjobs and multiple jobs. +* to add CI/CD pipeline to ease the deploy pulling a docker container. +* Enabling adapters for integrations: kafka, etc. ## PROJECT STRUCTURE * **quartz-parent/quartz-manager-api** is the library that can be imported in webapp to have the quartz-manager API. @@ -29,14 +38,7 @@ The project `quartz-manager-parent/quartz-manager-web` is an example of how-to: * **quartz-parent/quartz-manager-web-showcase** is an example of webapp that imports quartz-manager-api. Useful to develop the frontend started locally with the webpack dev server. * **quartz-frontend** is the angular app that interacts with the Quartz Manager API. -Next steps in the roadmap are: -* to add a persistent layer to save all job setup. -* to add a complete setup UI panel for quartz, in term of cronjobs and multiple jobs. -* to add CI/CD pipeline to ease the deploy pulling a docker container. -* Enabling adapters for integrations: kafka, etc. - - -## QUICK START +## HOW-TO CONTRIBUTE **[requirements]** Make sure you have installed * [Java 8](https://java.com/download/) or greater * [Maven](https://maven.apache.org/) From c29af8c5930b8d60e803850f87dab8c936d61cee Mon Sep 17 00:00:00 2001 From: Fabio Formosa Date: Tue, 2 Feb 2021 23:57:16 +0100 Subject: [PATCH 11/11] Update README.md --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 329e15f..a07a086 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,15 @@ Through this webapp you can launch and control your scheduled job. The UI Consol Open the [Project Roadmap](https://github.com/fabioformosa/quartz-manager/projects) to take a look at the plan of Quartz Manager. Currently this project might be useful to look how to import Quartz Library in a spring boot application. For this purpose, browse the folder `quartz-manager-parent/quartz-manager-api`. We're just working to create a library, from project `quartz-manager-parent/quartz-manager-api`, to be imported in your spring boot where you have your job to be scheduled. -The project [Quartz-Manager Demo](https://github.com/fabioformosa/quartz-manager-demo) is an example of how-to: - * import the quartz-manager-api library + +Take a loot to the project [Quartz-Manager Demo](https://github.com/fabioformosa/quartz-manager-demo), it is an example of how-to: + * import the quartz-manager-api library in your webapp * include the quartz-manager frontend (angular based) through a webjar - * set the application.yml - * add secure layer to allow the API only to logged users + * set properties into the application.yml + * add a secure layer to allow the API only to logged users * schedule a custom job (a dummy `hello world`) - **NB**: In few days, we'll release the library jar of quartz-manager into the maven central repo. + **NB: In few days, we'll release the library jar of quartz-manager into the maven central repo.** Next steps in the roadmap are: * to add a persistent layer to save all job setup.