-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add PathPatternRequestMatcher #16499
base: main
Are you sure you want to change the base?
Conversation
bdd1cf1
to
12f1cf2
Compare
This static factory simplifes the creation of RequestMatchers that specify the servlet path and other request elements Closes spring-projectsgh-16430
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all of your work on this @jzheaux! I've provided feedback below:
* @return the object that is chained after creating the {@link RequestMatcher} | ||
* @since 6.5 | ||
*/ | ||
public C requestMatchers(org.springframework.security.web.util.matcher.RequestMatchers.Builder builder) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer that interfaces be passed in to the DSL rather than implementations. Implementations are quite limiting (which is why we tend to use interfaces).
Perhaps for now, users must leverage Builder.matcher() and pass this into the existing DSL since we plan on refining the DLS going forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like the DSL to avoid needing static imports in order to function. It makes discovery more difficult. Even if it is only a little more difficult, each small difficulty adds up.
|
||
== Use Absolute Authorization URIs | ||
|
||
The Java DSL now requires that all URIs be absolute (less any context root). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rephrase this a bit to state that Spring Security 7 will require since I don't think that this is true now.
|
||
The Java DSL now requires that all URIs be absolute (less any context root). | ||
|
||
This means any endpoints that are not part of the default servlet, xref:servlet/authorization/authorize-http-requests.adoc#match-by-mvc[the servlet path needs to be specified]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm having trouble understanding this section.
http { | ||
authorizeHttpRequests { | ||
authorize(mvc.pattern("/my/controller/**"), hasAuthority("controller")) | ||
authorize("/spring-mvc", "/admin/**", hasAuthority("admin")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need updated? I think that authorize was in a different revision, but does not exist anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation was mistaken. AFAIK, this is the correct way to specify the servlet path in the Kotlin DSL. See this test as an example.
|
||
[TIP] | ||
===== | ||
There are several other components that create request matchers for you like `PathRequest#toStaticResources#atCommonLocations` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is PathRequest#toStaticResources#atCommonLocations
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a Spring Boot feature. I'll add a link for additional context.
* {@code servletPath}. | ||
* | ||
* <p> | ||
* The {@code servletPath} must correlate to a configured servlet in your application. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds like servletPath
might be the equivalent of <servlet-mapping>/<url-pattern>
, but I suspect it is corresponding to HttpServletRequest.servletPath
. Perhaps, this could be clarified?
* @return a {@link Builder} that treats URIs as relative to the context path, if any | ||
* @since 6.5 | ||
*/ | ||
public static Builder request() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this could be emptyServletPath()
or similar?
* @since 6.5 | ||
*/ | ||
public static Builder request() { | ||
return new Builder(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this is accurate since it matches any servletPath vs an empty servlet path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps. Though this method is not really about declaring a request in absence of something else. I wouldn't, for example, want AntPathRequestMatcher#antPattern(String pattern)
to be AntPathRequestMatcher#emptyMethodPattern(String pattern)
because no method is specified.
I'm open to thinking about other names, but I don't see why we'd want to define this in terms of what is not specified.
Furthermore, I think the 95% case is that defining a servlet path isn't necessary, so I'd prefer not to define the common case in terms of a concept that commonly is abstracted away from the developer.
Could you elaborate on why it's important to you?
(as a side note, even though I think that specifying a servlet is not in the 95%, I like that having it as an entry point allows for the returned builder to be reused, and I also like that it makes it clear that such a matcher should only be described once)
*/ | ||
public final class PathPatternRequestMatcher implements RequestMatcher { | ||
|
||
private final PathPattern pattern; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While PathPattern does not match on the servlet path, is that meaningful for Spring Security applications? I am concerned that this makes it too easy to do the wrong thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm open to other possibilities. One that I considered was to enhance PathPatternRequestMatcher
to be something more of an general-purpose request matcher. In this way, its pattern of construction would indicate a place for the servlet path. Perhaps the builder in RequestMatchers
can move to PathPatternRequestMatcher
.
What are your thoughts on this?
@@ -102,3 +102,12 @@ Xml:: | |||
</b:bean> | |||
---- | |||
====== | |||
|
|||
== Use Absolute Authorization URIs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add some examples?
This PR adds
PathPatternRequestMatcher
, a request matcher that doesn't requireHandlerMappingIntrospector
.Also, it adds a servlet-aware builder for specifying the servlet path (using this request matcher) in a way that looks similar to Kotlin and XML:
Future tickets like #16509 are taking a look at a first-class way to represent the servlet inside the authorization DSL. This builder is still helpful since there are many other places in the Java DSL where request matchers are provided that may need the servlet path specified.