NIFI-9322 Refactored OIDC and SAML Access Resources

- Removed parent AccessResource from OIDCAccessResource and SAMLAccessResource to avoid unexpected inherited methods
- Moved Token Expiration validation from AccessResource to StandardBearerTokenProvider

Signed-off-by: Nathan Gough <thenatog@gmail.com>

This closes #5489.
This commit is contained in:
exceptionfactory 2021-10-27 15:16:18 -05:00 committed by Nathan Gough
parent 28cd5d1300
commit 9865ea2bfb
6 changed files with 156 additions and 78 deletions

View File

@ -106,7 +106,7 @@ public class AccessResource extends ApplicationResource {
private BearerTokenResolver bearerTokenResolver;
private KnoxService knoxService;
private KerberosService kerberosService;
protected LogoutRequestManager logoutRequestManager;
private LogoutRequestManager logoutRequestManager;
/**
* Retrieves the access configuration for this NiFi.
@ -348,8 +348,7 @@ public class AccessResource extends ApplicationResource {
final String expirationFromProperties = properties.getKerberosAuthenticationExpiration();
long expiration = Math.round(FormatUtils.getPreciseTimeDuration(expirationFromProperties, TimeUnit.MILLISECONDS));
final String rawIdentity = authentication.getName();
String mappedIdentity = IdentityMappingUtil.mapIdentity(rawIdentity, IdentityMappingUtil.getIdentityMappings(properties));
expiration = validateTokenExpiration(expiration, mappedIdentity);
final String mappedIdentity = IdentityMappingUtil.mapIdentity(rawIdentity, IdentityMappingUtil.getIdentityMappings(properties));
final LoginAuthenticationToken loginAuthenticationToken = new LoginAuthenticationToken(mappedIdentity, expiration, "KerberosService");
final String token = bearerTokenProvider.getBearerToken(loginAuthenticationToken);
@ -416,8 +415,8 @@ public class AccessResource extends ApplicationResource {
// attempt to authenticate
final AuthenticationResponse authenticationResponse = loginIdentityProvider.authenticate(new LoginCredentials(username, password));
final String rawIdentity = authenticationResponse.getIdentity();
String mappedIdentity = IdentityMappingUtil.mapIdentity(rawIdentity, IdentityMappingUtil.getIdentityMappings(properties));
long expiration = validateTokenExpiration(authenticationResponse.getExpiration(), mappedIdentity);
final String mappedIdentity = IdentityMappingUtil.mapIdentity(rawIdentity, IdentityMappingUtil.getIdentityMappings(properties));
final long expiration = authenticationResponse.getExpiration();
// create the authentication token
loginAuthenticationToken = new LoginAuthenticationToken(mappedIdentity, expiration, authenticationResponse.getIssuer());
@ -506,7 +505,7 @@ public class AccessResource extends ApplicationResource {
httpServletResponse.sendRedirect(getNiFiLogoutCompleteUri());
}
LogoutRequest completeLogoutRequest(final HttpServletResponse httpServletResponse) {
private LogoutRequest completeLogoutRequest(final HttpServletResponse httpServletResponse) {
LogoutRequest logoutRequest = null;
final Optional<String> cookieValue = getLogoutRequestIdentifier();
@ -522,24 +521,7 @@ public class AccessResource extends ApplicationResource {
return logoutRequest;
}
long validateTokenExpiration(long proposedTokenExpiration, String identity) {
final long maxExpiration = TimeUnit.MILLISECONDS.convert(12, TimeUnit.HOURS);
final long minExpiration = TimeUnit.MILLISECONDS.convert(1, TimeUnit.MINUTES);
if (proposedTokenExpiration > maxExpiration) {
logger.warn(String.format("Max token expiration exceeded. Setting expiration to %s from %s for %s", maxExpiration,
proposedTokenExpiration, identity));
proposedTokenExpiration = maxExpiration;
} else if (proposedTokenExpiration < minExpiration) {
logger.warn(String.format("Min token expiration not met. Setting expiration to %s from %s for %s", minExpiration,
proposedTokenExpiration, identity));
proposedTokenExpiration = minExpiration;
}
return proposedTokenExpiration;
}
String getNiFiLogoutCompleteUri() {
private String getNiFiLogoutCompleteUri() {
return getNiFiUri() + "logout-complete";
}
@ -548,7 +530,7 @@ public class AccessResource extends ApplicationResource {
*
* @param httpServletResponse HTTP Servlet Response
*/
protected void removeLogoutRequestCookie(final HttpServletResponse httpServletResponse) {
private void removeLogoutRequestCookie(final HttpServletResponse httpServletResponse) {
applicationCookieService.removeCookie(getCookieResourceUri(), httpServletResponse, ApplicationCookieName.LOGOUT_REQUEST_IDENTIFIER);
}
@ -557,7 +539,7 @@ public class AccessResource extends ApplicationResource {
*
* @return Optional Logout Request Identifier
*/
protected Optional<String> getLogoutRequestIdentifier() {
private Optional<String> getLogoutRequestIdentifier() {
return applicationCookieService.getCookieValue(httpServletRequest, ApplicationCookieName.LOGOUT_REQUEST_IDENTIFIER);
}

View File

@ -74,7 +74,7 @@ import java.util.regex.Pattern;
value = OIDCEndpoints.OIDC_ACCESS_ROOT,
description = "Endpoints for obtaining an access token or checking access status."
)
public class OIDCAccessResource extends AccessResource {
public class OIDCAccessResource extends ApplicationResource {
private static final Logger logger = LoggerFactory.getLogger(OIDCAccessResource.class);
private static final String OIDC_ID_TOKEN_AUTHN_ERROR = "Unable to exchange authorization for ID token: ";
@ -115,7 +115,7 @@ public class OIDCAccessResource extends AccessResource {
public void oidcRequest(@Context HttpServletRequest httpServletRequest, @Context HttpServletResponse httpServletResponse) throws Exception {
// only consider user specific access over https
if (!httpServletRequest.isSecure()) {
forwardToLoginMessagePage(httpServletRequest, httpServletResponse, AUTHENTICATION_NOT_ENABLED_MSG);
forwardToLoginMessagePage(httpServletRequest, httpServletResponse, AccessResource.AUTHENTICATION_NOT_ENABLED_MSG);
return;
}
@ -199,7 +199,7 @@ public class OIDCAccessResource extends AccessResource {
public Response oidcExchange(@Context HttpServletRequest httpServletRequest, @Context HttpServletResponse httpServletResponse) {
// only consider user specific access over https
if (!httpServletRequest.isSecure()) {
throw new AuthenticationNotSupportedException(AUTHENTICATION_NOT_ENABLED_MSG);
throw new AuthenticationNotSupportedException(AccessResource.AUTHENTICATION_NOT_ENABLED_MSG);
}
// ensure oidc is enabled
@ -238,7 +238,7 @@ public class OIDCAccessResource extends AccessResource {
)
public void oidcLogout(@Context HttpServletRequest httpServletRequest, @Context HttpServletResponse httpServletResponse) throws Exception {
if (!httpServletRequest.isSecure()) {
throw new IllegalStateException(AUTHENTICATION_NOT_ENABLED_MSG);
throw new IllegalStateException(AccessResource.AUTHENTICATION_NOT_ENABLED_MSG);
}
if (!oidcService.isOidcEnabled()) {
@ -468,7 +468,7 @@ public class OIDCAccessResource extends AccessResource {
// only consider user specific access over https
if (!httpServletRequest.isSecure()) {
forwardToMessagePage(httpServletRequest, httpServletResponse, pageTitle, AUTHENTICATION_NOT_ENABLED_MSG);
forwardToMessagePage(httpServletRequest, httpServletResponse, pageTitle, AccessResource.AUTHENTICATION_NOT_ENABLED_MSG);
return null;
}

View File

@ -27,6 +27,7 @@ import org.apache.nifi.idp.IdpType;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.api.cookie.ApplicationCookieName;
import org.apache.nifi.web.security.logout.LogoutRequest;
import org.apache.nifi.web.security.logout.LogoutRequestManager;
import org.apache.nifi.web.security.saml.SAMLCredentialStore;
import org.apache.nifi.web.security.saml.SAMLEndpoints;
import org.apache.nifi.web.security.saml.SAMLService;
@ -61,7 +62,7 @@ import java.util.stream.Collectors;
value = SAMLEndpoints.SAML_ACCESS_ROOT,
description = "Endpoints for authenticating, obtaining an access token or logging out of a configured SAML authentication provider."
)
public class SAMLAccessResource extends AccessResource {
public class SAMLAccessResource extends ApplicationResource {
private static final Logger logger = LoggerFactory.getLogger(SAMLAccessResource.class);
private static final String SAML_METADATA_MEDIA_TYPE = "application/samlmetadata+xml";
@ -73,6 +74,7 @@ public class SAMLAccessResource extends AccessResource {
private SAMLStateManager samlStateManager;
private SAMLCredentialStore samlCredentialStore;
private IdpUserGroupService idpUserGroupService;
private LogoutRequestManager logoutRequestManager;
@GET
@Consumes(MediaType.WILDCARD)
@ -85,7 +87,7 @@ public class SAMLAccessResource extends AccessResource {
public Response samlMetadata(@Context HttpServletRequest httpServletRequest, @Context HttpServletResponse httpServletResponse) {
// only consider user specific access over https
if (!httpServletRequest.isSecure()) {
throw new AuthenticationNotSupportedException(AUTHENTICATION_NOT_ENABLED_MSG);
throw new AuthenticationNotSupportedException(AccessResource.AUTHENTICATION_NOT_ENABLED_MSG);
}
// ensure saml is enabled
@ -212,7 +214,7 @@ public class SAMLAccessResource extends AccessResource {
// create the login token
final String rawIdentity = samlService.getUserIdentity(samlCredential);
final String mappedIdentity = IdentityMappingUtil.mapIdentity(rawIdentity, IdentityMappingUtil.getIdentityMappings(properties));
final long expiration = validateTokenExpiration(samlService.getAuthExpiration(), mappedIdentity);
final long expiration = samlService.getAuthExpiration();
final String issuer = samlCredential.getRemoteEntityID();
final LoginAuthenticationToken loginToken = new LoginAuthenticationToken(mappedIdentity, mappedIdentity, expiration, issuer);
@ -255,7 +257,7 @@ public class SAMLAccessResource extends AccessResource {
// only consider user specific access over https
if (!httpServletRequest.isSecure()) {
throw new AuthenticationNotSupportedException(AUTHENTICATION_NOT_ENABLED_MSG);
throw new AuthenticationNotSupportedException(AccessResource.AUTHENTICATION_NOT_ENABLED_MSG);
}
// ensure saml is enabled
@ -446,19 +448,21 @@ public class SAMLAccessResource extends AccessResource {
assert(isSamlEnabled(httpServletRequest, httpServletResponse, !LOGGING_IN));
// complete the logout request if one exists
final LogoutRequest completedLogoutRequest = completeLogoutRequest(httpServletResponse);
final Optional<String> cookieValue = getLogoutRequestIdentifier();
if (cookieValue.isPresent()) {
final String logoutRequestIdentifier = cookieValue.get();
final LogoutRequest logoutRequest = logoutRequestManager.complete(logoutRequestIdentifier);
// if a logout request was completed, then delete the stored SAMLCredential for that user
if (completedLogoutRequest != null) {
final String userIdentity = completedLogoutRequest.getMappedUserIdentity();
final String mappedUserIdentity = logoutRequest.getMappedUserIdentity();
samlCredentialStore.delete(mappedUserIdentity);
idpUserGroupService.deleteUserGroups(mappedUserIdentity);
logger.info("Removing cached SAML information for " + userIdentity);
samlCredentialStore.delete(userIdentity);
logger.info("Removing cached SAML Groups for " + userIdentity);
idpUserGroupService.deleteUserGroups(userIdentity);
logger.info("Logout Request [{}] Identity [{}] SAML Local Logout Completed", logoutRequestIdentifier, mappedUserIdentity);
} else {
logger.warn("Logout Request Cookie [{}] not found", ApplicationCookieName.LOGOUT_REQUEST_IDENTIFIER.getCookieName());
}
removeLogoutRequestCookie(httpServletResponse);
// redirect to logout landing page
httpServletResponse.sendRedirect(getNiFiLogoutCompleteUri());
}
@ -488,7 +492,7 @@ public class SAMLAccessResource extends AccessResource {
// only consider user specific access over https
if (!httpServletRequest.isSecure()) {
forwardToMessagePage(httpServletRequest, httpServletResponse, pageTitle, AUTHENTICATION_NOT_ENABLED_MSG);
forwardToMessagePage(httpServletRequest, httpServletResponse, pageTitle, AccessResource.AUTHENTICATION_NOT_ENABLED_MSG);
return false;
}
@ -508,6 +512,18 @@ public class SAMLAccessResource extends AccessResource {
return applicationCookieService.getCookieValue(httpServletRequest, ApplicationCookieName.SAML_REQUEST_IDENTIFIER);
}
private void removeLogoutRequestCookie(final HttpServletResponse httpServletResponse) {
applicationCookieService.removeCookie(getCookieResourceUri(), httpServletResponse, ApplicationCookieName.LOGOUT_REQUEST_IDENTIFIER);
}
private Optional<String> getLogoutRequestIdentifier() {
return applicationCookieService.getCookieValue(httpServletRequest, ApplicationCookieName.LOGOUT_REQUEST_IDENTIFIER);
}
private String getNiFiLogoutCompleteUri() {
return getNiFiUri() + "logout-complete";
}
public void setSamlService(SAMLService samlService) {
this.samlService = samlService;
}
@ -531,4 +547,8 @@ public class SAMLAccessResource extends AccessResource {
protected NiFiProperties getProperties() {
return properties;
}
public void setLogoutRequestManager(LogoutRequestManager logoutRequestManager) {
this.logoutRequestManager = logoutRequestManager;
}
}

View File

@ -32,6 +32,8 @@ import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;
@ -44,6 +46,10 @@ public class StandardBearerTokenProvider implements BearerTokenProvider {
private static final String URL_ENCODED_CHARACTER_SET = StandardCharsets.UTF_8.name();
private static final Duration MAXIMUM_EXPIRATION = Duration.ofHours(12);
private static final Duration MINIMUM_EXPIRATION = Duration.ofMinutes(1);
private final JwsSignerProvider jwsSignerProvider;
public StandardBearerTokenProvider(final JwsSignerProvider jwsSignerProvider) {
@ -64,7 +70,7 @@ public class StandardBearerTokenProvider implements BearerTokenProvider {
final String issuer = getUrlEncoded(loginAuthenticationToken.getIssuer());
final Date now = new Date();
final Date expirationTime = new Date(loginAuthenticationToken.getExpiration());
final Date expirationTime = getExpirationTime(loginAuthenticationToken);
final JWTClaimsSet claims = new JWTClaimsSet.Builder()
.jwtID(UUID.randomUUID().toString())
.subject(subject)
@ -78,6 +84,24 @@ public class StandardBearerTokenProvider implements BearerTokenProvider {
return getSignedBearerToken(claims);
}
private Date getExpirationTime(final LoginAuthenticationToken loginAuthenticationToken) {
Instant expiration = Instant.ofEpochMilli(loginAuthenticationToken.getExpiration());
final Instant maximumExpiration = Instant.now().plus(MAXIMUM_EXPIRATION);
final Instant minimumExpiration = Instant.now().plus(MINIMUM_EXPIRATION);
final String identity = loginAuthenticationToken.getName();
if (expiration.isAfter(maximumExpiration)) {
LOGGER.warn("Identity [{}] Token Expiration [{}] greater than maximum [{}]", identity, expiration, MAXIMUM_EXPIRATION);
expiration = maximumExpiration;
} else if (expiration.isBefore(minimumExpiration)) {
LOGGER.warn("Identity [{}] Token Expiration [{}] less than minimum [{}]", identity, expiration, MINIMUM_EXPIRATION);
expiration = minimumExpiration;
}
return Date.from(expiration);
}
private String getSignedBearerToken(final JWTClaimsSet claims) {
final Date expirationTime = claims.getExpirationTime();
final JwsSignerContainer jwsSignerContainer = jwsSignerProvider.getJwsSignerContainer(expirationTime.toInstant());

View File

@ -19,8 +19,7 @@ package org.apache.nifi.web.security.token;
import org.apache.nifi.security.util.CertificateUtils;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.time.Instant;
/**
* This is an Authentication Token for logging in. Once a user is authenticated, they can be issued an ID token.
@ -57,8 +56,7 @@ public class LoginAuthenticationToken extends AbstractAuthenticationToken {
this.identity = identity;
this.username = username;
this.issuer = issuer;
Calendar now = Calendar.getInstance();
this.expiration = now.getTimeInMillis() + expiration;
this.expiration = Instant.now().plusMillis(expiration).toEpochMilli();
}
@Override
@ -98,20 +96,15 @@ public class LoginAuthenticationToken extends AbstractAuthenticationToken {
@Override
public String toString() {
Calendar expirationTime = Calendar.getInstance();
expirationTime.setTimeInMillis(getExpiration());
long remainingTime = expirationTime.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS");
dateFormat.setTimeZone(expirationTime.getTimeZone());
String expirationTimeString = dateFormat.format(expirationTime.getTime());
final Instant expirationTime = Instant.ofEpochMilli(expiration);
long remainingTime = expirationTime.toEpochMilli() - Instant.now().toEpochMilli();
return new StringBuilder("LoginAuthenticationToken for ")
.append(getName())
.append(" issued by ")
.append(getIssuer())
.append(" expiring at ")
.append(expirationTimeString)
.append(expirationTime)
.append(" [")
.append(getExpiration())
.append(" ms, ")

View File

@ -27,34 +27,41 @@ import com.nimbusds.jwt.SignedJWT;
import org.apache.nifi.web.security.jwt.jws.JwsSignerContainer;
import org.apache.nifi.web.security.jwt.jws.JwsSignerProvider;
import org.apache.nifi.web.security.token.LoginAuthenticationToken;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.junit.jupiter.MockitoExtension;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.Date;
import java.util.UUID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
@ExtendWith(MockitoExtension.class)
public class StandardBearerTokenProviderTest {
private static final String USERNAME = "USERNAME";
private static final String IDENTITY = "IDENTITY";
private static final long EXPIRATION = 60;
private static final Duration EXPIRATION = Duration.ofHours(1);
private static final Duration MAXIMUM_DURATION_EXCEEDED = Duration.parse("PT12H5M");
private static final Duration MINIMUM_DURATION_EXCEEDED = Duration.parse("PT30S");
private static final String ISSUER = "ISSUER";
@ -73,7 +80,7 @@ public class StandardBearerTokenProviderTest {
private JWSSigner jwsSigner;
@Before
@BeforeEach
public void setProvider() throws NoSuchAlgorithmException {
provider = new StandardBearerTokenProvider(jwsSignerProvider);
@ -86,24 +93,76 @@ public class StandardBearerTokenProviderTest {
@Test
public void testGetBearerToken() throws ParseException, JOSEException {
final LoginAuthenticationToken loginAuthenticationToken = new LoginAuthenticationToken(IDENTITY, USERNAME, EXPIRATION, ISSUER);
final String keyIdentifier = UUID.randomUUID().toString();
final JwsSignerContainer jwsSignerContainer = new JwsSignerContainer(keyIdentifier, JWS_ALGORITHM, jwsSigner);
when(jwsSignerProvider.getJwsSignerContainer(isA(Instant.class))).thenReturn(jwsSignerContainer);
final LoginAuthenticationToken loginAuthenticationToken = new LoginAuthenticationToken(IDENTITY, USERNAME, EXPIRATION.toMillis(), ISSUER);
setSignerProvider();
final String bearerToken = provider.getBearerToken(loginAuthenticationToken);
final SignedJWT signedJwt = SignedJWT.parse(bearerToken);
assertTrue("Verification Failed", signedJwt.verify(jwsVerifier));
final SignedJWT signedJwt = assertTokenVerified(bearerToken);
final JWTClaimsSet claims = signedJwt.getJWTClaimsSet();
assertNotNull("Issue Time not found", claims.getIssueTime());
assertNotNull("Not Before Time Time not found", claims.getNotBeforeTime());
assertNotNull("Expiration Time Time not found", claims.getExpirationTime());
assertNotNull(claims.getIssueTime(), "Issue Time not found");
assertNotNull(claims.getNotBeforeTime(), "Not Before Time not found");
final Date claimExpirationTime = claims.getExpirationTime();
assertNotNull(claimExpirationTime, "Expiration Time not found");
final Date loginExpirationTime = new Date(loginAuthenticationToken.getExpiration());
assertEquals(loginExpirationTime.toString(), claimExpirationTime.toString(), "Expiration Time not matched");
assertEquals(ISSUER, claims.getIssuer());
assertEquals(Collections.singletonList(ISSUER), claims.getAudience());
assertEquals(IDENTITY, claims.getSubject());
assertEquals(USERNAME, claims.getClaim(SupportedClaim.PREFERRED_USERNAME.getClaim()));
assertNotNull("JSON Web Token Identifier not found", claims.getJWTID());
}
@Test
public void testGetBearerTokenExpirationMaximum() throws ParseException, JOSEException {
final long expiration = MAXIMUM_DURATION_EXCEEDED.toMillis();
final LoginAuthenticationToken loginAuthenticationToken = new LoginAuthenticationToken(IDENTITY, USERNAME, expiration, ISSUER);
setSignerProvider();
final String bearerToken = provider.getBearerToken(loginAuthenticationToken);
final SignedJWT signedJwt = assertTokenVerified(bearerToken);
final JWTClaimsSet claims = signedJwt.getJWTClaimsSet();
final Date claimExpirationTime = claims.getExpirationTime();
assertNotNull(claimExpirationTime, "Expiration Time not found");
final Date loginExpirationTime = new Date(loginAuthenticationToken.getExpiration());
assertNotSame(loginExpirationTime.toString(), claimExpirationTime.toString(), "Expiration Time matched");
assertTrue(claimExpirationTime.toInstant().isBefore(loginExpirationTime.toInstant()), "Claim Expiration after Login Expiration");
}
@Test
public void testGetBearerTokenExpirationMinimum() throws ParseException, JOSEException {
final long expiration = MINIMUM_DURATION_EXCEEDED.toMillis();
final LoginAuthenticationToken loginAuthenticationToken = new LoginAuthenticationToken(IDENTITY, USERNAME, expiration, ISSUER);
setSignerProvider();
final String bearerToken = provider.getBearerToken(loginAuthenticationToken);
final SignedJWT signedJwt = assertTokenVerified(bearerToken);
final JWTClaimsSet claims = signedJwt.getJWTClaimsSet();
final Date claimExpirationTime = claims.getExpirationTime();
assertNotNull(claimExpirationTime, "Expiration Time not found");
final Date loginExpirationTime = new Date(loginAuthenticationToken.getExpiration());
assertNotSame(loginExpirationTime.toString(), claimExpirationTime.toString(), "Expiration Time matched");
assertTrue(claimExpirationTime.toInstant().isAfter(loginExpirationTime.toInstant()), "Claim Expiration before Login Expiration");
}
private void setSignerProvider() {
final String keyIdentifier = UUID.randomUUID().toString();
final JwsSignerContainer jwsSignerContainer = new JwsSignerContainer(keyIdentifier, JWS_ALGORITHM, jwsSigner);
when(jwsSignerProvider.getJwsSignerContainer(isA(Instant.class))).thenReturn(jwsSignerContainer);
}
private SignedJWT assertTokenVerified(final String bearerToken) throws ParseException, JOSEException {
final SignedJWT signedJwt = SignedJWT.parse(bearerToken);
assertTrue(signedJwt.verify(jwsVerifier), "Verification Failed");
return signedJwt;
}
}