Skip to content

Commit 7772401

Browse files
balhar-jakubJakub Balharachmelo
authored
feat: Fix SAF IDT scheme and service (#2224)
* Finish the movement of the SAF IDT related PR Signed-off-by: Jakub Balhar <jakub.balhar@broadcom.net> * Add applid related behavior in mock Signed-off-by: Jakub Balhar <jakub.balhar@broadcom.net> * Fix the configuration Signed-off-by: Jakub Balhar <jakub.balhar@broadcom.net> Co-authored-by: Jakub Balhar <jakub.balhar@broadcom.net> Co-authored-by: achmelo <a.chmelo@gmail.com> Co-authored-by: achmelo <37397715+achmelo@users.noreply.github.com>
1 parent 0e39aa7 commit 7772401

File tree

6 files changed

+120
-176
lines changed

6 files changed

+120
-176
lines changed

gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/saf/SafProviderBeansConfig.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,13 @@
1414
import org.springframework.context.annotation.Bean;
1515
import org.springframework.context.annotation.Configuration;
1616
import org.springframework.web.client.RestTemplate;
17-
import org.zowe.apiml.gateway.security.service.AuthenticationService;
18-
import org.zowe.apiml.passticket.PassTicketService;
1917

2018
@Configuration
2119
@RequiredArgsConstructor
2220
public class SafProviderBeansConfig {
2321
@Bean
2422
@ConditionalOnProperty(name = "apiml.security.saf.provider", havingValue = "rest")
25-
public SafIdtProvider restSafProvider(
26-
RestTemplate restTemplate,
27-
AuthenticationService authenticationService,
28-
PassTicketService passTicketService
29-
) {
30-
return new SafRestAuthenticationService(restTemplate, authenticationService, passTicketService);
23+
public SafIdtProvider restSafProvider(RestTemplate restTemplate) {
24+
return new SafRestAuthenticationService(restTemplate);
3125
}
3226
}

gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/saf/SafRestAuthenticationService.java

Lines changed: 47 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,18 @@
99
*/
1010
package org.zowe.apiml.gateway.security.service.saf;
1111

12-
import com.netflix.zuul.context.RequestContext;
13-
import lombok.Data;
14-
import lombok.RequiredArgsConstructor;
15-
import lombok.extern.slf4j.Slf4j;
12+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
13+
import com.fasterxml.jackson.databind.ser.std.StdArraySerializers;
14+
import lombok.*;
15+
import org.apache.commons.lang3.StringUtils;
1616
import org.springframework.beans.factory.annotation.Value;
17-
import org.springframework.http.ResponseEntity;
17+
import org.springframework.http.*;
1818
import org.springframework.web.client.HttpClientErrorException;
19+
import org.springframework.web.client.RestClientException;
1920
import org.springframework.web.client.RestTemplate;
20-
import org.zowe.apiml.gateway.security.service.AuthenticationService;
21-
import org.zowe.apiml.passticket.IRRPassTicketGenerationException;
22-
import org.zowe.apiml.passticket.PassTicketService;
23-
import org.zowe.apiml.security.common.token.TokenAuthentication;
2421

2522
import java.net.URI;
26-
import java.util.Optional;
23+
import java.util.Collections;
2724

2825
import static org.springframework.util.StringUtils.isEmpty;
2926

@@ -37,84 +34,82 @@
3734
* - apiml.security.saf.urls.verify - URL to verify the validity of the token
3835
*/
3936
@RequiredArgsConstructor
40-
@Slf4j
4137
public class SafRestAuthenticationService implements SafIdtProvider {
38+
4239
private final RestTemplate restTemplate;
43-
private final AuthenticationService authenticationService;
44-
private final PassTicketService passTicketService;
40+
41+
static final HttpHeaders HEADERS = new HttpHeaders();
42+
43+
static {
44+
HEADERS.setContentType(MediaType.APPLICATION_JSON);
45+
HEADERS.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
46+
}
4547

4648
@Value("${apiml.security.saf.urls.authenticate}")
4749
String authenticationUrl;
4850
@Value("${apiml.security.saf.urls.verify}")
4951
String verifyUrl;
50-
@Value("${apiml.security.zosmf.applid:IZUDFLT}")
51-
protected String zosmfApplId;
5252

5353
@Override
5454
public String generate(String username, char[] password, String applId) {
55-
final RequestContext context = RequestContext.getCurrentContext();
56-
Optional<String> jwtToken = authenticationService.getJwtTokenFromRequest(context.getRequest());
57-
if (!jwtToken.isPresent()) {
58-
throw new SafIdtException("Provided no JWT token");
59-
}
60-
61-
TokenAuthentication tokenAuthentication = authenticationService.validateJwtToken(jwtToken.get());
62-
if (!tokenAuthentication.isAuthenticated()) {
63-
throw new SafIdtException("Provided invalid JWT token");
64-
}
55+
Authentication authentication = Authentication.builder()
56+
.username(username)
57+
.pass(password)
58+
.appl(applId)
59+
.build();
6560

6661
try {
67-
Authentication authentication = new Authentication();
68-
authentication.setJwt(jwtToken.get());
69-
authentication.setUsername(username);
70-
String passTicket = passTicketService.generate(username, zosmfApplId);
71-
log.debug("Generated passticket: {}", passTicket);
72-
authentication.setPass(passTicket);
73-
74-
ResponseEntity<Token> re = restTemplate.postForEntity(URI.create(authenticationUrl), authentication, Token.class);
75-
76-
if (!re.getStatusCode().is2xxSuccessful()) {
77-
throw new SafIdtException("ZSS authentication service has not returned the Identity token");
78-
}
79-
80-
Token responseBody = re.getBody();
81-
if (responseBody == null) {
62+
ResponseEntity<Token> response = restTemplate.exchange(
63+
URI.create(authenticationUrl),
64+
HttpMethod.POST,
65+
new HttpEntity<>(authentication, HEADERS),
66+
Token.class);
67+
68+
Token responseBody = response.getBody();
69+
if (responseBody == null || StringUtils.isEmpty(responseBody.getJwt())) {
8270
throw new SafIdtException("ZSS authentication service has not returned the Identity token");
8371
}
8472

8573
return responseBody.getJwt();
86-
} catch (HttpClientErrorException.Unauthorized | HttpClientErrorException.Forbidden | IRRPassTicketGenerationException e) {
74+
} catch (HttpClientErrorException.Unauthorized | HttpClientErrorException.Forbidden e) {
8775
throw new SafIdtAuthException("Authentication to ZSS failed", e);
8876
}
8977
}
9078

9179
@Override
92-
public boolean verify(String safToken, String applId) {
80+
public boolean verify(String safToken, String applid) {
9381
if (isEmpty(safToken)) {
9482
return false;
9583
}
9684

9785
try {
98-
Token token = new Token();
99-
token.setJwt(safToken);
100-
101-
ResponseEntity<String> re = restTemplate.postForEntity(URI.create(verifyUrl), token, String.class);
102-
103-
return re.getStatusCode().is2xxSuccessful();
104-
} catch (HttpClientErrorException.Unauthorized e) {
86+
ResponseEntity<Void> response = restTemplate.exchange(
87+
URI.create(verifyUrl),
88+
HttpMethod.POST,
89+
new HttpEntity<>(new Token(safToken, applid), HEADERS),
90+
Void.class);
91+
92+
return response.getStatusCode().is2xxSuccessful();
93+
} catch (RestClientException e) {
10594
return false;
10695
}
10796
}
10897

10998
@Data
99+
@NoArgsConstructor
100+
@AllArgsConstructor
110101
public static class Token {
111102
String jwt;
103+
String appl;
112104
}
113105

114-
@Data
106+
@lombok.Value
107+
@Builder
115108
public static class Authentication {
116-
String jwt;
117109
String username;
118-
String pass;
110+
@JsonSerialize(using = StdArraySerializers.CharArraySerializer.class)
111+
char[] pass;
112+
String appl;
119113
}
114+
120115
}

gateway-service/src/test/java/org/zowe/apiml/acceptance/SafIdtSchemeTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ void thenValidTokenIsProvided() throws IOException {
9898
.signWith(Keys.secretKeyFor(SignatureAlgorithm.HS256))
9999
.compact();
100100

101-
ResponseEntity<Object> response = mock(ResponseEntity.class);
102-
when(mockTemplate.postForEntity(any(), any(), any())).thenReturn(response);
103-
when(response.getStatusCode()).thenReturn(org.springframework.http.HttpStatus.CREATED);
104-
SafRestAuthenticationService.Token responseBody = new SafRestAuthenticationService.Token();
105-
responseBody.setJwt(resultSafToken);
101+
ResponseEntity<SafRestAuthenticationService.Token> response = mock(ResponseEntity.class);
102+
when(mockTemplate.exchange(any(), eq(HttpMethod.POST), any(), eq(SafRestAuthenticationService.Token.class)))
103+
.thenReturn(response);
104+
SafRestAuthenticationService.Token responseBody =
105+
new SafRestAuthenticationService.Token(resultSafToken, "applid");
106106
when(response.getBody()).thenReturn(responseBody);
107107

108108
given()

0 commit comments

Comments
 (0)