From cb0369b1d439a02ba2beb84492fe2ec6758b20d5 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 13 Aug 2024 17:08:06 +0300 Subject: [PATCH] [springboot3]: Refactor websecurity logic --- .gitignore | 6 +- README.md | 21 +++++- .../AuthorizationConfiguration.java | 71 +++++++++++++++++-- .../SecurityConfiguration.java | 9 +-- .../authorization/configuration/Mode.java | 5 ++ ...roperties.java => SecurityProperties.java} | 5 +- ...orizationLibraryCheckDeployController.java | 36 +++------- .../exceptions/ExceptionResponse.java | 36 ++++++++++ .../exceptions/ExceptionsHandler.java | 33 +++++++++ .../exceptions/HttpException.java | 16 +++++ .../exceptions/http/ConflictException.java | 10 +++ .../exceptions/http/ForbiddenException.java | 9 +++ .../exceptions/http/NotFoundException.java | 11 +++ .../http/UnauthorizedException.java | 10 +++ .../http/UnprocessableException.java | 10 +++ .../authorization/redis/RedisConfig.java | 20 +++--- .../authorization/redis/RedisWebSecurity.java | 3 + .../authorization/security/CorsConfig.java | 10 +-- .../stateless/AuthorizationUtils.java | 15 ++-- .../stateless/StatelessWebSecurity.java | 5 +- src/main/resources/authorization.properties | 2 - 21 files changed, 275 insertions(+), 68 deletions(-) create mode 100644 src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/configuration/Mode.java rename src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/configuration/{Properties.java => SecurityProperties.java} (91%) create mode 100644 src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/ExceptionResponse.java create mode 100644 src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/ExceptionsHandler.java create mode 100644 src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/HttpException.java create mode 100644 src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/ConflictException.java create mode 100644 src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/ForbiddenException.java create mode 100644 src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/NotFoundException.java create mode 100644 src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/UnauthorizedException.java create mode 100644 src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/UnprocessableException.java diff --git a/.gitignore b/.gitignore index 88b968b..4603eb3 100644 --- a/.gitignore +++ b/.gitignore @@ -54,9 +54,9 @@ atlassian-ide-plugin.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties +crashlytics.securityProperties +crashlytics-build.securityProperties +fabric.securityProperties # Editor-based Rest Client .idea/httpRequests diff --git a/README.md b/README.md index dfcb22a..8b1df7b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ user's session, but with a cost of an extra http request per request. import eu.dnetlib.uoaauthorizationlibrary.authorization.SecurityConfiguration; - @PropertySources({@PropertySource("classpath:authorization.properties")}) + @PropertySources({@PropertySource("classpath:authorization.securityProperties")}) @Import(SecurityConfiguration.class) public class Application { public static void main(String[] args) { @@ -62,7 +62,7 @@ where session is stored. import eu.dnetlib.uoaauthorizationlibrary.authorization.SecurityConfiguration; - @PropertySources({@PropertySource("classpath:authorization.properties")}) + @PropertySources({@PropertySource("classpath:authorization.securityProperties")}) @Import(SecurityConfiguration.class) public class Application { public static void main(String[] args) { @@ -152,10 +152,25 @@ e.g public Entity getEntity(@PathVariable("type") String type, @PathVariable("id") String id) {} +## Exception Handling + +This library provides exception handling if an error is occurred. + +### Know Http Exceptions + +- UnauthorizedException (401) +- ForbiddenException (403) +- NotFoundException (404) +- ConflictException (409) +- UnprocessableException (422) + +Create your own Exception with HttpStatus by extending **HttpException** class. +By default, any other Exception produces Http Status 400 (BAD REQUEST). + ## Swagger configuration This library by default includes swagger configuration, which is accessible only by PORTAL ADMIN users. -Optional set API info properties in your project configuration file: +Optional set API info securityProperties in your project configuration file: api.title = api.description = <Description> diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/AuthorizationConfiguration.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/AuthorizationConfiguration.java index 3c7a10c..13a8a8b 100644 --- a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/AuthorizationConfiguration.java +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/AuthorizationConfiguration.java @@ -1,14 +1,77 @@ package eu.dnetlib.uoaauthorizationlibrary; -import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.API; -import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.GlobalVars; -import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.Properties; +import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.*; +import jakarta.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; @Configuration -@EnableConfigurationProperties({Properties.class, GlobalVars.class, API.class}) +@EnableConfigurationProperties({SecurityProperties.class, GlobalVars.class, API.class}) @ComponentScan(basePackages = {"eu.dnetlib.uoaauthorizationlibrary.authorization"}) public class AuthorizationConfiguration { + + private final SecurityProperties properties; + private final GlobalVars globalVars; + + @Autowired + public AuthorizationConfiguration(SecurityProperties properties, GlobalVars globalVars) { + this.properties = properties; + this.globalVars = globalVars; + } + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + @PostConstruct + public void checkProperties() { + if(properties.getDomain() == null || properties.getDomain().isEmpty()) { + throw new RuntimeException("authorization.security.domain is missing!"); + } else if(properties.getSession() == null || properties.getSession().isEmpty()) { + throw new RuntimeException("authorization.security.session is missing!"); + } else if(SecurityProperties.MODE == Mode.STATELESS) { + if(properties.getUserInfoUrl() == null || properties.getUserInfoUrl().isEmpty()) { + throw new RuntimeException("authorization.security.userInfoUrl is missing!"); + } + } else if(SecurityProperties.MODE == Mode.REDIS) { + Redis redis = properties.getRedis(); + if (redis.getHost() == null || redis.getHost().isEmpty()) { + throw new RuntimeException("authorization.security.redis.host is missing!"); + } else if (redis.getPort() == null || redis.getPort().isEmpty()) { + throw new RuntimeException("authorization.security.redis.port is missing!"); + } + } + } + + public Map<String, String> getProperties() { + Map<String, String> map = new HashMap<>(); + map.put("authorization.security.domain", properties.getDomain()); + map.put("authorization.security.session", properties.getSession()); + if(SecurityProperties.MODE == Mode.STATELESS) { + map.put("authorization.security.userInfoUrl", properties.getUserInfoUrl()); + } + if(SecurityProperties.MODE == Mode.REDIS) { + map.put("authorization.security.redis.host", properties.getRedis().getHost()); + map.put("authorization.security.redis.port", properties.getRedis().getPort()); + map.put("authorization.security.redis.password", properties.getRedis().getPassword()); + } + if (GlobalVars.date != null) { + map.put("Date of deploy", GlobalVars.date.toString()); + } + if (globalVars.getBuildDate() != null) { + map.put("Date of build", globalVars.getBuildDate()); + } + if (globalVars.getVersion() != null) { + map.put("Version", globalVars.getVersion()); + } + return map; + } } diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/SecurityConfiguration.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/SecurityConfiguration.java index 6bd815d..ba13b89 100644 --- a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/SecurityConfiguration.java +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/SecurityConfiguration.java @@ -1,13 +1,10 @@ package eu.dnetlib.uoaauthorizationlibrary; -import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.API; -import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.GlobalVars; -import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.Properties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; @Configuration -@EnableConfigurationProperties({Properties.class, GlobalVars.class, API.class}) -@ComponentScan(basePackages = {"eu.dnetlib.uoaauthorizationlibrary.authorization"}, basePackageClasses = {WebSecurityConfig.class}) +@Import(AuthorizationConfiguration.class) +@ComponentScan(basePackageClasses = {WebSecurityConfig.class}) public class SecurityConfiguration { } diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/configuration/Mode.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/configuration/Mode.java new file mode 100644 index 0000000..08132a8 --- /dev/null +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/configuration/Mode.java @@ -0,0 +1,5 @@ +package eu.dnetlib.uoaauthorizationlibrary.authorization.configuration; + +public enum Mode { + STATELESS, REDIS +} diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/configuration/Properties.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/configuration/SecurityProperties.java similarity index 91% rename from src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/configuration/Properties.java rename to src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/configuration/SecurityProperties.java index e80ae37..ccb5541 100644 --- a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/configuration/Properties.java +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/configuration/SecurityProperties.java @@ -2,8 +2,11 @@ package eu.dnetlib.uoaauthorizationlibrary.authorization.configuration; import org.springframework.boot.context.properties.ConfigurationProperties; + @ConfigurationProperties("authorization.security") -public class Properties { +public class SecurityProperties { + + public static Mode MODE = Mode.STATELESS; private Redis redis = new Redis(); private String userInfoUrl; diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/controllers/AuthorizationLibraryCheckDeployController.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/controllers/AuthorizationLibraryCheckDeployController.java index 6e37823..9310a1b 100644 --- a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/controllers/AuthorizationLibraryCheckDeployController.java +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/controllers/AuthorizationLibraryCheckDeployController.java @@ -1,16 +1,15 @@ package eu.dnetlib.uoaauthorizationlibrary.authorization.controllers; -import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.GlobalVars; -import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.Properties; +import eu.dnetlib.uoaauthorizationlibrary.AuthorizationConfiguration; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; -import java.util.HashMap; import java.util.Map; @RestController @@ -18,37 +17,22 @@ import java.util.Map; public class AuthorizationLibraryCheckDeployController { private final Logger log = LogManager.getLogger(this.getClass()); - @Autowired - private Properties securityConfig; + private final AuthorizationConfiguration configuration; @Autowired - private GlobalVars globalVars; + public AuthorizationLibraryCheckDeployController(AuthorizationConfiguration configuration) { + this.configuration = configuration; + } @RequestMapping(value = {"","/", "/health_check"}, method = RequestMethod.GET) - public String hello() { + public ResponseEntity<String> hello() { log.debug("Hello from uoa-authorization-library!"); - return "Hello from uoa-authorization-library!"; + return ResponseEntity.ok("Hello from uoa-authorization-library!"); } @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN)") @RequestMapping(value = "/health_check/advanced", method = RequestMethod.GET) - public Map<String, String> checkEverything() { - Map<String, String> response = new HashMap<>(); - response.put("authorization.security.redis.host", securityConfig.getRedis().getHost()); - response.put("authorization.security.redis.port", securityConfig.getRedis().getPort()); - response.put("authorization.security.redis.password", securityConfig.getRedis().getPassword()); - response.put("authorization.security.userInfoUrl", securityConfig.getUserInfoUrl()); - response.put("authorization.security.session", securityConfig.getSession()); - response.put("authorization.security.domain", securityConfig.getDomain()); - if(GlobalVars.date != null) { - response.put("Date of deploy", GlobalVars.date.toString()); - } - if(globalVars.getBuildDate() != null) { - response.put("Date of build", globalVars.getBuildDate()); - } - if (globalVars.getVersion() != null) { - response.put("Version", globalVars.getVersion()); - } - return response; + public ResponseEntity<Map<String, String>> checkEverything() { + return ResponseEntity.ok(this.configuration.getProperties()); } } diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/ExceptionResponse.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/ExceptionResponse.java new file mode 100644 index 0000000..c129fed --- /dev/null +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/ExceptionResponse.java @@ -0,0 +1,36 @@ +package eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions; + +import org.springframework.http.HttpStatus; + +import java.util.Date; + +public class ExceptionResponse { + private final long timestamp; + private final int status; + private final String error; + private final Class<?> exception; + + public + ExceptionResponse(Exception exception, HttpStatus status) { + this.timestamp = new Date().getTime(); + this.status = status.value(); + this.error = exception.getMessage(); + this.exception = exception.getClass(); + } + + public long getTimestamp() { + return timestamp; + } + + public int getStatus() { + return status; + } + + public String getError() { + return error; + } + + public String getException() { + return exception.getName(); + } +} diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/ExceptionsHandler.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/ExceptionsHandler.java new file mode 100644 index 0000000..f5d7460 --- /dev/null +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/ExceptionsHandler.java @@ -0,0 +1,33 @@ +package eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions; + +import eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.http.UnauthorizedException; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class ExceptionsHandler { + private final Logger log = LogManager.getLogger(this.getClass()); + + @ExceptionHandler(AccessDeniedException.class) + public ResponseEntity<?> accessDenied(AccessDeniedException ex) { + log.error(ex.getMessage(), ex); + return new ResponseEntity<>(new ExceptionResponse(ex, HttpStatus.UNAUTHORIZED), HttpStatus.UNAUTHORIZED); + } + + @ExceptionHandler(HttpException.class) + public ResponseEntity<?> http(HttpException ex) { + log.error(ex.getMessage(), ex); + return new ResponseEntity<>(new ExceptionResponse(ex, ex.getHttpStatus()), ex.getHttpStatus()); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity<?> exception(Exception ex) { + log.error(ex.getMessage(), ex); + return new ResponseEntity<>(new ExceptionResponse(ex, HttpStatus.BAD_REQUEST), HttpStatus.BAD_REQUEST); + } +} diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/HttpException.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/HttpException.java new file mode 100644 index 0000000..889280e --- /dev/null +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/HttpException.java @@ -0,0 +1,16 @@ +package eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions; + +import org.springframework.http.HttpStatus; + +public class HttpException extends RuntimeException { + private final HttpStatus httpStatus; + + public HttpException(String message, HttpStatus httpStatus) { + super(message); + this.httpStatus = httpStatus; + } + + public HttpStatus getHttpStatus() { + return httpStatus; + } +} diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/ConflictException.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/ConflictException.java new file mode 100644 index 0000000..e6162c3 --- /dev/null +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/ConflictException.java @@ -0,0 +1,10 @@ +package eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.http; + +import eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.HttpException; +import org.springframework.http.HttpStatus; + +public class ConflictException extends HttpException { + public ConflictException(String message){ + super(message, HttpStatus.CONFLICT); + } +} diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/ForbiddenException.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/ForbiddenException.java new file mode 100644 index 0000000..755c933 --- /dev/null +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/ForbiddenException.java @@ -0,0 +1,9 @@ +package eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.http; + +import eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.HttpException; +import org.springframework.http.HttpStatus; + +public class ForbiddenException extends HttpException { + public ForbiddenException(String message){ + super(message, HttpStatus.FORBIDDEN); } +} diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/NotFoundException.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/NotFoundException.java new file mode 100644 index 0000000..0d08b7e --- /dev/null +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/NotFoundException.java @@ -0,0 +1,11 @@ +package eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.http; + +import eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.HttpException; +import org.springframework.http.HttpStatus; + +public class NotFoundException extends HttpException { + public NotFoundException(String message){ + super(message, HttpStatus.NOT_FOUND); + } +} + diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/UnauthorizedException.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/UnauthorizedException.java new file mode 100644 index 0000000..5e42b64 --- /dev/null +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/UnauthorizedException.java @@ -0,0 +1,10 @@ +package eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.http; + +import eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.HttpException; +import org.springframework.http.HttpStatus; + +public class UnauthorizedException extends HttpException { + public UnauthorizedException(String message){ + super(message, HttpStatus.UNAUTHORIZED); + } +} diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/UnprocessableException.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/UnprocessableException.java new file mode 100644 index 0000000..4c369a3 --- /dev/null +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/exceptions/http/UnprocessableException.java @@ -0,0 +1,10 @@ +package eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.http; + +import eu.dnetlib.uoaauthorizationlibrary.authorization.exceptions.HttpException; +import org.springframework.http.HttpStatus; + +public class UnprocessableException extends HttpException { + public UnprocessableException(String message){ + super(message, HttpStatus.UNPROCESSABLE_ENTITY); + } +} diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/redis/RedisConfig.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/redis/RedisConfig.java index 0a878a1..e954d60 100644 --- a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/redis/RedisConfig.java +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/redis/RedisConfig.java @@ -1,6 +1,6 @@ package eu.dnetlib.uoaauthorizationlibrary.authorization.redis; -import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.Properties; +import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.SecurityProperties; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; @@ -20,21 +20,21 @@ import org.springframework.session.web.http.DefaultCookieSerializer; @Configuration public class RedisConfig { - private final Properties properties; + private final SecurityProperties securityProperties; private static final Logger logger = LogManager.getLogger(RedisConfig.class); @Autowired - public RedisConfig(Properties properties) { - this.properties = properties; + public RedisConfig(SecurityProperties securityProperties) { + this.securityProperties = securityProperties; } @Bean public JedisConnectionFactory connectionFactory() { - logger.info(String.format("Redis connection listens to %s:%s ", properties.getRedis().getHost(), properties.getRedis().getPort())); - RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(properties.getRedis().getHost(), Integer.parseInt(properties.getRedis().getPort())); - if (properties.getRedis().getPassword() != null) - configuration.setPassword(properties.getRedis().getPassword()); + logger.info(String.format("Redis connection listens to %s:%s ", securityProperties.getRedis().getHost(), securityProperties.getRedis().getPort())); + RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(securityProperties.getRedis().getHost(), Integer.parseInt(securityProperties.getRedis().getPort())); + if (securityProperties.getRedis().getPassword() != null) + configuration.setPassword(securityProperties.getRedis().getPassword()); return new JedisConnectionFactory(configuration); } @@ -50,9 +50,9 @@ public class RedisConfig { @Bean public CookieSerializer cookieSerializer() { DefaultCookieSerializer serializer = new DefaultCookieSerializer(); - serializer.setCookieName(properties.getSession()); + serializer.setCookieName(securityProperties.getSession()); serializer.setCookiePath("/"); - serializer.setDomainName(properties.getDomain()); + serializer.setDomainName(securityProperties.getDomain()); return serializer; } } diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/redis/RedisWebSecurity.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/redis/RedisWebSecurity.java index 8e94665..c957448 100644 --- a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/redis/RedisWebSecurity.java +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/redis/RedisWebSecurity.java @@ -1,5 +1,7 @@ package eu.dnetlib.uoaauthorizationlibrary.authorization.redis; +import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.Mode; +import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.SecurityProperties; import eu.dnetlib.uoaauthorizationlibrary.authorization.security.AuthorizationService; import eu.dnetlib.uoaauthorizationlibrary.authorization.security.EntryPoint; import eu.dnetlib.uoaauthorizationlibrary.authorization.security.WebSecurity; @@ -18,6 +20,7 @@ public class RedisWebSecurity implements WebSecurity { public RedisWebSecurity(EntryPoint entryPoint, AuthorizationService service) { this.entryPoint = entryPoint; this.service = service; + SecurityProperties.MODE = Mode.REDIS; } public HttpSecurity security(HttpSecurity http) throws Exception { diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/security/CorsConfig.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/security/CorsConfig.java index 13d8f3c..51b21da 100644 --- a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/security/CorsConfig.java +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/security/CorsConfig.java @@ -1,6 +1,6 @@ package eu.dnetlib.uoaauthorizationlibrary.authorization.security; -import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.Properties; +import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.SecurityProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -10,11 +10,11 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig { - private final Properties properties; + private final SecurityProperties securityProperties; @Autowired - public CorsConfig(Properties properties) { - this.properties = properties; + public CorsConfig(SecurityProperties securityProperties) { + this.securityProperties = securityProperties; } @Bean @@ -23,7 +23,7 @@ public class CorsConfig { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") - .allowedOriginPatterns("*" + properties.getDomain(), "*" + properties.getDomain() + ":*") + .allowedOriginPatterns("*" + securityProperties.getDomain(), "*" + securityProperties.getDomain() + ":*") .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS") .allowCredentials(true); } diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/stateless/AuthorizationUtils.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/stateless/AuthorizationUtils.java index 88bbc44..4bb8d49 100644 --- a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/stateless/AuthorizationUtils.java +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/stateless/AuthorizationUtils.java @@ -1,6 +1,6 @@ package eu.dnetlib.uoaauthorizationlibrary.authorization.stateless; -import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.Properties; +import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.SecurityProperties; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import org.apache.logging.log4j.LogManager; @@ -16,16 +16,17 @@ import java.util.Collections; @Component public class AuthorizationUtils { private final Logger log = LogManager.getLogger(this.getClass()); - private final Properties properties; + private final SecurityProperties securityProperties; + private final RestTemplate restTemplate; @Autowired - AuthorizationUtils(Properties properties) { - this.properties = properties; + AuthorizationUtils(SecurityProperties securityProperties, RestTemplate restTemplate) { + this.securityProperties = securityProperties; + this.restTemplate = restTemplate; } public UserInfo getUserInfo(HttpServletRequest request) { - String url = properties.getUserInfoUrl(); - RestTemplate restTemplate = new RestTemplate(); + String url = securityProperties.getUserInfoUrl(); try { if(url != null && hasCookie(request)) { ResponseEntity<UserInfo> response = restTemplate.exchange(url, HttpMethod.GET, createHeaders(request), UserInfo.class); @@ -41,7 +42,7 @@ public class AuthorizationUtils { private boolean hasCookie(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); if(cookies != null) { - return Arrays.stream(cookies).anyMatch(cookie -> cookie.getName().equalsIgnoreCase(this.properties.getSession())); + return Arrays.stream(cookies).anyMatch(cookie -> cookie.getName().equalsIgnoreCase(this.securityProperties.getSession())); } return false; } diff --git a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/stateless/StatelessWebSecurity.java b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/stateless/StatelessWebSecurity.java index 97fa9bf..d1a5e7a 100644 --- a/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/stateless/StatelessWebSecurity.java +++ b/src/main/java/eu/dnetlib/uoaauthorizationlibrary/authorization/stateless/StatelessWebSecurity.java @@ -1,5 +1,7 @@ package eu.dnetlib.uoaauthorizationlibrary.authorization.stateless; +import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.Mode; +import eu.dnetlib.uoaauthorizationlibrary.authorization.configuration.SecurityProperties; import eu.dnetlib.uoaauthorizationlibrary.authorization.security.AuthorizationService; import eu.dnetlib.uoaauthorizationlibrary.authorization.security.EntryPoint; import eu.dnetlib.uoaauthorizationlibrary.authorization.security.WebSecurity; @@ -22,15 +24,16 @@ public class StatelessWebSecurity implements WebSecurity { this.filter = filter; this.entryPoint = entryPoint; this.service = service; + SecurityProperties.MODE = Mode.STATELESS; } @Override public HttpSecurity security(HttpSecurity http) throws Exception { http.csrf(AbstractHttpConfigurer::disable); + http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); http.addFilterBefore(filter, BasicAuthenticationFilter.class); http.exceptionHandling(handler -> handler.authenticationEntryPoint(entryPoint)); http.authorizeHttpRequests(auth -> auth.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").hasAuthority(this.service.PORTAL_ADMIN).anyRequest().permitAll()); - http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); return http; } diff --git a/src/main/resources/authorization.properties b/src/main/resources/authorization.properties index 68f450f..e2dcfc6 100644 --- a/src/main/resources/authorization.properties +++ b/src/main/resources/authorization.properties @@ -1,5 +1,3 @@ -spring.session.store-type=none -authorization.security.userInfoUrl= authorization.security.domain=di.uoa.gr authorization.security.session=openAIRESession authorization.global-vars.buildDate=@timestampAuthorizationLibrary@