11
11
12
12
import com .netflix .appinfo .InstanceInfo ;
13
13
import com .netflix .zuul .context .RequestContext ;
14
-
15
- import java .util .Arrays ;
16
- import java .util .Date ;
17
- import java .util .Optional ;
14
+ import io .jsonwebtoken .Claims ;
15
+ import lombok .Getter ;
18
16
import lombok .RequiredArgsConstructor ;
19
-
20
17
import org .apache .commons .lang3 .time .DateUtils ;
21
18
import org .springframework .beans .factory .annotation .Value ;
22
19
import org .springframework .stereotype .Component ;
23
20
import org .zowe .apiml .auth .Authentication ;
24
21
import org .zowe .apiml .auth .AuthenticationScheme ;
25
- import org .zowe .apiml .gateway .security .service .PassTicketException ;
22
+ import org .zowe .apiml .gateway .security .service .saf . SafIdtAuthException ;
26
23
import org .zowe .apiml .gateway .security .service .saf .SafIdtException ;
27
24
import org .zowe .apiml .gateway .security .service .saf .SafIdtProvider ;
25
+ import org .zowe .apiml .gateway .security .service .schema .source .AuthSchemeException ;
28
26
import org .zowe .apiml .gateway .security .service .schema .source .AuthSource ;
29
27
import org .zowe .apiml .gateway .security .service .schema .source .AuthSourceService ;
30
28
import org .zowe .apiml .passticket .IRRPassTicketGenerationException ;
31
29
import org .zowe .apiml .passticket .PassTicketService ;
32
30
import org .zowe .apiml .security .common .config .AuthConfigurationProperties ;
33
31
import org .zowe .apiml .security .common .token .TokenExpireException ;
34
32
import org .zowe .apiml .security .common .token .TokenNotValidException ;
35
- import org .zowe .apiml .util .CookieUtil ;
36
-
37
- import io .jsonwebtoken .Claims ;
38
33
39
- import javax .annotation .PostConstruct ;
34
+ import javax .validation .constraints .NotNull ;
35
+ import java .util .Arrays ;
36
+ import java .util .Date ;
37
+ import java .util .Optional ;
40
38
41
39
import static org .zowe .apiml .gateway .security .service .JwtUtils .getJwtClaims ;
42
40
@@ -54,12 +52,6 @@ public class SafIdtScheme implements IAuthenticationScheme {
54
52
55
53
@ Value ("${apiml.security.saf.defaultIdtExpiration:10}" )
56
54
int defaultIdtExpiration ;
57
- private String cookieName ;
58
-
59
- @ PostConstruct
60
- public void initCookieName () {
61
- cookieName = authConfigurationProperties .getCookieProperties ().getCookieName ();
62
- }
63
55
64
56
@ Override
65
57
public AuthenticationScheme getScheme () {
@@ -68,73 +60,103 @@ public AuthenticationScheme getScheme() {
68
60
69
61
@ Override
70
62
public AuthenticationCommand createCommand (Authentication authentication , AuthSource authSource ) {
71
- final AuthSource .Parsed parsedAuthSource = authSourceService .parse (authSource );
72
-
73
- if (parsedAuthSource == null ) {
74
- return AuthenticationCommand .EMPTY ;
63
+ // check the authentication source
64
+ if (authSource == null || authSource .getRawSource () == null ) {
65
+ throw new AuthSchemeException ("org.zowe.apiml.gateway.security.schema.missingAuthentication" );
66
+ }
67
+ // parse the authentication source
68
+ AuthSource .Parsed parsedAuthSource ;
69
+ try {
70
+ parsedAuthSource = authSourceService .parse (authSource );
71
+ if (parsedAuthSource == null ) {
72
+ throw new IllegalStateException ("Error occurred while parsing authenticationSource" );
73
+ }
74
+ } catch (TokenNotValidException e ) {
75
+ throw new AuthSchemeException ("org.zowe.apiml.gateway.security.invalidToken" );
76
+ } catch (TokenExpireException e ) {
77
+ throw new AuthSchemeException ("org.zowe.apiml.gateway.security.expiredToken" );
75
78
}
76
79
77
- final String userId = parsedAuthSource .getUserId ();
78
- final String applId = authentication .getApplid ();
80
+ String safIdentityToken ;
81
+ long expireAt ;
82
+
83
+ String applId = getApplId (authentication );
84
+ safIdentityToken = generateSafIdentityToken (parsedAuthSource , applId );
85
+ expireAt = getSafIdtExpiration (safIdentityToken );
86
+
87
+ return new SafIdtCommand (safIdentityToken , expireAt );
88
+ }
89
+
90
+ @ Override
91
+ public Optional <AuthSource > getAuthSource () {
92
+ return authSourceService .getAuthSourceFromRequest ();
93
+ }
94
+
95
+ private String getApplId (Authentication authentication ) {
96
+ String applId = authentication == null ? null : authentication .getApplid ();
79
97
if (applId == null ) {
80
- throw new PassTicketException (
81
- "Applid is required. Check the configuration of service"
82
- );
98
+ throw new AuthSchemeException ("org.zowe.apiml.gateway.security.scheme.missingApplid" );
83
99
}
100
+ return applId ;
101
+ }
84
102
103
+ private String generateSafIdentityToken (@ NotNull AuthSource .Parsed parsedAuthSource , @ NotNull String applId ) {
85
104
String safIdentityToken ;
105
+
106
+ String userId = parsedAuthSource .getUserId ();
107
+ if (userId == null ) {
108
+ throw new AuthSchemeException ("org.zowe.apiml.gateway.security.schema.x509.mappingFailed" );
109
+ }
110
+
111
+ char [] passTicket = "" .toCharArray ();
86
112
try {
87
- char [] passTicket = passTicketService .generate (userId , applId ).toCharArray ();
88
- try {
89
- safIdentityToken = safIdtProvider .generate (userId , passTicket , applId );
90
- } finally {
91
- Arrays .fill (passTicket , (char ) 0 );
92
- }
113
+ passTicket = passTicketService .generate (userId , applId ).toCharArray ();
114
+ safIdentityToken = safIdtProvider .generate (userId , passTicket , applId );
93
115
} catch (IRRPassTicketGenerationException e ) {
94
- throw new PassTicketException (
95
- String .format ("Could not generate PassTicket for user ID '%s' and APPLID '%s'" , userId , applId ), e
96
- );
116
+ throw new AuthSchemeException ("org.zowe.apiml.security.ticket.generateFailed" , e .getMessage ());
117
+ } catch (SafIdtException | SafIdtAuthException e ) {
118
+ throw new AuthSchemeException ("org.zowe.apiml.security.idt.failed" , e .getMessage ());
119
+ } finally {
120
+ Arrays .fill (passTicket , (char ) 0 );
97
121
}
122
+ return safIdentityToken ;
123
+ }
98
124
125
+ private long getSafIdtExpiration (String safIdentityToken ) {
126
+ Date expirationTime ;
99
127
try {
100
128
Claims claims = getJwtClaims (safIdentityToken );
101
- Date expirationDate = claims .getExpiration ();
102
- if (expirationDate == null ) {
103
- expirationDate = DateUtils .addMinutes (new Date (), defaultIdtExpiration );
129
+ expirationTime = claims .getExpiration ();
130
+ if (expirationTime == null ) {
131
+ expirationTime = DateUtils .addMinutes (new Date (), defaultIdtExpiration );
104
132
}
105
-
106
- return new SafIdtCommand ( safIdentityToken , cookieName , expirationDate . getTime () );
107
- } catch (TokenNotValidException | TokenExpireException e ) {
108
- throw new SafIdtException ( "Unable to parse Identity Token" , e );
133
+ } catch ( TokenNotValidException e ) {
134
+ throw new AuthSchemeException ( "org.zowe.apiml.gateway.security.invalidToken" );
135
+ } catch (TokenExpireException e ) {
136
+ throw new AuthSchemeException ( "org.zowe.apiml.gateway.security.expiredToken" );
109
137
}
110
- }
111
-
112
- @ Override
113
- public Optional <AuthSource > getAuthSource () {
114
- return authSourceService .getAuthSourceFromRequest ();
138
+ return expirationTime .getTime ();
115
139
}
116
140
117
141
@ RequiredArgsConstructor
118
142
public class SafIdtCommand extends AuthenticationCommand {
119
143
private static final long serialVersionUID = 8213192949049438897L ;
120
144
145
+ @ Getter
121
146
private final String safIdentityToken ;
122
- private final String cookieName ;
147
+ @ Getter
123
148
private final Long expireAt ;
124
149
125
- private static final String COOKIE_HEADER = "cookie" ;
126
- private static final String SAF_TOKEN_HEADER = "X-SAF-Token" ;
150
+ protected static final String SAF_TOKEN_HEADER = "X-SAF-Token" ;
127
151
128
152
@ Override
129
153
public void apply (InstanceInfo instanceInfo ) {
130
- final RequestContext context = RequestContext .getCurrentContext ();
131
- context .addZuulRequestHeader (SAF_TOKEN_HEADER , safIdentityToken );
132
- context .addZuulRequestHeader (COOKIE_HEADER ,
133
- CookieUtil .removeCookie (
134
- context .getZuulRequestHeaders ().get (COOKIE_HEADER ),
135
- cookieName
136
- )
137
- );
154
+ if (safIdentityToken != null ) {
155
+ final RequestContext context = RequestContext .getCurrentContext ();
156
+ // add header with SafIdt token to request and remove APIML token from Cookie if exists
157
+ context .addZuulRequestHeader (SAF_TOKEN_HEADER , safIdentityToken );
158
+ JwtCommand .removeCookie (context , authConfigurationProperties .getCookieProperties ().getCookieName ());
159
+ }
138
160
}
139
161
140
162
@ Override
0 commit comments