diff --git a/src/main/java/io/wwan13/wintersecurity/auth/RequestAccessManager.java b/src/main/java/io/wwan13/wintersecurity/auth/RequestAccessManager.java index 18ba658..f0f239c 100644 --- a/src/main/java/io/wwan13/wintersecurity/auth/RequestAccessManager.java +++ b/src/main/java/io/wwan13/wintersecurity/auth/RequestAccessManager.java @@ -18,9 +18,11 @@ import org.springframework.http.HttpMethod; +import java.util.Set; + public interface RequestAccessManager { - void manageWithAuthentication(HttpMethod method, String uri, String role); + void manageWithAuthentication(HttpMethod method, String uri, Set roles); void manageWithoutAuthentication(HttpMethod method, String uri); } diff --git a/src/main/java/io/wwan13/wintersecurity/auth/authorizedrequest/AuthorizedRequest.java b/src/main/java/io/wwan13/wintersecurity/auth/authorizedrequest/AuthorizedRequest.java index d311c45..57195c7 100644 --- a/src/main/java/io/wwan13/wintersecurity/auth/authorizedrequest/AuthorizedRequest.java +++ b/src/main/java/io/wwan13/wintersecurity/auth/authorizedrequest/AuthorizedRequest.java @@ -19,18 +19,23 @@ import org.springframework.http.HttpMethod; import java.util.Map; +import java.util.Set; public record AuthorizedRequest( Map registered, boolean isElseRequestPermit ) { - public boolean isAccessibleRequest(HttpMethod httpMethod, String requestUri, String role) { + public boolean isAccessibleRequest( + HttpMethod httpMethod, + String requestUri, + Set roles + ) { return registered.keySet().stream() .filter(requests -> requests.isRegistered(httpMethod, requestUri)) .map(registered::get) .findFirst() - .map(permissions -> permissions.canAccess(role)) + .map(permissions -> permissions.canAccess(roles)) .orElse(isElseRequestPermit); } } diff --git a/src/main/java/io/wwan13/wintersecurity/auth/authorizedrequest/Permissions.java b/src/main/java/io/wwan13/wintersecurity/auth/authorizedrequest/Permissions.java index 8509dac..c914f61 100644 --- a/src/main/java/io/wwan13/wintersecurity/auth/authorizedrequest/Permissions.java +++ b/src/main/java/io/wwan13/wintersecurity/auth/authorizedrequest/Permissions.java @@ -18,28 +18,34 @@ import io.wwan13.wintersecurity.constant.DefaultAuthPattern; +import java.util.Optional; import java.util.Set; public record Permissions( Set roles ) { - public boolean canAccess(String enteredRole) { + public boolean canAccess(Set enteredRoles) { return roles.stream() .anyMatch(role -> checkPermitAll(role) || - checkAuthenticated(role, enteredRole) || hasRole(role, enteredRole)); + checkAuthenticated(role, enteredRoles) || hasRole(role, enteredRoles)); } private boolean checkPermitAll(String registeredRole) { return registeredRole.equals(DefaultAuthPattern.PERMIT_ALL); } - private boolean checkAuthenticated(String registeredRole, String enteredRole) { + private boolean checkAuthenticated(String registeredRole, Set enteredRoles) { + Optional anonymousRole = enteredRoles.stream() + .filter(DefaultAuthPattern.ANONYMOUS_ROLE::equals) + .findAny(); + return registeredRole.equals(DefaultAuthPattern.AUTHENTICATED) && - !enteredRole.equals(DefaultAuthPattern.ANONYMOUS_ROLE); + anonymousRole.isEmpty(); } - private boolean hasRole(String registeredRole, String enteredRole) { - return registeredRole.equals(enteredRole); + private boolean hasRole(String registeredRole, Set enteredRoles) { + return enteredRoles.stream() + .anyMatch(registeredRole::equals); } } diff --git a/src/main/java/io/wwan13/wintersecurity/auth/processor/InterceptorAuthProcessor.java b/src/main/java/io/wwan13/wintersecurity/auth/processor/InterceptorAuthProcessor.java index ba57c35..2472571 100644 --- a/src/main/java/io/wwan13/wintersecurity/auth/processor/InterceptorAuthProcessor.java +++ b/src/main/java/io/wwan13/wintersecurity/auth/processor/InterceptorAuthProcessor.java @@ -21,6 +21,7 @@ import io.wwan13.wintersecurity.auth.TokenExtractor; import io.wwan13.wintersecurity.constant.Constants; import io.wwan13.wintersecurity.jwt.TokenDecoder; +import io.wwan13.wintersecurity.jwt.payload.util.RoleSerializer; import org.springframework.http.HttpMethod; import javax.servlet.http.HttpServletRequest; @@ -57,12 +58,12 @@ private void actionIfTokenPresent( RequestStorage storage ) { Map claims = tokenDecoder.decode(token); - String role = (String) claims.get(Constants.PAYLOAD_KEY_USER_ROLE); + String rawRoles = (String) claims.get(Constants.PAYLOAD_KEY_USER_ROLE); accessManager.manageWithAuthentication( HttpMethod.resolve(request.getMethod()), request.getRequestURI(), - role + RoleSerializer.deserialize(rawRoles) ); storage.saveAll(claims); diff --git a/src/main/java/io/wwan13/wintersecurity/auth/provider/HttpRequestAccessManager.java b/src/main/java/io/wwan13/wintersecurity/auth/provider/HttpRequestAccessManager.java index 243235e..8ed73fd 100644 --- a/src/main/java/io/wwan13/wintersecurity/auth/provider/HttpRequestAccessManager.java +++ b/src/main/java/io/wwan13/wintersecurity/auth/provider/HttpRequestAccessManager.java @@ -23,6 +23,9 @@ import io.wwan13.wintersecurity.exception.unauthirized.UnauthorizedException; import org.springframework.http.HttpMethod; +import java.util.Collections; +import java.util.Set; + public class HttpRequestAccessManager implements RequestAccessManager { private final AuthorizedRequest authorizedRequest; @@ -31,14 +34,18 @@ public HttpRequestAccessManager(AuthorizedRequest authorizedRequest) { this.authorizedRequest = authorizedRequest; } - public void manageWithAuthentication(HttpMethod method, String uri, String role) { - if (!authorizedRequest.isAccessibleRequest(method, uri, role)) { + public void manageWithAuthentication( + HttpMethod method, + String uri, + Set roles + ) { + if (!authorizedRequest.isAccessibleRequest(method, uri, roles)) { throw new ForbiddenException(); } } public void manageWithoutAuthentication(HttpMethod method, String uri) { - String role = DefaultAuthPattern.ANONYMOUS_ROLE; + Set role = Collections.singleton(DefaultAuthPattern.ANONYMOUS_ROLE); if (!authorizedRequest.isAccessibleRequest(method, uri, role)) { throw new UnauthorizedException(); diff --git a/src/test/java/io/wwan13/wintersecurity/auth/authorizedrequest/AuthorizedRequestTest.java b/src/test/java/io/wwan13/wintersecurity/auth/authorizedrequest/AuthorizedRequestTest.java index 2f7159e..c5edd93 100644 --- a/src/test/java/io/wwan13/wintersecurity/auth/authorizedrequest/AuthorizedRequestTest.java +++ b/src/test/java/io/wwan13/wintersecurity/auth/authorizedrequest/AuthorizedRequestTest.java @@ -23,6 +23,8 @@ import org.junit.jupiter.params.provider.CsvSource; import org.springframework.http.HttpMethod; +import java.util.Set; + import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; @@ -74,7 +76,7 @@ void should_JudgeRequestIsAccessible( // when boolean result = authorizedRequest - .isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, requestRole); + .isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, Set.of(requestRole)); // then assertThat(result).isEqualTo(expected); @@ -107,7 +109,7 @@ void should_AcceptUnregisteredRequest_when_AnyRequestPermitAll( // when boolean result = authorizedRequest - .isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, requestRole); + .isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, Set.of(requestRole)); // then assertThat(result).isEqualTo(expected); @@ -141,7 +143,7 @@ void should_BlockUnregisteredRequest_when_AnyRequestAuthenticated( // when boolean result = authorizedRequest - .isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, requestRole); + .isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, Set.of(requestRole)); // then assertThat(result).isEqualTo(expected); diff --git a/src/test/java/io/wwan13/wintersecurity/auth/authorizedrequest/PermissionsTest.java b/src/test/java/io/wwan13/wintersecurity/auth/authorizedrequest/PermissionsTest.java index f043bcf..a87da4d 100644 --- a/src/test/java/io/wwan13/wintersecurity/auth/authorizedrequest/PermissionsTest.java +++ b/src/test/java/io/wwan13/wintersecurity/auth/authorizedrequest/PermissionsTest.java @@ -55,7 +55,7 @@ void should_AcceptOnlyRegisteredRoles_when_SomeRolesRegistered( Permissions permissions = new Permissions(roles); // when - boolean result = permissions.canAccess(enteredRole); + boolean result = permissions.canAccess(Set.of(enteredRole)); // then assertThat(result).isEqualTo(expected); @@ -72,7 +72,7 @@ void should_AcceptAll_when_RegisteredIsPermitAll( Permissions permissions = new Permissions(roles); // when - boolean result = permissions.canAccess(enteredRole); + boolean result = permissions.canAccess(Set.of(enteredRole)); // then assertThat(result).isEqualTo(expected); @@ -89,7 +89,7 @@ void should_AcceptAllValidRolesWithoutAnonymous_when_RegisteredIsAuthenticated( Permissions permissions = new Permissions(roles); // when - boolean result = permissions.canAccess(enteredRole); + boolean result = permissions.canAccess(Set.of(enteredRole)); // then assertThat(result).isEqualTo(expected); diff --git a/src/test/java/io/wwan13/wintersecurity/auth/provider/HttpRequestAccessManagerTest.java b/src/test/java/io/wwan13/wintersecurity/auth/provider/HttpRequestAccessManagerTest.java index fc3456d..370dd81 100644 --- a/src/test/java/io/wwan13/wintersecurity/auth/provider/HttpRequestAccessManagerTest.java +++ b/src/test/java/io/wwan13/wintersecurity/auth/provider/HttpRequestAccessManagerTest.java @@ -25,6 +25,8 @@ import org.junit.jupiter.api.Test; import org.springframework.http.HttpMethod; +import java.util.Set; + import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -52,7 +54,7 @@ void should_PassWithoutException_when_ValidRequestEnteredWithAuthentication() { // when, then assertThatNoException() - .isThrownBy(() -> accessManager.manageWithAuthentication(method, uri, role)); + .isThrownBy(() -> accessManager.manageWithAuthentication(method, uri, Set.of(role))); } @Test @@ -63,7 +65,7 @@ void should_ThrowForbiddenException_when_InvalidRequestEnteredWithAuthentication final String role = "ROLE_ADMIN"; // when, then - assertThatThrownBy(() -> accessManager.manageWithAuthentication(method, uri, role)) + assertThatThrownBy(() -> accessManager.manageWithAuthentication(method, uri, Set.of(role))) .isInstanceOf(ForbiddenException.class); } diff --git a/src/test/java/io/wwan13/wintersecurity/context/AuthorizedRequestContextTest.java b/src/test/java/io/wwan13/wintersecurity/context/AuthorizedRequestContextTest.java index cce932f..fa85c0e 100644 --- a/src/test/java/io/wwan13/wintersecurity/context/AuthorizedRequestContextTest.java +++ b/src/test/java/io/wwan13/wintersecurity/context/AuthorizedRequestContextTest.java @@ -25,6 +25,8 @@ import org.springframework.context.annotation.Import; import org.springframework.http.HttpMethod; +import java.util.Set; + import static org.assertj.core.api.Assertions.assertThat; @Import({TestContextConfig.class}) @@ -46,7 +48,7 @@ void should_RegisteredInSpringIocWithEnteredValue_when_ContextLoaded( ) { // given, when boolean result = authorizedRequest - .isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, requestRole); + .isAccessibleRequest(HttpMethod.resolve(requestMethod), requestUri, Set.of(requestRole)); // then assertThat(result).isEqualTo(expected);