38
38
import org .apache .commons .logging .LogFactory ;
39
39
40
40
import org .springframework .core .log .LogMessage ;
41
- import org .springframework .security .web .access .ExceptionTranslationFilter ;
42
- import org .springframework .security .web .access .channel .ChannelProcessingFilter ;
43
- import org .springframework .security .web .access .intercept .AuthorizationFilter ;
44
- import org .springframework .security .web .access .intercept .FilterSecurityInterceptor ;
45
- import org .springframework .security .web .authentication .AnonymousAuthenticationFilter ;
46
- import org .springframework .security .web .authentication .UsernamePasswordAuthenticationFilter ;
47
- import org .springframework .security .web .authentication .logout .LogoutFilter ;
48
- import org .springframework .security .web .authentication .preauth .AbstractPreAuthenticatedProcessingFilter ;
49
- import org .springframework .security .web .authentication .preauth .x509 .X509AuthenticationFilter ;
50
- import org .springframework .security .web .authentication .rememberme .RememberMeAuthenticationFilter ;
51
- import org .springframework .security .web .authentication .switchuser .SwitchUserFilter ;
52
- import org .springframework .security .web .authentication .ui .DefaultLoginPageGeneratingFilter ;
53
- import org .springframework .security .web .authentication .ui .DefaultLogoutPageGeneratingFilter ;
54
- import org .springframework .security .web .authentication .www .BasicAuthenticationFilter ;
55
- import org .springframework .security .web .authentication .www .DigestAuthenticationFilter ;
56
- import org .springframework .security .web .context .SecurityContextHolderFilter ;
57
- import org .springframework .security .web .context .SecurityContextPersistenceFilter ;
58
- import org .springframework .security .web .context .request .async .WebAsyncManagerIntegrationFilter ;
59
- import org .springframework .security .web .csrf .CsrfFilter ;
60
- import org .springframework .security .web .header .HeaderWriterFilter ;
61
- import org .springframework .security .web .jaasapi .JaasApiIntegrationFilter ;
62
- import org .springframework .security .web .savedrequest .RequestCacheAwareFilter ;
63
- import org .springframework .security .web .servletapi .SecurityContextHolderAwareRequestFilter ;
64
- import org .springframework .security .web .session .ConcurrentSessionFilter ;
65
- import org .springframework .security .web .session .DisableEncodeUrlFilter ;
66
- import org .springframework .security .web .session .ForceEagerSessionCreationFilter ;
67
- import org .springframework .security .web .session .SessionManagementFilter ;
68
- import org .springframework .util .Assert ;
69
- import org .springframework .util .StringUtils ;
70
- import org .springframework .web .filter .CorsFilter ;
71
41
72
42
/**
73
43
* A {@link org.springframework.security.web.FilterChainProxy.FilterChainDecorator} that
@@ -80,12 +50,6 @@ public final class ObservationFilterChainDecorator implements FilterChainProxy.F
80
50
81
51
private static final Log logger = LogFactory .getLog (FilterChainProxy .class );
82
52
83
- private static final int OPENTELEMETRY_MAX_NAME_LENGTH = 63 ;
84
-
85
- private static final int MAX_OBSERVATION_NAME_LENGTH = OPENTELEMETRY_MAX_NAME_LENGTH - ".before" .length ();
86
-
87
- private static final Map <String , String > OBSERVATION_NAMES = new HashMap <>();
88
-
89
53
private static final String ATTRIBUTE = ObservationFilterChainDecorator .class + ".observation" ;
90
54
91
55
static final String UNSECURED_OBSERVATION_NAME = "spring.security.http.unsecured.requests" ;
@@ -136,83 +100,10 @@ private List<ObservationFilter> wrap(List<Filter> filters) {
136
100
return observableFilters ;
137
101
}
138
102
139
- static {
140
- registerName (DisableEncodeUrlFilter .class , "session.encode-url.disable" );
141
- registerName (ForceEagerSessionCreationFilter .class , "session.create" );
142
- registerName (ChannelProcessingFilter .class , "web.request.delivery.ensure" );
143
- registerName (WebAsyncManagerIntegrationFilter .class , "web-async-manager.join.security-context" );
144
- registerName (SecurityContextHolderFilter .class , "security-context.hold" );
145
- registerName (SecurityContextPersistenceFilter .class , "security-context.persist" );
146
- registerName (HeaderWriterFilter .class , "web.response.header.set" );
147
- registerName (CorsFilter .class , "cors.process" );
148
- registerName (CsrfFilter .class , "csrf.protect" );
149
- registerName (LogoutFilter .class , "principal.logout" );
150
- registerName ("org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter" ,
151
- "web.request.oauth2.redirect" );
152
- registerName (
153
- "org.springframework.security.saml2.provider.service.web." + "Saml2WebSsoAuthenticationRequestFilter" ,
154
- "web.request.saml2.redirect" );
155
- registerName (X509AuthenticationFilter .class , "web.request.x509.auth" );
156
- registerName (AbstractPreAuthenticatedProcessingFilter .class , "web.request.pre-auth.base.process" );
157
- registerName ("org.springframework.security.cas.web.CasAuthenticationFilter" , "web.request.sas.auth" );
158
- registerName ("org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter" ,
159
- "web.response.oauth2.process" );
160
- registerName ("org.springframework.security.saml2.provider.service.web.authentication"
161
- + ".Saml2WebSsoAuthenticationFilter" , "web.request.saml2.auth" );
162
- registerName (UsernamePasswordAuthenticationFilter .class , "web.request.username-password.auth" );
163
- registerName (DefaultLoginPageGeneratingFilter .class , "web.login-page.default.generate" );
164
- registerName (DefaultLogoutPageGeneratingFilter .class , "web.logout-page.default.generate" );
165
- registerName (ConcurrentSessionFilter .class , "session.refresh" );
166
- registerName (DigestAuthenticationFilter .class , "web.request.digest.auth" );
167
- registerName ("org.springframework.security.oauth2.server.resource.web.authentication."
168
- + "BearerTokenAuthenticationFilter" , "web.request.bearer.auth" );
169
- registerName (BasicAuthenticationFilter .class , "web.request.basic.auth" );
170
- registerName (RequestCacheAwareFilter .class , "web.request.cache.extract" );
171
- registerName (SecurityContextHolderAwareRequestFilter .class , "web.request.security.wrap" );
172
- registerName (JaasApiIntegrationFilter .class , "web.request.jass.auth" );
173
- registerName (RememberMeAuthenticationFilter .class , "web.request.remember-me.auth" );
174
- registerName (AnonymousAuthenticationFilter .class , "web.request.anonymous.auth" );
175
- registerName ("org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter" ,
176
- "web.response.oauth2.code-grant.process" );
177
- registerName (SessionManagementFilter .class , "session.manage" );
178
- registerName (ExceptionTranslationFilter .class , "exception.translate" );
179
- registerName (FilterSecurityInterceptor .class , "web.response.security.intercept" );
180
- registerName (AuthorizationFilter .class , "web.access.auth.restrict" );
181
- registerName (SwitchUserFilter .class , "session.switch" );
182
- }
183
-
184
- public static void registerName (Class clazz , String name ) {
185
- String keyName = clazz .getName ();
186
- checkAlreadyRegistered (keyName );
187
- OBSERVATION_NAMES .put (keyName , limitLength (name ));
188
- }
189
-
190
- public static void registerName (String className , String name ) {
191
- checkAlreadyRegistered (className );
192
- OBSERVATION_NAMES .put (className , name );
193
- }
194
-
195
103
static AroundFilterObservation observation (HttpServletRequest request ) {
196
104
return (AroundFilterObservation ) request .getAttribute (ATTRIBUTE );
197
105
}
198
106
199
- private static String getObservationName (String className ) {
200
- if (OBSERVATION_NAMES .containsKey (className )) {
201
- return OBSERVATION_NAMES .get (className );
202
- }
203
- throw new IllegalArgumentException ("Class not registered for observation: " + className );
204
- }
205
-
206
- private static String limitLength (String s ) {
207
- Assert .isTrue (s .length () <= MAX_OBSERVATION_NAME_LENGTH ,
208
- "The name must be less than MAX_OBSERVATION_NAME_LENGTH=" + MAX_OBSERVATION_NAME_LENGTH );
209
- return s ;
210
- }
211
-
212
- private static void checkAlreadyRegistered (String keyName ) {
213
- Assert .isTrue (!OBSERVATION_NAMES .containsKey (keyName ), "Observation name is registered already: " + keyName );
214
- }
215
-
216
107
private static final class VirtualFilterChain implements FilterChain {
217
108
218
109
private final FilterChain originalChain ;
@@ -248,6 +139,49 @@ public void doFilter(ServletRequest request, ServletResponse response) throws IO
248
139
249
140
static final class ObservationFilter implements Filter {
250
141
142
+ private static final Map <String , String > OBSERVATION_NAMES = new HashMap <>();
143
+
144
+ static {
145
+ OBSERVATION_NAMES .put ("DisableEncodeUrlFilter" , "session.url-encoding" );
146
+ OBSERVATION_NAMES .put ("ForceEagerSessionCreationFilter" , "session.eager-create" );
147
+ OBSERVATION_NAMES .put ("ChannelProcessingFilter" , "access.channel" );
148
+ OBSERVATION_NAMES .put ("WebAsyncManagerIntegrationFilter" , "context.async" );
149
+ OBSERVATION_NAMES .put ("SecurityContextHolderFilter" , "context.holder" );
150
+ OBSERVATION_NAMES .put ("SecurityContextPersistenceFilter" , "context.management" );
151
+ OBSERVATION_NAMES .put ("HeaderWriterFilter" , "header" );
152
+ OBSERVATION_NAMES .put ("CorsFilter" , "cors" );
153
+ OBSERVATION_NAMES .put ("CsrfFilter" , "csrf" );
154
+ OBSERVATION_NAMES .put ("LogoutFilter" , "logout" );
155
+ OBSERVATION_NAMES .put ("OAuth2AuthorizationRequestRedirectFilter" , "oauth2.authnrequest" );
156
+ OBSERVATION_NAMES .put ("Saml2WebSsoAuthenticationRequestFilter" , "saml2.authnrequest" );
157
+ OBSERVATION_NAMES .put ("X509AuthenticationFilter" , "authentication.x509" );
158
+ OBSERVATION_NAMES .put ("J2eePreAuthenticatedProcessingFilter" , "preauthentication.j2ee" );
159
+ OBSERVATION_NAMES .put ("RequestHeaderAuthenticationFilter" , "preauthentication.header" );
160
+ OBSERVATION_NAMES .put ("RequestAttributeAuthenticationFilter" , "preauthentication.attribute" );
161
+ OBSERVATION_NAMES .put ("WebSpherePreAuthenticatedProcessingFilter" , "preauthentication.websphere" );
162
+ OBSERVATION_NAMES .put ("CasAuthenticationFilter" , "cas.authentication" );
163
+ OBSERVATION_NAMES .put ("OAuth2LoginAuthenticationFilter" , "oauth2.authentication" );
164
+ OBSERVATION_NAMES .put ("Saml2WebSsoAuthenticationFilter" , "saml2.authentication" );
165
+ OBSERVATION_NAMES .put ("UsernamePasswordAuthenticationFilter" , "authentication.form" );
166
+ OBSERVATION_NAMES .put ("DefaultLoginPageGeneratingFilter" , "page.login" );
167
+ OBSERVATION_NAMES .put ("DefaultLogoutPageGeneratingFilter" , "page.logout" );
168
+ OBSERVATION_NAMES .put ("ConcurrentSessionFilter" , "session.concurrent" );
169
+ OBSERVATION_NAMES .put ("DigestAuthenticationFilter" , "authentication.digest" );
170
+ OBSERVATION_NAMES .put ("BearerTokenAuthenticationFilter" , "authentication.bearer" );
171
+ OBSERVATION_NAMES .put ("BasicAuthenticationFilter" , "authentication.basic" );
172
+ OBSERVATION_NAMES .put ("RequestCacheAwareFilter" , "requestcache" );
173
+ OBSERVATION_NAMES .put ("SecurityContextHolderAwareRequestFilter" , "context.servlet" );
174
+ OBSERVATION_NAMES .put ("JaasApiIntegrationFilter" , "jaas" );
175
+ OBSERVATION_NAMES .put ("RememberMeAuthenticationFilter" , "authentication.rememberme" );
176
+ OBSERVATION_NAMES .put ("AnonymousAuthenticationFilter" , "authentication.anonymous" );
177
+ OBSERVATION_NAMES .put ("OAuth2AuthorizationCodeGrantFilter" , "oauth2.client.code" );
178
+ OBSERVATION_NAMES .put ("SessionManagementFilter" , "session.management" );
179
+ OBSERVATION_NAMES .put ("ExceptionTranslationFilter" , "access.exceptions" );
180
+ OBSERVATION_NAMES .put ("FilterSecurityInterceptor" , "access.request" );
181
+ OBSERVATION_NAMES .put ("AuthorizationFilter" , "authorization" );
182
+ OBSERVATION_NAMES .put ("SwitchUserFilter" , "authentication.switch" );
183
+ }
184
+
251
185
private final ObservationRegistry registry ;
252
186
253
187
private final FilterChainObservationConvention convention = new FilterChainObservationConvention ();
@@ -256,7 +190,7 @@ static final class ObservationFilter implements Filter {
256
190
257
191
private final String name ;
258
192
259
- private final String observationName ;
193
+ private final String eventName ;
260
194
261
195
private final int position ;
262
196
@@ -268,28 +202,16 @@ static final class ObservationFilter implements Filter {
268
202
this .name = filter .getClass ().getSimpleName ();
269
203
this .position = position ;
270
204
this .size = size ;
271
- String tempObservationName ;
272
- try {
273
- tempObservationName = ObservationFilterChainDecorator .getObservationName (filter .getClass ().getName ());
274
- }
275
- catch (IllegalArgumentException ex ) {
276
- tempObservationName = compressName (this .name );
277
- logger .warn (
278
- "Class " + filter .getClass ().getName ()
279
- + " is not registered for observation and will have name " + tempObservationName
280
- + ". Please consider of registering this class with "
281
- + ObservationFilterChainDecorator .class .getSimpleName () + ".registerName(class, name)." ,
282
- ex );
283
- }
284
- this .observationName = tempObservationName ;
205
+ this .eventName = eventName (this .name );
285
206
}
286
207
287
- String getName () {
288
- return this .name ;
208
+ private String eventName (String className ) {
209
+ String eventName = OBSERVATION_NAMES .get (className );
210
+ return (eventName != null ) ? eventName : className ;
289
211
}
290
212
291
- String getObservationName () {
292
- return this .observationName ;
213
+ String getName () {
214
+ return this .name ;
293
215
}
294
216
295
217
@ Override
@@ -312,17 +234,15 @@ private void wrapFilter(ServletRequest request, ServletResponse response, Filter
312
234
parentBefore .setFilterName (this .name );
313
235
parentBefore .setChainPosition (this .position );
314
236
}
315
- parent .before ().event (Observation .Event .of (this .observationName + ".before" ,
316
- "before " + this .name ));
237
+ parent .before ().event (Observation .Event .of (this .eventName + ".before" , "before " + this .name ));
317
238
this .filter .doFilter (request , response , chain );
318
239
parent .start ();
319
240
if (parent .after ().getContext () instanceof FilterChainObservationContext parentAfter ) {
320
241
parentAfter .setChainSize (this .size );
321
242
parentAfter .setFilterName (this .name );
322
243
parentAfter .setChainPosition (this .size - this .position + 1 );
323
244
}
324
- parent .after ().event (Observation .Event .of (this .observationName + ".after" ,
325
- "after " + this .name ));
245
+ parent .after ().event (Observation .Event .of (this .eventName + ".after" , "after " + this .name ));
326
246
}
327
247
328
248
private AroundFilterObservation parent (HttpServletRequest request ) {
@@ -335,24 +255,6 @@ private AroundFilterObservation parent(HttpServletRequest request) {
335
255
return parent ;
336
256
}
337
257
338
- private String compressName (String className ) {
339
- if (className .length () >= MAX_OBSERVATION_NAME_LENGTH ) {
340
- return maximalCompressClassName (className , MAX_OBSERVATION_NAME_LENGTH );
341
- }
342
- return className ;
343
- }
344
-
345
- private String maximalCompressClassName (String className , int maxLength ) {
346
- String [] names = className .split ("(?=\\ p{Lu})" );
347
- for (int j = 0 ; j < names .length ; j ++) {
348
- final int maxPortionLength = maxLength / names .length ;
349
- if (names [j ].length () > maxPortionLength ) {
350
- names [j ] = names [j ].substring (0 , maxPortionLength );
351
- }
352
- }
353
- return StringUtils .arrayToDelimitedString (names , "" );
354
- }
355
-
356
258
}
357
259
358
260
interface AroundFilterObservation extends FilterObservation {
0 commit comments