Skip to content

Commit

Permalink
feat: zowe jwt from x509 (#2245)
Browse files Browse the repository at this point in the history
* zowe jwt

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

* translate x509 into zoweJWT

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

* update header after LB

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

* integration tests for zowejwtscheme

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

* fix tests

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

* run when zosmf auth tests

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

* hostname

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

* cleanup

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

* common string

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

* get JWT in create command

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

* send empty header in case of missing auth in request

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

* return empty command

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

* translate all exceptions from createTokenWithoutCreds into custom so it can be propagated with zuul exception

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

* use header to inform about transformation failure

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

* styles

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

* custom exception, code smells

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

* override default method

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

* documentation, mark applyToRequest as deprecated

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

* return failure header to client

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

* inform about invalid token

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

* higher timeout

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

* higher timeout all container tests

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

* remove cookie and add error header if token is expired

Signed-off-by: achmelo <[email protected]>
  • Loading branch information
achmelo authored Apr 4, 2022
1 parent 90fa300 commit aedbbda
Show file tree
Hide file tree
Showing 16 changed files with 591 additions and 83 deletions.
32 changes: 16 additions & 16 deletions .github/workflows/containers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
needs: PublishJibContainers
runs-on: ubuntu-latest
container: ubuntu:latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -82,7 +82,7 @@ jobs:
needs: PublishJibContainers
runs-on: ubuntu-latest
container: ubuntu:latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -128,7 +128,7 @@ jobs:
needs: PublishJibContainers
runs-on: ubuntu-latest
container: ubuntu:latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -180,7 +180,7 @@ jobs:
needs: PublishJibContainers
runs-on: ubuntu-latest
container: ubuntu:latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -228,7 +228,7 @@ jobs:
needs: PublishJibContainers
runs-on: ubuntu-latest
container: ubuntu:latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -277,7 +277,7 @@ jobs:
needs: PublishJibContainers
runs-on: ubuntu-latest
container: ubuntu:latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -325,7 +325,7 @@ jobs:
needs: PublishJibContainers
runs-on: ubuntu-latest
container: ubuntu:latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -377,7 +377,7 @@ jobs:
needs: PublishJibContainers
runs-on: ubuntu-latest
container: ubuntu:latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -441,7 +441,7 @@ jobs:
needs: PublishJibContainers
runs-on: ubuntu-latest
container: ubuntu:latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -507,7 +507,7 @@ jobs:
needs: PublishJibContainers
container: ubuntu:latest
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -586,7 +586,7 @@ jobs:
needs: PublishJibContainers
container: ubuntu:latest
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -682,7 +682,7 @@ jobs:
needs: PublishJibContainers
container: ubuntu:latest
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -753,7 +753,7 @@ jobs:
needs: PublishJibContainers
container: ubuntu:latest
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -824,7 +824,7 @@ jobs:
needs: PublishJibContainers
container: ubuntu:latest
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -899,7 +899,7 @@ jobs:
needs: PublishJibContainers
container: ubuntu:latest
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down Expand Up @@ -974,7 +974,7 @@ jobs:
needs: PublishJibContainers
runs-on: ubuntu-latest
container: ubuntu:latest
timeout-minutes: 10
timeout-minutes: 15

services:
api-catalog-services:
Expand Down
23 changes: 23 additions & 0 deletions config/docker/api-defs/staticclient.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,29 @@ services:
apiml:
okToRetryOnAllOperations: true

- serviceId: zowejwt # unique lowercase ID of the service
catalogUiTileId: static # ID of the API Catalog UI tile (visual grouping of the services)
title: Staticaly Defined Service To Test Zowe JWT scheme # Title of the service in the API catalog
description: Sample to demonstrate how to add an API service without Swagger documentation to API Catalog using a static YAML definition # Description of the service in the API catalog
instanceBaseUrls: # list of base URLs for each instance
- https://discoverable-client:10012/discoverableclient # scheme://hostname:port/contextPath
homePageRelativeUrl: # Normally used for informational purposes for other services to use it as a landing page
statusPageRelativeUrl: /application/info # Appended to the instanceBaseUrl
healthCheckRelativeUrl: /application/health # Appended to the instanceBaseUrl
routes:
- gatewayUrl: api/v1 # [api/ui/ws]/v{majorVersion}
serviceRelativeUrl: /api/v1 # relativePath that is added to baseUrl of an instance
- gatewayUrl: ui/v1
serviceRelativeUrl: /
- gatewayUrl: ws/v1
serviceRelativeUrl: /ws
authentication:
scheme: zoweJwt # This service expects JWT or client cert in HTTP request
apiInfo:
- apiId: zowe.apiml.discoverableclient
gatewayUrl: api/v1
version: 1.0.0

- serviceId: staticclient2 # unique lowercase ID of the service
catalogUiTileId: static # ID of the API Catalog UI tile (visual grouping of the services)
title: Staticaly Defined Service 2 # Title of the service in the API catalog
Expand Down
23 changes: 23 additions & 0 deletions config/local/api-defs/staticclient.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,29 @@ services:
gatewayUrl: api/v1
version: 1.0.0

- serviceId: zowejwt # unique lowercase ID of the service
catalogUiTileId: static # ID of the API Catalog UI tile (visual grouping of the services)
title: Staticaly Defined Service To Test Zowe JWT scheme # Title of the service in the API catalog
description: Sample to demonstrate how to add an API service without Swagger documentation to API Catalog using a static YAML definition # Description of the service in the API catalog
instanceBaseUrls: # list of base URLs for each instance
- https://localhost:10012/discoverableclient # scheme://hostname:port/contextPath
homePageRelativeUrl: # Normally used for informational purposes for other services to use it as a landing page
statusPageRelativeUrl: /application/info # Appended to the instanceBaseUrl
healthCheckRelativeUrl: /application/health # Appended to the instanceBaseUrl
routes:
- gatewayUrl: api/v1 # [api/ui/ws]/v{majorVersion}
serviceRelativeUrl: /api/v1 # relativePath that is added to baseUrl of an instance
- gatewayUrl: ui/v1
serviceRelativeUrl: /
- gatewayUrl: ws/v1
serviceRelativeUrl: /ws
authentication:
scheme: zoweJwt # This service expects JWT or client cert in HTTP request
apiInfo:
- apiId: zowe.apiml.discoverableclient
gatewayUrl: api/v1
version: 1.0.0

- serviceId: dcbypass # unique lowercase ID of the service
catalogUiTileId: static # ID of the API Catalog UI tile (visual grouping of the services)
title: Discoverable client with by pass authentication scheme # Title of the service in the API catalog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,16 @@ public Authentication getAuthentication(String serviceId) {
final List<InstanceInfo> instances = application.getInstances();

Authentication found = null;
// iterates over all instances to verify if they all have the same authentication scheme in registration metadata
for (final InstanceInfo instance : instances) {
final Authentication auth = getAuthentication(instance);

if (found == null) {
// this is the first record
found = auth;
} else if (!found.equals(auth)) {
// if next record is different, authentication cannot be determined before load balancer
// if next record is different, authentication cannot be determined before load balancer and
// will be selected in load balancer with applyToRequest method
return loadBalancerAuthentication;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public boolean isExpired() {
* In that case, the filter applies {@link org.zowe.apiml.gateway.security.service.ServiceAuthenticationServiceImpl.LoadBalancerAuthenticationCommand}
* and defers the processing to happen during Ribbon's Retry.
*/
@Deprecated
public void applyToRequest(HttpRequest request) {
throw new UnsupportedOperationException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright Contributors to the Zowe Project.
*/
package org.zowe.apiml.gateway.security.service.schema;

import com.netflix.zuul.context.RequestContext;
import org.apache.http.HttpRequest;
import org.zowe.apiml.util.CookieUtil;
import org.zowe.apiml.util.Cookies;

import java.net.HttpCookie;

public abstract class JwtCommand extends AuthenticationCommand {

public static final String COOKIE_HEADER = "cookie";
public static final String AUTH_FAIL_HEADER = "X-Zowe-Auth-Failure";

public static void createCookie(Cookies cookies, String name, String token) {
HttpCookie jwtCookie = new HttpCookie(name, token);
jwtCookie.setSecure(true);
jwtCookie.setHttpOnly(true);
jwtCookie.setVersion(0);
cookies.set(jwtCookie);
}

public static void setCookie(RequestContext context, String name, String value) {
context.addZuulRequestHeader(COOKIE_HEADER,
CookieUtil.setCookie(
context.getZuulRequestHeaders().get(COOKIE_HEADER),
name,
value
)
);
}

public static void setErrorHeader(RequestContext context, String value) {
context.addZuulRequestHeader(AUTH_FAIL_HEADER, value);
context.addZuulResponseHeader(AUTH_FAIL_HEADER, value);
}

public static void addErrorHeader(HttpRequest request, String value) {
request.addHeader(AUTH_FAIL_HEADER, value);
}

public static void removeCookie(RequestContext context, String name) {
context.addZuulRequestHeader(COOKIE_HEADER,
CookieUtil.removeCookie(
context.getZuulRequestHeaders().get(COOKIE_HEADER),
name
)
);
}

@Override
public boolean isExpired() {
if (getExpireAt() == null) return false;

return System.currentTimeMillis() > getExpireAt();
}

@Override
public boolean isRequiredValidSource() {
return true;
}

public abstract Long getExpireAt();
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public interface ServiceAuthenticationService extends ServiceCacheEvict {
AuthenticationCommand getAuthenticationCommand(String serviceId, Authentication authentication, AuthSource authSource);

/**
* Get authentication for given InstanceInfo
* Provides information about authentication scheme selected by a service registered in Eureka
* @param instanceInfo InstanceInfo object of service instance, containing the security metadata
* @return Authentication object representing instance's authentication schema
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@
import org.zowe.apiml.gateway.security.service.schema.source.JwtAuthSource;
import org.zowe.apiml.gateway.security.service.zosmf.ZosmfService;
import org.zowe.apiml.security.common.config.AuthConfigurationProperties;
import org.zowe.apiml.util.CookieUtil;
import org.zowe.apiml.util.Cookies;

import java.net.HttpCookie;
import java.util.Date;
import java.util.Optional;

Expand Down Expand Up @@ -68,40 +66,10 @@ public Optional<AuthSource> getAuthSource() {

@lombok.Value
@EqualsAndHashCode(callSuper = false)
public class ZosmfCommand extends AuthenticationCommand {
public class ZosmfCommand extends JwtCommand {

private static final long serialVersionUID = 2284037230674275720L;

public static final String COOKIE_HEADER = "cookie";

private final Long expireAt;

private void createCookie(Cookies cookies, String name, String token) {
HttpCookie jwtCookie = new HttpCookie(name, token);
jwtCookie.setSecure(true);
jwtCookie.setHttpOnly(true);
jwtCookie.setVersion(0);
cookies.set(jwtCookie);
}

private void setCookie(RequestContext context, String name, String value) {
context.addZuulRequestHeader(COOKIE_HEADER,
CookieUtil.setCookie(
context.getZuulRequestHeaders().get(COOKIE_HEADER),
name,
value
)
);
}

private void removeCookie(RequestContext context, String name) {
context.addZuulRequestHeader(COOKIE_HEADER,
CookieUtil.removeCookie(
context.getZuulRequestHeaders().get(COOKIE_HEADER),
name
)
);
}
Long expireAt;

@Override
public void apply(InstanceInfo instanceInfo) {
Expand Down Expand Up @@ -156,18 +124,6 @@ public void applyToRequest(HttpRequest request) {
});
}

@Override
public boolean isExpired() {
if (expireAt == null) return false;

return System.currentTimeMillis() > expireAt;
}

@Override
public boolean isRequiredValidSource() {
return true;
}

}

}
Loading

0 comments on commit aedbbda

Please sign in to comment.