Skip to content

Commit

Permalink
fix: immediately expires passticket command (#2496)
Browse files Browse the repository at this point in the history
* immediately expires passticket command, so it generates fresh passticket for each call

Signed-off-by: achmelo <[email protected]>

* remove obsolete tests

Signed-off-by: achmelo <[email protected]>

* add comment, remove passticket timeout parameter from conf

Signed-off-by: achmelo <[email protected]>
  • Loading branch information
achmelo authored Jul 14, 2022
1 parent 4421527 commit 8adca78
Show file tree
Hide file tree
Showing 9 changed files with 6 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ public class AuthConfigurationProperties {

private String provider = "zosmf";

private AuthConfigurationProperties.PassTicket passTicket;
private AuthConfigurationProperties.X509Cert x509Cert;

private AuthConfigurationProperties.Zosmf zosmf = new AuthConfigurationProperties.Zosmf();
Expand Down Expand Up @@ -88,11 +87,6 @@ public static class CookieProperties {
private SameSiteCookies cookieSameSite = SameSiteCookies.STRICT;
}

@Data
public static class PassTicket {
private Integer timeout = 540;
}

@Data
public static class X509Cert {
private Integer timeout = 15 * 60;
Expand All @@ -108,7 +102,6 @@ public static class Zosmf {
public AuthConfigurationProperties() {
this.cookieProperties = new AuthConfigurationProperties.CookieProperties();
this.tokenProperties = new AuthConfigurationProperties.TokenProperties();
this.passTicket = new AuthConfigurationProperties.PassTicket();
this.x509Cert = new AuthConfigurationProperties.X509Cert();
}

Expand Down
2 changes: 0 additions & 2 deletions config/docker/gateway-service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ apiml:
auth:
zosmf:
serviceId: mockzosmf # Replace me with the correct z/OSMF service id
passTicket:
timeout: 360 # [s] - default timeout to expire (z/OS has 10 mins as default)
ssl:
verifySslCertificatesOfServices: true
x509:
Expand Down
2 changes: 0 additions & 2 deletions config/local-multi/gateway-service-1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ apiml:
provider: zosmf
zosmf:
serviceId: mockzosmf # Replace me with the correct z/OSMF service id
passTicket:
timeout: 360 # [s] - default timeout to expire (z/OS has 10 mins as default)
ssl:
verifySslCertificatesOfServices: true
x509:
Expand Down
2 changes: 0 additions & 2 deletions config/local-multi/gateway-service-2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ apiml:
provider: zosmf
zosmf:
serviceId: mockzosmf # Replace me with the correct z/OSMF service id
passTicket:
timeout: 360 # [s] - default timeout to expire (z/OS has 10 mins as default)
ssl:
verifySslCertificatesOfServices: true
x509:
Expand Down
2 changes: 0 additions & 2 deletions config/local/gateway-service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ apiml:
provider: zosmf
zosmf:
serviceId: mockzosmf # Replace me with the correct z/OSMF service id
passTicket:
timeout: 360 # [s] - default timeout to expire (z/OS has 10 mins as default)
ssl:
verifySslCertificatesOfServices: true
x509:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,27 @@

import com.netflix.appinfo.InstanceInfo;
import com.netflix.zuul.context.RequestContext;
import java.util.Optional;
import lombok.EqualsAndHashCode;
import lombok.Value;
import org.apache.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.zowe.apiml.auth.Authentication;
import org.zowe.apiml.auth.AuthenticationScheme;
import org.zowe.apiml.gateway.security.service.schema.source.AuthSchemeException;
import org.zowe.apiml.gateway.security.service.schema.source.AuthSource;
import org.zowe.apiml.gateway.security.service.schema.source.AuthSourceService;
import org.zowe.apiml.message.core.MessageType;
import org.zowe.apiml.message.log.ApimlLogger;
import org.zowe.apiml.passticket.IRRPassTicketGenerationException;
import org.zowe.apiml.passticket.PassTicketService;
import org.zowe.apiml.auth.Authentication;
import org.zowe.apiml.auth.AuthenticationScheme;
import org.zowe.apiml.product.logging.annotations.InjectApimlLogger;
import org.zowe.apiml.security.common.config.AuthConfigurationProperties;
import org.zowe.apiml.security.common.token.TokenExpireException;
import org.zowe.apiml.security.common.token.TokenNotValidException;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Optional;

/**
* This bean support PassTicket. Bean is responsible for getting PassTicket from
Expand All @@ -44,7 +44,6 @@ public class HttpBasicPassTicketScheme implements IAuthenticationScheme {

private final PassTicketService passTicketService;
private final AuthSourceService authSourceService;
private final AuthConfigurationProperties authConfigurationProperties;
private final String cookieName;

public HttpBasicPassTicketScheme(
Expand All @@ -54,7 +53,6 @@ public HttpBasicPassTicketScheme(
) {
this.passTicketService = passTicketService;
this.authSourceService = authSourceService;
this.authConfigurationProperties = authConfigurationProperties;
cookieName = authConfigurationProperties.getCookieProperties().getCookieName();
}

Expand All @@ -65,7 +63,6 @@ public AuthenticationScheme getScheme() {

@Override
public AuthenticationCommand createCommand(Authentication authentication, AuthSource authSource) {
final long before = System.currentTimeMillis();

if (authSource == null || authSource.getRawSource() == null) {
throw new AuthSchemeException("org.zowe.apiml.gateway.security.schema.missingAuthentication");
Expand Down Expand Up @@ -103,12 +100,9 @@ public AuthenticationCommand createCommand(Authentication authentication, AuthSo
final String encoded = Base64.getEncoder()
.encodeToString((userId + ":" + passTicket).getBytes(StandardCharsets.UTF_8));
final String value = "Basic " + encoded;

final long defaultExpirationTime = before + authConfigurationProperties.getPassTicket().getTimeout() * 1000L;
final long expirationTime = parsedAuthSource.getExpiration() != null ? parsedAuthSource.getExpiration().getTime() : defaultExpirationTime;
final Long expireAt = Math.min(defaultExpirationTime, expirationTime);

return new PassTicketCommand(value, cookieName, expireAt);
// passticket is valid only once, therefore this command needs to expire immediately and each call should generate new passticket
long expiration = System.currentTimeMillis();
return new PassTicketCommand(value, cookieName, expiration);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.util.ReflectionTestUtils;
import org.zowe.apiml.auth.Authentication;
import org.zowe.apiml.auth.AuthenticationScheme;
import org.zowe.apiml.gateway.security.service.schema.source.*;
Expand Down Expand Up @@ -133,16 +132,6 @@ void testCreateCommand() {
class ExpirationTest {
AuthenticationCommand ac;

@Test
void whenJwtExpired_thenCommandExpired() {
// JWT token expired one minute ago (command expired also if JWT token expired)
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, -1);
AuthSource.Parsed parsedSource = new JwtAuthSource.Parsed(USERNAME, calendar.getTime(), calendar.getTime(), AuthSource.Origin.ZOWE);
when(authSourceService.parse(jwtAuthSource)).thenReturn(parsedSource);
ac = httpBasicPassTicketScheme.createCommand(authentication, jwtAuthSource);
assertTrue(ac.isExpired());
}

@Test
void whenJwtExpireSoon_thenCommandInNotExpiredYet() {
Expand All @@ -154,20 +143,6 @@ void whenJwtExpireSoon_thenCommandInNotExpiredYet() {
ac = httpBasicPassTicketScheme.createCommand(authentication, jwtAuthSource);
assertFalse(ac.isExpired());
}

@Test
void testPassticketTimeout() {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 100);
AuthSource.Parsed parsedSource4 = new JwtAuthSource.Parsed(USERNAME, calendar.getTime(), calendar.getTime(), AuthSource.Origin.ZOWE);
when(authSourceService.parse(jwtAuthSource)).thenReturn(parsedSource4);
ac = httpBasicPassTicketScheme.createCommand(authentication, jwtAuthSource);

calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, authConfigurationProperties.getPassTicket().getTimeout());
// checking setup of expired time, JWT expired in future (more than hour), check if set date is similar to passticket timeout (5s)
assertEquals(0.0, Math.abs(calendar.getTime().getTime() - (long) ReflectionTestUtils.getField(ac, "expireAt")), 10.0);
}
}

@Nested
Expand Down
2 changes: 0 additions & 2 deletions gateway-service/src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ apiml:
provider: dummy
zosmf:
serviceId: zosmf # Replace me with the correct z/OSMF service id
passTicket:
timeout: 360 # [s] - default timeout to expire (z/OS has 10 mins as default)
zosmf:
useJwtToken: true # if true and z/OSMF returns JWT token use it, otherwise create Zowe JWT token with LTPA token from z/OSMF, default is true
saf:
Expand Down
2 changes: 0 additions & 2 deletions gateway-service/src/test/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ apiml:
zosmf:
serviceId: zosmf # Replace me with the correct z/OSMF service id
jwtAutoconfiguration: jwt
passTicket:
timeout: 360 # [s] - default timeout to expire (z/OS has 10 mins as default)
saf:
provider: rest
urls:
Expand Down

0 comments on commit 8adca78

Please sign in to comment.