Skip to content

Commit 09b4659

Browse files
committed
wip
Signed-off-by: Richard Salac <richard.salac@broadcom.com>
1 parent e2371c9 commit 09b4659

File tree

4 files changed

+76
-33
lines changed

4 files changed

+76
-33
lines changed

zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/AuthenticationService.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import java.util.Optional;
6868
import java.util.Set;
6969

70+
import static org.zowe.apiml.security.common.token.QueryResponse.Source.ZOWE;
7071
import static org.zowe.apiml.security.common.util.JwtUtils.getJwtClaims;
7172
import static org.zowe.apiml.security.common.util.JwtUtils.handleJwtParserException;
7273
import static org.zowe.apiml.zaas.security.service.zosmf.ZosmfService.TokenType.JWT;
@@ -381,17 +382,16 @@ public TokenAuthentication validateJwtToken(String jwtToken) {
381382
}
382383

383384
QueryResponse queryResponse = parseJwtToken(jwtToken);
384-
boolean isValid = switch (queryResponse.getSource()) {
385-
case ZOWE -> {
386-
validateAndParseLocalJwtToken(jwtToken);
387-
yield true;
388-
}
385+
386+
switch (queryResponse.getSource()) {
387+
case ZOWE -> validateAndParseLocalJwtToken(jwtToken);
389388
case ZOSMF -> zosmfService.validate(jwtToken);
390389
default -> throw new TokenNotValidException("Unknown token type.");
391-
};
390+
}
391+
392392
boolean notInvalidated = !isInvalidated(jwtToken);
393393
TokenAuthentication tokenAuthentication = new TokenAuthentication(queryResponse.getUserId(), jwtToken, TokenAuthentication.Type.JWT);
394-
tokenAuthentication.setAuthenticated(notInvalidated && isValid);
394+
tokenAuthentication.setAuthenticated(notInvalidated);
395395

396396
putValidationCache(jwtToken, tokenAuthentication);
397397
log.debug("JWT validation result: {}", tokenAuthentication.isAuthenticated());
@@ -457,9 +457,9 @@ public TokenAuthentication validateJwtToken(TokenAuthentication token) {
457457
throw new TokenNotValidException("Null token.");
458458
}
459459
parseJwtToken(token.getCredentials()); // throws on expired token, this needs to happen before cache
460-
460+
461461
var tokenAuth = validateJwtToken(token.getCredentials());
462-
462+
463463
return tokenAuth;
464464
}
465465

zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/zosmf/ZosmfService.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,7 @@
6060
import java.io.IOException;
6161
import java.net.MalformedURLException;
6262
import java.net.URL;
63-
import java.util.Collections;
64-
import java.util.EnumMap;
65-
import java.util.HashMap;
66-
import java.util.List;
67-
import java.util.Map;
63+
import java.util.*;
6864

6965
import static org.zowe.apiml.zaas.security.service.zosmf.ZosmfService.TokenType.JWT;
7066
import static org.zowe.apiml.zaas.security.service.zosmf.ZosmfService.TokenType.LTPA;
@@ -487,24 +483,47 @@ public boolean jwtBuilderEndpointExists() {
487483
return meAsProxy.jwtEndpointExists(headers);
488484
}
489485

486+
/**
487+
* Validates jwt token with all available strategies.
488+
*
489+
* @param token
490+
* @return true if at least one validation strategy evaluates token as valid
491+
* @throws ServiceNotAccessibleException if all validation strategies failed because of an error
492+
* @throws TokenNotValidException if all token validation strategies evaluate token as invalid
493+
*/
490494
public boolean validate(String token) {
491495
log.debug("ZosmfService validating token: ....{}", StringUtils.right(token, 15));
492496
TokenValidationRequest request = new TokenValidationRequest(TokenType.JWT, token, getURI(getZosmfServiceId()), getEndpointMap());
493497

498+
var isTokenValid = Optional.<Boolean>empty();
499+
494500
for (TokenValidationStrategy s : tokenValidationStrategy) {
495501
log.debug("Trying to validate token with strategy: {}", s.toString());
496502
try {
497503
s.validate(request);
498504
if (requestIsAuthenticated(request)) {
499505
log.debug("Token validity has been successfully determined: {}", request.getAuthenticated());
500-
return true;
506+
isTokenValid = Optional.of(true);
507+
break;
508+
} else {
509+
isTokenValid = Optional.of(false);
501510
}
502511
} catch (RuntimeException re) {
503512
log.debug("Exception during token validation:", re);
504513
}
505514
}
515+
506516
log.debug("Token validation strategies exhausted, final validation status: {}", request.getAuthenticated());
507-
return false;
517+
518+
if (isTokenValid.isPresent()) {
519+
if (isTokenValid.get()) {
520+
return true;
521+
} else {
522+
throw new TokenNotValidException("Token is not valid by any of zosmf validation strategies");
523+
}
524+
}
525+
526+
throw new ServiceNotAccessibleException("All token validation strategies has failed with " + request.getZosmfBaseUrl());
508527
}
509528

510529
private boolean requestIsAuthenticated(TokenValidationRequest request) {

zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/AuthenticationServiceTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class GivenCorrectInputsTest {
140140
@BeforeEach
141141
void setup() {
142142
stubJWTSecurityForSign();
143-
143+
144144
}
145145

146146
@Test

zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/zosmf/ZosmfServiceTest.java

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -523,33 +523,66 @@ void setUp() {
523523
}
524524

525525
@Test
526-
void givenException_thenHandleExceptions() {
527-
ZosmfService zosmfService = getZosmfServiceWithValidationStrategy(Collections.singletonList(tokenValidationStrategy1));
526+
void givenFirstValidationStrategyFailed_thenSecondSucceeds() {
527+
ZosmfService zosmfService = getZosmfServiceWithValidationStrategy(validationStrategyList);
528528

529529
doThrow(RuntimeException.class).when(tokenValidationStrategy1).validate(any());
530-
assertDoesNotThrow(() -> zosmfService.validate("TOKN"));
530+
doValidate(tokenValidationStrategy2, TokenValidationRequest.STATUS.AUTHENTICATED);
531+
532+
var validationResult = assertDoesNotThrow(() -> zosmfService.validate("TOKN"));
533+
assertTrue(validationResult);
534+
535+
verify(tokenValidationStrategy1, times(1)).validate(any());
536+
verify(tokenValidationStrategy2, times(1)).validate(any());
537+
}
538+
539+
@Test
540+
void givenAllValidationStrategiesFail_thenThrowException() {
541+
ZosmfService zosmfService = getZosmfServiceWithValidationStrategy(validationStrategyList);
542+
543+
doThrow(RuntimeException.class).when(tokenValidationStrategy1).validate(any());
544+
doThrow(RuntimeException.class).when(tokenValidationStrategy2).validate(any());
545+
546+
assertThrows(ServiceNotAccessibleException.class, () -> zosmfService.validate("TOKN"));
547+
548+
verify(tokenValidationStrategy1, times(1)).validate(any());
549+
verify(tokenValidationStrategy2, times(1)).validate(any());
531550
}
532551

552+
@Test
553+
void givenAllValidationStrategiesReturnInvalid_thenReturnFalse() {
554+
ZosmfService zosmfService = getZosmfServiceWithValidationStrategy(validationStrategyList);
555+
556+
doValidate(tokenValidationStrategy1, TokenValidationRequest.STATUS.INVALID);
557+
doValidate(tokenValidationStrategy2, TokenValidationRequest.STATUS.INVALID);
558+
559+
assertThrows(TokenNotValidException.class, () -> zosmfService.validate("TOKN"));
560+
561+
verify(tokenValidationStrategy1, times(1)).validate(any());
562+
verify(tokenValidationStrategy2, times(1)).validate(any());
563+
}
564+
565+
533566
@Test
534567
void givenOneValidationStrategy_thenReturnValidationStrategyResult() {
535568
ZosmfService zosmfService = getZosmfServiceWithValidationStrategy(Collections.singletonList(tokenValidationStrategy1));
536569

537570
//UNKNOWN by default
538-
assertThat(zosmfService.validate("TOKN"), is(false));
571+
assertThrows(TokenNotValidException.class, () -> zosmfService.validate("TOKN"));
539572

540573
doValidate(tokenValidationStrategy1, TokenValidationRequest.STATUS.AUTHENTICATED);
541574

542575
assertThat(zosmfService.validate("TOKN"), is(true));
543576

544577
doValidate(tokenValidationStrategy1, TokenValidationRequest.STATUS.INVALID);
545-
assertThat(zosmfService.validate("TOKN"), is(false));
578+
assertThrows(TokenNotValidException.class, () -> zosmfService.validate("TOKN"));
546579
}
547580

548581
@Test
549582
void givenFirstValidationStrategyAuthentications_thenDontUseSecondValidationStrategy() {
550583
ZosmfService zosmfService = getZosmfServiceWithValidationStrategy(validationStrategyList);
551584

552-
assertThat(zosmfService.validate("TOKN"), is(false));
585+
assertThrows(TokenNotValidException.class, () -> zosmfService.validate("TOKN"));
553586
verify(tokenValidationStrategy1, times(1)).validate(any());
554587
verify(tokenValidationStrategy2, times(1)).validate(any());
555588

@@ -571,19 +604,10 @@ void givenFirstStrategyInvalidAndSecondValid_thenTokenIsValid() {
571604
verify(tokenValidationStrategy2, times(1)).validate(any());
572605
}
573606

574-
@Test
575-
void doesNotRethrowExceptionsFromValidationStrategies() {
576-
ZosmfService zosmfService = getZosmfServiceWithValidationStrategy(Collections.singletonList(tokenValidationStrategy1));
577-
TokenValidationRequest request = mock(TokenValidationRequest.class);
578-
579-
lenient().doThrow(RuntimeException.class).when(tokenValidationStrategy1).validate(request);
580-
assertDoesNotThrow(() -> zosmfService.validate("TOKN"));
581-
}
582-
583607
@Test
584608
void suppliesValidationRequestWithVerifiedEndpointsList() {
585609
ZosmfService zosmfService = getZosmfServiceWithValidationStrategy(validationStrategyList);
586-
zosmfService.validate("TOKN");
610+
assertThrows(TokenNotValidException.class, () -> zosmfService.validate("TOKN"));
587611
verify(tokenValidationStrategy1).validate(argThat(request -> !request.getEndpointExistenceMap().isEmpty()));
588612
}
589613

0 commit comments

Comments
 (0)