11
11
12
12
import com .fasterxml .jackson .databind .ObjectMapper ;
13
13
import lombok .RequiredArgsConstructor ;
14
+ import org .springframework .beans .factory .annotation .Value ;
14
15
import org .springframework .context .annotation .Bean ;
15
16
import org .springframework .context .annotation .Configuration ;
17
+ import org .springframework .core .annotation .Order ;
16
18
import org .springframework .http .HttpMethod ;
19
+ import org .springframework .security .authentication .AuthenticationManager ;
17
20
import org .springframework .security .config .annotation .authentication .builders .AuthenticationManagerBuilder ;
18
21
import org .springframework .security .config .annotation .web .builders .HttpSecurity ;
19
22
import org .springframework .security .config .annotation .web .builders .WebSecurity ;
20
23
import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
21
24
import org .springframework .security .config .annotation .web .configuration .WebSecurityConfigurerAdapter ;
22
25
import org .springframework .security .config .http .SessionCreationPolicy ;
26
+ import org .springframework .security .core .userdetails .User ;
27
+ import org .springframework .security .core .userdetails .UserDetailsService ;
23
28
import org .springframework .security .web .authentication .UsernamePasswordAuthenticationFilter ;
24
29
import org .springframework .security .web .authentication .logout .LogoutSuccessHandler ;
30
+ import org .springframework .security .web .authentication .preauth .x509 .X509AuthenticationFilter ;
25
31
import org .springframework .security .web .util .matcher .AntPathRequestMatcher ;
32
+ import org .zowe .apiml .product .filter .AttlsFilter ;
26
33
import org .zowe .apiml .security .client .EnableApimlAuth ;
27
34
import org .zowe .apiml .security .client .login .GatewayLoginProvider ;
28
35
import org .zowe .apiml .security .client .token .GatewayTokenProvider ;
33
40
import org .zowe .apiml .security .common .login .LoginFilter ;
34
41
import org .zowe .apiml .security .common .login .ShouldBeAlreadyAuthenticatedFilter ;
35
42
43
+ import java .util .Collections ;
44
+
36
45
/**
37
46
* Main configuration class of Spring web security for Api Catalog
38
47
* binds authentication managers
44
53
@ EnableWebSecurity
45
54
@ RequiredArgsConstructor
46
55
@ EnableApimlAuth
47
- public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
56
+ public class SecurityConfiguration {
57
+ private static final String APIDOC_ROUTES = "/apidoc/**" ;
48
58
49
59
private final ObjectMapper securityObjectMapper ;
50
60
private final AuthConfigurationProperties authConfigurationProperties ;
51
61
private final HandlerInitializer handlerInitializer ;
52
62
private final GatewayLoginProvider gatewayLoginProvider ;
53
63
private final GatewayTokenProvider gatewayTokenProvider ;
54
64
55
- @ Override
56
- protected void configure (AuthenticationManagerBuilder auth ) {
57
- auth .authenticationProvider (gatewayLoginProvider );
58
- auth .authenticationProvider (gatewayTokenProvider );
65
+ /**
66
+ * Filter chain for protecting /apidoc/** endpoints with MF credentials for client certificate.
67
+ */
68
+ @ Configuration
69
+ @ Order (1 )
70
+ public class FilterChainBasicAuthOrTokenOrCertForApiDoc extends WebSecurityConfigurerAdapter {
71
+
72
+ @ Value ("${apiml.security.ssl.verifySslCertificatesOfServices:true}" )
73
+ private boolean verifySslCertificatesOfServices ;
74
+
75
+ @ Value ("${apiml.security.ssl.nonStrictVerifySslCertificatesOfServices:false}" )
76
+ private boolean nonStrictVerifySslCertificatesOfServices ;
77
+
78
+ @ Value ("${server.attls.enabled:false}" )
79
+ private boolean isAttlsEnabled ;
80
+
81
+ @ Override
82
+ protected void configure (AuthenticationManagerBuilder auth ) {
83
+ auth .authenticationProvider (gatewayLoginProvider );
84
+ auth .authenticationProvider (gatewayTokenProvider );
85
+ }
86
+
87
+ @ Override
88
+ protected void configure (HttpSecurity http ) throws Exception {
89
+ mainframeCredentialsConfiguration (
90
+ baseConfiguration (http .antMatcher (APIDOC_ROUTES )),
91
+ authenticationManager ()
92
+ )
93
+ .authorizeRequests ()
94
+ .antMatchers (APIDOC_ROUTES ).authenticated ();
95
+
96
+ if (verifySslCertificatesOfServices || nonStrictVerifySslCertificatesOfServices ) {
97
+ http .x509 ().userDetailsService (x509UserDetailsService ());
98
+ if (isAttlsEnabled ) {
99
+ http .addFilterBefore (new AttlsFilter (), X509AuthenticationFilter .class );
100
+ }
101
+ }
102
+ }
103
+
104
+ private UserDetailsService x509UserDetailsService () {
105
+ return username -> new User (username , "" , Collections .emptyList ());
106
+ }
59
107
}
60
108
61
- @ Override
62
- public void configure (WebSecurity web ) {
63
- // skip security filters matchers
64
- String [] noSecurityAntMatchers = {
65
- "/" ,
66
- "/static/**" ,
67
- "/favicon.ico" ,
68
- "/api-doc"
69
- };
70
-
71
- web .ignoring ().antMatchers (noSecurityAntMatchers );
109
+ /**
110
+ * Default filter chain to protect all routes with MF credentials.
111
+ */
112
+ @ Configuration
113
+ public class FilterChainBasicAuthOrTokenAllEndpoints extends WebSecurityConfigurerAdapter {
114
+
115
+ @ Override
116
+ protected void configure (AuthenticationManagerBuilder auth ) {
117
+ auth .authenticationProvider (gatewayLoginProvider );
118
+ auth .authenticationProvider (gatewayTokenProvider );
119
+ }
120
+
121
+ @ Override
122
+ public void configure (WebSecurity web ) {
123
+ // skip security filters matchers
124
+ String [] noSecurityAntMatchers = {
125
+ "/" ,
126
+ "/static/**" ,
127
+ "/favicon.ico" ,
128
+ "/api-doc"
129
+ };
130
+
131
+ web .ignoring ().antMatchers (noSecurityAntMatchers );
132
+ }
133
+
134
+ @ Override
135
+ protected void configure (HttpSecurity http ) throws Exception {
136
+ mainframeCredentialsConfiguration (
137
+ baseConfiguration (http ),
138
+ authenticationManager ()
139
+ )
140
+ .authorizeRequests ()
141
+ .antMatchers ("/static-api/**" ).authenticated ()
142
+ .antMatchers ("/containers/**" ).authenticated ()
143
+ .antMatchers (APIDOC_ROUTES ).authenticated ()
144
+ .antMatchers ("/application/health" , "/application/info" ).permitAll ()
145
+ .antMatchers ("/application/**" ).authenticated ();
146
+ }
72
147
}
73
148
74
- @ Override
75
- protected void configure (HttpSecurity http ) throws Exception {
149
+ private HttpSecurity baseConfiguration (HttpSecurity http ) throws Exception {
76
150
http
77
151
.csrf ().disable () // NOSONAR
78
152
.headers ()
@@ -85,20 +159,24 @@ protected void configure(HttpSecurity http) throws Exception {
85
159
handlerInitializer .getBasicAuthUnauthorizedHandler (), new AntPathRequestMatcher ("/application/**" )
86
160
)
87
161
.defaultAuthenticationEntryPointFor (
88
- handlerInitializer .getBasicAuthUnauthorizedHandler (), new AntPathRequestMatcher ("/apidoc/**" )
162
+ handlerInitializer .getBasicAuthUnauthorizedHandler (), new AntPathRequestMatcher (APIDOC_ROUTES )
89
163
)
90
164
.defaultAuthenticationEntryPointFor (
91
165
handlerInitializer .getUnAuthorizedHandler (), new AntPathRequestMatcher ("/**" )
92
166
)
93
167
94
168
.and ()
95
169
.sessionManagement ()
96
- .sessionCreationPolicy (SessionCreationPolicy .STATELESS )
170
+ .sessionCreationPolicy (SessionCreationPolicy .STATELESS );
97
171
172
+ return http ;
173
+ }
174
+
175
+ private HttpSecurity mainframeCredentialsConfiguration (HttpSecurity http , AuthenticationManager authenticationManager ) throws Exception {
176
+ http
98
177
// login endpoint
99
- .and ()
100
178
.addFilterBefore (new ShouldBeAlreadyAuthenticatedFilter (authConfigurationProperties .getServiceLoginEndpoint (), handlerInitializer .getAuthenticationFailureHandler ()), UsernamePasswordAuthenticationFilter .class )
101
- .addFilterBefore (loginFilter (authConfigurationProperties .getServiceLoginEndpoint ()), ShouldBeAlreadyAuthenticatedFilter .class )
179
+ .addFilterBefore (loginFilter (authConfigurationProperties .getServiceLoginEndpoint (), authenticationManager ), ShouldBeAlreadyAuthenticatedFilter .class )
102
180
.authorizeRequests ()
103
181
.antMatchers (HttpMethod .POST , authConfigurationProperties .getServiceLoginEndpoint ()).permitAll ()
104
182
@@ -110,33 +188,29 @@ protected void configure(HttpSecurity http) throws Exception {
110
188
111
189
// endpoints protection
112
190
.and ()
113
- .addFilterBefore (basicFilter (), UsernamePasswordAuthenticationFilter .class )
114
- .addFilterBefore (cookieFilter (), UsernamePasswordAuthenticationFilter .class )
115
- .authorizeRequests ()
116
- .antMatchers ("/static-api/**" ).authenticated ()
117
- .antMatchers ("/containers/**" ).authenticated ()
118
- .antMatchers ("/apidoc/**" ).authenticated ()
119
- .antMatchers ("/application/health" , "/application/info" ).permitAll ()
120
- .antMatchers ("/application/**" ).authenticated ();
191
+ .addFilterBefore (basicFilter (authenticationManager ), UsernamePasswordAuthenticationFilter .class )
192
+ .addFilterBefore (cookieFilter (authenticationManager ), UsernamePasswordAuthenticationFilter .class );
193
+
194
+ return http ;
121
195
}
122
196
123
- private LoginFilter loginFilter (String loginEndpoint ) throws Exception {
197
+ private LoginFilter loginFilter (String loginEndpoint , AuthenticationManager authenticationManager ) {
124
198
return new LoginFilter (
125
199
loginEndpoint ,
126
200
handlerInitializer .getSuccessfulLoginHandler (),
127
201
handlerInitializer .getAuthenticationFailureHandler (),
128
202
securityObjectMapper ,
129
- authenticationManager () ,
203
+ authenticationManager ,
130
204
handlerInitializer .getResourceAccessExceptionHandler ()
131
205
);
132
206
}
133
207
134
208
/**
135
209
* Secures content with a basic authentication
136
210
*/
137
- private BasicContentFilter basicFilter () throws Exception {
211
+ private BasicContentFilter basicFilter (AuthenticationManager authenticationManager ) {
138
212
return new BasicContentFilter (
139
- authenticationManager () ,
213
+ authenticationManager ,
140
214
handlerInitializer .getAuthenticationFailureHandler (),
141
215
handlerInitializer .getResourceAccessExceptionHandler ()
142
216
);
@@ -145,9 +219,9 @@ private BasicContentFilter basicFilter() throws Exception {
145
219
/**
146
220
* Secures content with a token stored in a cookie
147
221
*/
148
- private CookieContentFilter cookieFilter () throws Exception {
222
+ private CookieContentFilter cookieFilter (AuthenticationManager authenticationManager ) {
149
223
return new CookieContentFilter (
150
- authenticationManager () ,
224
+ authenticationManager ,
151
225
handlerInitializer .getAuthenticationFailureHandler (),
152
226
handlerInitializer .getResourceAccessExceptionHandler (),
153
227
authConfigurationProperties );
0 commit comments