-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
apiml/GH2062/add-x509-auth-source (#2185)
* feat(authentication): introduce x509 authentication source Introduce the object and basic service for a client certificate as source of authentication Signed-off-by: Yelyzaveta Chebanova <[email protected]> * refactor: use dedicated origin of the authentication source instead of QueryResponse.Source Signed-off-by: Yelyzaveta Chebanova <[email protected]> * refactor: improve code coverage Signed-off-by: Yelyzaveta Chebanova <[email protected]> * refactor: resolve licence issue Signed-off-by: Yelyzaveta Chebanova <[email protected]> * feat: Add implementation of AuthSourceService interface to process client certificate authentication Signed-off-by: Yelyzaveta Chebanova <[email protected]> * feat: add JUnits Signed-off-by: Yelyzaveta Chebanova <[email protected]> * feat: return BAD REQUEST (400) when X509 certificate which cannot be used for client authentication is used in authentication scheme Signed-off-by: Yelyzaveta Chebanova <[email protected]> * feat: fix error in acceptance test (ZosmfSchemeTest) Signed-off-by: Yelyzaveta Chebanova <[email protected]> * feat: fix Sonar issues Signed-off-by: Yelyzaveta Chebanova <[email protected]> * feat: define X509 authentication source service as bean in configuration Signed-off-by: Yelyzaveta Chebanova <[email protected]> * rerun Signed-off-by: achmelo <[email protected]> Co-authored-by: achmelo <[email protected]>
- Loading branch information
1 parent
576fd72
commit efd53a8
Showing
21 changed files
with
1,470 additions
and
403 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
.../java/org/zowe/apiml/gateway/security/service/schema/source/DefaultAuthSourceService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/* | ||
* 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.source; | ||
|
||
import java.util.EnumMap; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Qualifier; | ||
import org.springframework.context.annotation.EnableAspectJAutoProxy; | ||
import org.springframework.context.annotation.Primary; | ||
import org.springframework.context.annotation.Scope; | ||
import org.springframework.context.annotation.ScopedProxyMode; | ||
import org.springframework.stereotype.Service; | ||
import org.zowe.apiml.gateway.security.service.schema.source.AuthSource.AuthSourceType; | ||
import org.zowe.apiml.gateway.security.service.schema.source.AuthSource.Parsed; | ||
|
||
/** | ||
* Main implementation of AuthSourceService, supports two types of authentication source - JWT token and client certificate. | ||
* <p> | ||
* Service keeps a map of the specific implementations of {@link AuthSourceService} which are responsible to perform operations defined by an interface | ||
* for a particular authentication source. {@link JwtAuthSourceService} is responsible for processing of the authentication source based on JWT token; | ||
* @Qualifier("x509MFAuthSourceService") {@link X509AuthSourceService} is responsible for processing of the authentication source based on client certificate. | ||
* The key for the map is {@link AuthSourceType}. | ||
*/ | ||
@Slf4j | ||
@Service | ||
@Primary | ||
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS) | ||
@EnableAspectJAutoProxy(proxyTargetClass = true) | ||
public class DefaultAuthSourceService implements AuthSourceService { | ||
private final Map<AuthSourceType, AuthSourceService> map = new EnumMap<>(AuthSourceType.class); | ||
|
||
/** | ||
* Build the map of the specific implementations of {@link AuthSourceService} for processing of different type of authentications | ||
* @param jwtAuthSourceService {@link JwtAuthSourceService} service which process authentication source of type JWT | ||
* @param x509AuthSourceService {@link X509AuthSourceService} service which process authentication source of type client certificate | ||
*/ | ||
public DefaultAuthSourceService(@Autowired JwtAuthSourceService jwtAuthSourceService, @Autowired @Qualifier("x509MFAuthSourceService") X509AuthSourceService x509AuthSourceService) { | ||
map.put(AuthSourceType.JWT, jwtAuthSourceService); | ||
map.put(AuthSourceType.CLIENT_CERT, x509AuthSourceService); | ||
} | ||
|
||
/** | ||
* Core method of the interface. Gets source of authentication from request. | ||
* <p> | ||
* In case if more than one source is present in request the precedence is the following: | ||
* 1) JWT token | ||
* 2) Client certificate | ||
* <p> | ||
* @return Optional<AuthSource> which hold original source of authentication (JWT token, client certificate etc.) | ||
* or Optional.empty() when no authentication source found. | ||
*/ | ||
@Override | ||
public Optional<AuthSource> getAuthSourceFromRequest() { | ||
AuthSourceService service = getService(AuthSourceType.JWT); | ||
Optional<AuthSource> authSource = service.getAuthSourceFromRequest(); | ||
if (!authSource.isPresent()) { | ||
service = getService(AuthSourceType.CLIENT_CERT); | ||
authSource = service.getAuthSourceFromRequest(); | ||
} | ||
return authSource; | ||
} | ||
|
||
/** | ||
* Delegates the validation of the authentication source to a corresponding service. | ||
* @param authSource {@link AuthSource} object which hold original source of authentication (JWT token, client certificate etc.) | ||
* @return true is authentication source is valid, false otherwise | ||
*/ | ||
@Override | ||
public boolean isValid(AuthSource authSource) { | ||
AuthSourceService service = getService(authSource); | ||
return service != null && service.isValid(authSource); | ||
} | ||
|
||
/** | ||
* Delegates the parsing of the authentication source to a corresponding service. | ||
* @param authSource {@link AuthSource} object which hold original source of authentication (JWT token, client certificate etc.) | ||
* @return authentication source in parsed form | ||
*/ | ||
@Override | ||
public Parsed parse(AuthSource authSource) { | ||
AuthSourceService service = getService(authSource); | ||
return service != null ? service.parse(authSource) : null; | ||
} | ||
|
||
/** | ||
* Delegates the generation of the LTPA token based on the authentication source to a corresponding service. | ||
* @param authSource {@link AuthSource} object which hold original source of authentication (JWT token, client certificate etc.) | ||
* @return LPTA token | ||
*/ | ||
@Override | ||
public String getLtpaToken(AuthSource authSource) { | ||
AuthSourceService service = getService(authSource); | ||
return service != null ? service.getLtpaToken(authSource) : null; | ||
} | ||
|
||
/** | ||
* Choose a service to process authentication source from the map of available services. | ||
* @param authSource {@link AuthSource} object which hold original source of authentication (JWT token, client certificate etc.) | ||
* @return implementation of {@link AuthSourceService} or null if service not found | ||
*/ | ||
private AuthSourceService getService(AuthSource authSource) { | ||
return authSource != null ? getService(authSource.getType()) : null; | ||
} | ||
|
||
/** | ||
* Choose a service to process authentication source of specific type from the map of available services. | ||
* @param authSourceType {@link AuthSourceType} type of the authentication source | ||
* @return implementation of {@link AuthSourceService} or null if service not found | ||
*/ | ||
private AuthSourceService getService(AuthSourceType authSourceType) { | ||
final AuthSourceService service = map.get(authSourceType); | ||
if (service == null) { | ||
throw new IllegalArgumentException("Unknown authentication source"); | ||
} | ||
return service; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
...e/src/main/java/org/zowe/apiml/gateway/security/service/schema/source/X509AuthSource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* 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.source; | ||
|
||
import java.security.cert.X509Certificate; | ||
import java.util.Date; | ||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
/** | ||
* Implementation of source of authentication based on client certificate. | ||
*/ | ||
@RequiredArgsConstructor | ||
@Getter | ||
@EqualsAndHashCode(onlyExplicitlyIncluded = true) | ||
public class X509AuthSource implements AuthSource { | ||
public static final AuthSourceType type = AuthSourceType.CLIENT_CERT; | ||
/** | ||
* X509 client certificate | ||
*/ | ||
@EqualsAndHashCode.Include | ||
private final X509Certificate source; | ||
|
||
@Override | ||
public X509Certificate getRawSource() { | ||
return source; | ||
} | ||
|
||
@Override | ||
public AuthSourceType getType() { | ||
return AuthSourceType.CLIENT_CERT; | ||
} | ||
|
||
@RequiredArgsConstructor | ||
@Getter | ||
@EqualsAndHashCode | ||
public static class Parsed implements AuthSource.Parsed, X509Parsed { | ||
private final String userId; | ||
private final Date creation; | ||
private final Date expiration; | ||
private final Origin origin; | ||
private final String publicKey; | ||
private final String distinguishedName; | ||
|
||
public String getCommonName() { | ||
return userId; | ||
} | ||
} | ||
|
||
public interface X509Parsed { | ||
String getCommonName(); | ||
String getPublicKey(); | ||
String getDistinguishedName(); | ||
} | ||
} |
Oops, something went wrong.