The spring security filter related endpoints (e.g. /login, /logout) are mapped to ROOT uri, instead of being mapped to their URIs and have visibility over their metrics.
Due to the fact that the spring security handles the logic of the login/logout into a Filter (for instance, login in UsernamePasswordAuthenticationFilter), the login request doesn't reach the request handler mapper to have the required attribute (e.g. DATA_REST_PATH_PATTERN_ATTRIBUTE or BEST_MATCHING_PATTERN_ATTRIBUTE) for the actuator to fetch the Uri in WebMvcTags
To validate the issue, I created this demo repository => https://github.com/mohammedalics/actuator-login-filter-metrics-issue
** Call Login**
$ curl -kv 'http://localhost:8080/login' -H 'Content-Type: application/x-www-form-urlencoded' --data-raw 'username=user&password=password'`
HTTP/1.1 302
Set-Cookie: JSESSIONID=E0F21CAD780C1C25AAA22DE6F3069764; Path=/; HttpOnly
** Call Dummy endpoint**
curl -kv 'http://localhost:8080/hello' -H 'Cookie: JSESSIONID=E0F21CAD780C1C25AAA22DE6F3069764'
HTTP/1.1 200
hello
Then by calling the "http.server.requests" metrics => http://localhost:8080/actuator/metrics/http.server.requests
{
"name": "http.server.requests",
"description": null,
"baseUnit": "seconds",
"measurements": [
{
"statistic": "COUNT",
"value": 4
},
{
"statistic": "TOTAL_TIME",
"value": 0.22907417300000002
},
{
"statistic": "MAX",
"value": 0.012099089
}
],
"availableTags": [
{
"tag": "exception",
"values": [
"None"
]
},
{
"tag": "method",
"values": [
"POST",
"GET"
]
},
{
"tag": "uri",
"values": [
"REDIRECTION",
"/hello",
"root"
]
},
{
"tag": "outcome",
"values": [
"REDIRECTION",
"SUCCESS"
]
},
{
"tag": "status",
"values": [
"302",
"200"
]
}
]
}
--
If you agree on the issue, I can create a pull request to fix it.
Comment From: wilkinsona
The spring security filter related endpoints (e.g. /login, /logout) are mapped to ROOT uri
I don't think this is the case. The request to /login results in the uri tag being REDIRECTION due to the 302 response that redirects to /.
If you agree on the issue, I can create a pull request to fix it
What sort of fix did you have in mind? Note that when the pattern attributes aren't available the request URL cannot be used as-is as it may result in the uri tag's values being unbounded.
Comment From: mohammedalics
I understand that in the case of /login, the pattern here is null due to missing below attributes:
- DATA_REST_PATH_PATTERN_ATTRIBUTE which is supposed to be added by RepositoryRestHandlerMapping here
- BEST_MATCHING_PATTERN_ATTRIBUTE which is supposed to be added by AbstractUrlHandlerMapping or by RequestMappingInfoHandlerMapping here and here
In this case, the uri method tries to fulfil the uri by using the response and this describes why the request to /login results in the uri tag being REDIRECTION
Those attributes are HandlerMapping related attributes. If the request doesn't have a controller class and designed to be handled and served in a filter (like the case of /login), there will be no chance for the request mapper to add those attributes and then the actuator will not be able to identify the uri (because actuator depends on the request mapper added attributes as mentioned above).
The fix in my mind is to update the uri method to use the servletPath as kind of fallback if the pattern is null before using the response but use the response if the servletPath is just / or empty.
Comment From: wilkinsona
As I said above, we can't use the servlet path as it would mean that the values of the uri tag are potentially unbounded. For example, imagine a request URL where a portion of it is a UUID. If, for whatever reason, there's no pattern attribute available when the uri tag is being determined, every request with a different UUID in the URL would result in a different uri tag value.
Comment From: mohammedalics
Yes, totally make sense.
Do you think it could be achieved the other way around? I mean spring security adds the FilterProcessesUrl to a new attribute that can be caught by the actuator? Maybe we have something already?
Comment From: wilkinsona
I don't believe Security configures such an attribute at the moment. @rwinch @jzheaux what are your thoughts on this please?
Comment From: rwinch
I'm curious how we would generalize this to all of Spring Security's Filters or even more generally, any Filter. The challenge is that many Filters are involved in processing a request while only one MVC endpoint is involved. For example, during a typical form based log in at minimum the following Filters are going to be used: HeaderWriterFilter, CsrfFilter, and UsernamePasswordAuthenticationFilter. It doesn't seem that we can set a single attribute here. It seems that MVC was already setting the attribute and Metrics leveraged it. It seems strange that Security would set an attribute specifically for metrics. Perhaps we can provide hooks that allow Metrics to set attributes though?
To be clear I'm not saying that we cannot get something to work, but just that I'm not sure how we would expect it to work. This may be obvious to someone more experienced with metrics, but I'm very new to this space.
Comment From: philwebb
See also #2563