From d69022e3f893facf4b66eb0b567d533661b0079f Mon Sep 17 00:00:00 2001 From: Roger Floriano <31597636+petruki@users.noreply.github.com> Date: Sun, 17 Mar 2024 00:32:54 -0700 Subject: [PATCH] Fixes Jwt Request filter logic by white lists (#8) --- .../config/MultiTenantJwtRequestFilter.java | 27 +++++++------- .../config/MultiTenantSecurityConfig.java | 4 +-- trackerforce-common/pom.xml | 12 ++----- .../common/config/SecurityConfig.java | 20 ++++++++--- .../config/IdentityJwtRequestFilter.java | 35 +++++++++---------- .../config/IdentitySecurityConfig.java | 2 +- .../src/main/resources/application-dev.yml | 10 +++--- .../src/main/resources/application-prod.yml | 6 ++-- .../src/test/resources/application-test.yml | 8 ++--- .../src/main/resources/application-dev.yml | 2 +- .../src/main/resources/application-dev.yml | 2 +- 11 files changed, 65 insertions(+), 63 deletions(-) diff --git a/trackerforce-common-tenancy/src/main/java/com/trackerforce/common/tenant/config/MultiTenantJwtRequestFilter.java b/trackerforce-common-tenancy/src/main/java/com/trackerforce/common/tenant/config/MultiTenantJwtRequestFilter.java index b370f92..0b99761 100644 --- a/trackerforce-common-tenancy/src/main/java/com/trackerforce/common/tenant/config/MultiTenantJwtRequestFilter.java +++ b/trackerforce-common-tenancy/src/main/java/com/trackerforce/common/tenant/config/MultiTenantJwtRequestFilter.java @@ -27,20 +27,19 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse throws ServletException, IOException { final Optional jwt = getJwtFromRequest(request); - jwt.ifPresent(token -> { - try { - String username = jwtTokenService.getUsernameFromToken(token); - if (Boolean.TRUE.equals(jwtTokenService.validateToken(token, username))) { - final UsernamePasswordAuthenticationToken authUser = - new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>()); - authUser.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - - SecurityContextHolder.getContext().setAuthentication(authUser); - } - } catch (IllegalArgumentException | MalformedJwtException | ExpiredJwtException | SignatureException e) { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - } - }); + try { + jwt.ifPresent(token -> { + String username = jwtTokenService.getUsernameFromToken(token); + if (Boolean.TRUE.equals(jwtTokenService.validateToken(token, username))) { + final var authUser = new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>()); + authUser.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authUser); + } + }); + } catch (IllegalArgumentException | MalformedJwtException | ExpiredJwtException | SignatureException e) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; + } filterChain.doFilter(request, response); } diff --git a/trackerforce-common-tenancy/src/main/java/com/trackerforce/common/tenant/config/MultiTenantSecurityConfig.java b/trackerforce-common-tenancy/src/main/java/com/trackerforce/common/tenant/config/MultiTenantSecurityConfig.java index d01c56d..15fbf1b 100644 --- a/trackerforce-common-tenancy/src/main/java/com/trackerforce/common/tenant/config/MultiTenantSecurityConfig.java +++ b/trackerforce-common-tenancy/src/main/java/com/trackerforce/common/tenant/config/MultiTenantSecurityConfig.java @@ -26,8 +26,8 @@ public class MultiTenantSecurityConfig extends SecurityConfig { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(auth -> auth.requestMatchers(allowedEndpoint).permitAll() - .requestMatchers("/**").access((authentication, object) -> buildAllowedIpList()) - .requestMatchers(SWAGGER_MATCHERS).authenticated()); + .requestMatchers(SWAGGER_MATCHERS).permitAll() + .requestMatchers("/**").access(this::authorize)); http.exceptionHandling(auth -> auth.authenticationEntryPoint(jwtAuthenticationEntryPoint)); http.sessionManagement(auth -> auth.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); diff --git a/trackerforce-common/pom.xml b/trackerforce-common/pom.xml index 1fbb9ce..bb6522f 100644 --- a/trackerforce-common/pom.xml +++ b/trackerforce-common/pom.xml @@ -29,7 +29,7 @@ 0.11.2 - 1.6.12 + 2.4.0 4.12.2 @@ -114,14 +114,8 @@ org.springdoc - springdoc-openapi-ui - ${springdoc.version} - - - - org.springdoc - springdoc-openapi-security - ${springdoc.version} + springdoc-openapi-starter-webmvc-ui + ${springdoc-openapi-starter-webmvc-ui.version} diff --git a/trackerforce-common/src/main/java/com/trackerforce/common/config/SecurityConfig.java b/trackerforce-common/src/main/java/com/trackerforce/common/config/SecurityConfig.java index 8d2542d..c439b40 100644 --- a/trackerforce-common/src/main/java/com/trackerforce/common/config/SecurityConfig.java +++ b/trackerforce-common/src/main/java/com/trackerforce/common/config/SecurityConfig.java @@ -3,8 +3,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.access.intercept.RequestAuthorizationContext; import org.springframework.security.web.util.matcher.IpAddressMatcher; +import java.util.function.Supplier; + public abstract class SecurityConfig { @Value("${service.endpoint.allowed-addresses}") @@ -19,15 +23,23 @@ public abstract class SecurityConfig { @Autowired protected JwtRequestFilter jwtRequestFilter; - protected AuthorizationDecision buildAllowedIpList() { - AuthorizationDecision decision = new AuthorizationDecision(true); + protected AuthorizationDecision authorize(Supplier authentication, RequestAuthorizationContext object) { + final var remoteAddress = object.getRequest().getRemoteAddr(); + var decision = new AuthorizationDecision(authentication.get().isAuthenticated()); + + boolean isAllowed = false; for (String address : allowedAddresses) { IpAddressMatcher ipAddressMatcher = new IpAddressMatcher(address); - if (!ipAddressMatcher.matches(address)) { - decision = new AuthorizationDecision(false); + if (ipAddressMatcher.matches(remoteAddress)) { + isAllowed = true; break; } } + + if (!isAllowed) { + decision = new AuthorizationDecision(false); + } + return decision; } diff --git a/trackerforce-identity/src/main/java/com/trackerforce/identity/config/IdentityJwtRequestFilter.java b/trackerforce-identity/src/main/java/com/trackerforce/identity/config/IdentityJwtRequestFilter.java index a3f5c00..c0d4da8 100644 --- a/trackerforce-identity/src/main/java/com/trackerforce/identity/config/IdentityJwtRequestFilter.java +++ b/trackerforce-identity/src/main/java/com/trackerforce/identity/config/IdentityJwtRequestFilter.java @@ -1,9 +1,9 @@ package com.trackerforce.identity.config; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Optional; - +import com.trackerforce.common.config.JwtRequestFilter; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.security.SignatureException; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -13,34 +13,31 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; -import com.trackerforce.common.config.JwtRequestFilter; - -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.MalformedJwtException; -import io.jsonwebtoken.security.SignatureException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Optional; @Component public class IdentityJwtRequestFilter extends JwtRequestFilter { @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { final Optional jwt = getJwtFromRequest(request); - jwt.ifPresent(token -> { - try { + try { + jwt.ifPresent(token -> { String username = jwtTokenService.getUsernameFromToken(token); if (Boolean.TRUE.equals(jwtTokenService.validateToken(token, username))) { - final UsernamePasswordAuthenticationToken authUser = new UsernamePasswordAuthenticationToken( - username, null, new ArrayList<>()); + final var authUser = new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>()); authUser.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - SecurityContextHolder.getContext().setAuthentication(authUser); } - } catch (IllegalArgumentException | MalformedJwtException | ExpiredJwtException | SignatureException e) { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - } - }); + }); + } catch (IllegalArgumentException | MalformedJwtException | ExpiredJwtException | SignatureException e) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; + } filterChain.doFilter(request, response); } diff --git a/trackerforce-identity/src/main/java/com/trackerforce/identity/config/IdentitySecurityConfig.java b/trackerforce-identity/src/main/java/com/trackerforce/identity/config/IdentitySecurityConfig.java index 1eb3c6d..296871a 100644 --- a/trackerforce-identity/src/main/java/com/trackerforce/identity/config/IdentitySecurityConfig.java +++ b/trackerforce-identity/src/main/java/com/trackerforce/identity/config/IdentitySecurityConfig.java @@ -24,7 +24,7 @@ public class IdentitySecurityConfig extends SecurityConfig { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(auth -> auth.requestMatchers(allowedEndpoint).permitAll() - .requestMatchers("/**").authenticated()); + .anyRequest().access(this::authorize)); http.exceptionHandling(auth -> auth.authenticationEntryPoint(jwtAuthenticationEntryPoint)); http.sessionManagement(auth -> auth.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); diff --git a/trackerforce-identity/src/main/resources/application-dev.yml b/trackerforce-identity/src/main/resources/application-dev.yml index 07d6a86..de93fb8 100644 --- a/trackerforce-identity/src/main/resources/application-dev.yml +++ b/trackerforce-identity/src/main/resources/application-dev.yml @@ -4,7 +4,7 @@ spring: data: mongodb: database: trackerforce - uri: mongodb://master:masterpassword@localhost:27017 + uri: mongodb://localhost:27017 management: endpoints: @@ -27,10 +27,10 @@ service: 10.0.0.2 allowed-endpoints: > /v3/api-docs, - /**/swagger*/**, - /**/authenticate, - /**/register, - /**/activate, + /*/swagger*/**, + /*/authenticate, + /*/register, + /*/activate, /service/check management: url: http://127.0.0.1:8090 diff --git a/trackerforce-identity/src/main/resources/application-prod.yml b/trackerforce-identity/src/main/resources/application-prod.yml index 3037344..31c5911 100644 --- a/trackerforce-identity/src/main/resources/application-prod.yml +++ b/trackerforce-identity/src/main/resources/application-prod.yml @@ -25,9 +25,9 @@ service: allowed-addresses: ${WHITELIST} allowed-endpoints: > /v3/api-docs, - /**/authenticate, - /**/register, - /**/activate, + /*/authenticate, + /*/register, + /*/activate, /service/check management: url: http://127.0.0.1:8090 diff --git a/trackerforce-identity/src/test/resources/application-test.yml b/trackerforce-identity/src/test/resources/application-test.yml index e5d6edc..a0d068e 100644 --- a/trackerforce-identity/src/test/resources/application-test.yml +++ b/trackerforce-identity/src/test/resources/application-test.yml @@ -22,10 +22,10 @@ service: 127.0.0.1 allowed-endpoints: > /v2/api-docs, - /**/swagger*/**, - /**/authenticate, - /**/register, - /**/activate, + /*/swagger*/**, + /*/authenticate, + /*/register, + /*/activate, /service/check management: url: http://127.0.0.1:8090 diff --git a/trackerforce-management/src/main/resources/application-dev.yml b/trackerforce-management/src/main/resources/application-dev.yml index 65a85cb..39f62c3 100644 --- a/trackerforce-management/src/main/resources/application-dev.yml +++ b/trackerforce-management/src/main/resources/application-dev.yml @@ -4,7 +4,7 @@ spring: data: mongodb: database: tfm - uri: mongodb://master:masterpassword@localhost:27017 + uri: mongodb://localhost:27017 management: endpoints: diff --git a/trackerforce-session/src/main/resources/application-dev.yml b/trackerforce-session/src/main/resources/application-dev.yml index 348fdb6..59c5ec8 100644 --- a/trackerforce-session/src/main/resources/application-dev.yml +++ b/trackerforce-session/src/main/resources/application-dev.yml @@ -4,7 +4,7 @@ spring: data: mongodb: database: tfs - uri: mongodb://master:masterpassword@localhost:27017 + uri: mongodb://localhost:27017 management: endpoints: