Skip to content

Commit 4f96e80

Browse files
committed
Utilized Vaadin built in functionality for SecureVaadinRequestCache
1 parent 2171c34 commit 4f96e80

File tree

2 files changed

+7
-111
lines changed

2 files changed

+7
-111
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 2.2.0
2+
* Vaadin
3+
* `SecureVaadinRequestCache` now uses `RequestUtil#isSecuredFlowRoute` which should be more performant and future-proof
4+
15
# 2.1.1
26
* Vaadin
37
* `SecureVaadinRequestCache` no longer ignores `urlMapping`

vaadin/src/main/java/software/xdev/sse/vaadin/SecureVaadinRequestCache.java

Lines changed: 3 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,14 @@
1515
*/
1616
package software.xdev.sse.vaadin;
1717

18-
import java.lang.reflect.Field;
19-
import java.util.Set;
20-
import java.util.stream.Collectors;
21-
22-
import jakarta.servlet.ServletContext;
2318
import jakarta.servlet.http.HttpServletRequest;
2419
import jakarta.servlet.http.HttpServletResponse;
2520

26-
import org.apache.catalina.Wrapper;
27-
import org.apache.catalina.core.ApplicationServletRegistration;
28-
import org.apache.catalina.core.StandardWrapper;
29-
import org.slf4j.Logger;
30-
import org.slf4j.LoggerFactory;
3121
import org.springframework.beans.factory.annotation.Autowired;
3222
import org.springframework.http.HttpMethod;
33-
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
34-
import org.springframework.security.web.util.matcher.OrRequestMatcher;
3523
import org.springframework.security.web.util.matcher.RequestMatcher;
3624
import org.springframework.stereotype.Component;
3725

38-
import com.vaadin.flow.router.RouteBaseData;
39-
import com.vaadin.flow.server.VaadinServlet;
40-
import com.vaadin.flow.server.VaadinServletService;
4126
import com.vaadin.flow.spring.security.RequestUtil;
4227
import com.vaadin.flow.spring.security.VaadinDefaultRequestCache;
4328

@@ -50,27 +35,17 @@
5035
@Component
5136
public class SecureVaadinRequestCache extends VaadinDefaultRequestCache
5237
{
53-
private static final Logger LOG = LoggerFactory.getLogger(SecureVaadinRequestCache.class);
54-
5538
protected static final RequestMatcher NONE_REQUEST_MATCHER = r -> false;
5639

57-
@Autowired
58-
protected ServletContext context;
59-
6040
@Autowired
6141
protected RequestUtil requestUtil;
6242

63-
// Shortcut to save computation cost (no path is longer than this)
64-
protected int defaultPathMaxLength = 255;
65-
protected int defaultWildcardPathLengthAssumption = 48;
66-
protected int pathMaxLength = this.defaultPathMaxLength;
6743
protected RequestMatcher allowedMatcher;
6844

6945
@Override
7046
public void saveRequest(final HttpServletRequest request, final HttpServletResponse response)
7147
{
7248
if(!HttpMethod.GET.matches(request.getMethod())
73-
|| request.getServletPath().length() > this.pathMaxLength
7449
|| !this.getAllowedPathsRequestMatcher().matches(request))
7550
{
7651
return;
@@ -79,21 +54,6 @@ public void saveRequest(final HttpServletRequest request, final HttpServletRespo
7954
super.saveRequest(request, response);
8055
}
8156

82-
public void setPathMaxLength(final int pathMaxLength)
83-
{
84-
this.pathMaxLength = pathMaxLength;
85-
}
86-
87-
public void setDefaultPathMaxLength(final int defaultPathMaxLength)
88-
{
89-
this.defaultPathMaxLength = defaultPathMaxLength;
90-
}
91-
92-
public void setDefaultWildcardPathLengthAssumption(final int defaultWildcardPathLengthAssumption)
93-
{
94-
this.defaultWildcardPathLengthAssumption = defaultWildcardPathLengthAssumption;
95-
}
96-
9757
protected RequestMatcher getAllowedPathsRequestMatcher()
9858
{
9959
if(this.allowedMatcher == null)
@@ -116,79 +76,11 @@ protected synchronized void initAllowedPaths()
11676
return;
11777
}
11878

119-
if(!(this.context.getServletRegistration("springServlet")
120-
instanceof final ApplicationServletRegistration applicationServletRegistration))
121-
{
122-
LOG.warn("Unable to find ApplicationServletRegistration");
123-
return;
124-
}
125-
126-
final Wrapper wrapper;
127-
try
128-
{
129-
final Field fWrapper = ApplicationServletRegistration.class.getDeclaredField("wrapper");
130-
fWrapper.setAccessible(true);
131-
wrapper = (Wrapper)fWrapper.get(applicationServletRegistration);
132-
}
133-
catch(final Exception e)
134-
{
135-
LOG.error("Failed to get Wrapper", e);
136-
this.allowedMatcher = NONE_REQUEST_MATCHER;
137-
return;
138-
}
139-
140-
if(!(wrapper instanceof final StandardWrapper standardWrapper)
141-
|| !(standardWrapper.getServlet() instanceof final VaadinServlet vaadinServlet))
142-
{
143-
LOG.warn("Unable to extract VaadinServlet from Wrapper");
144-
return;
145-
}
146-
147-
final VaadinServletService servletService = vaadinServlet.getService();
148-
if(servletService == null)
149-
{
150-
LOG.info("No servletService in servlet - Not initialized yet?");
151-
return;
152-
}
153-
154-
final Set<String> allowedPaths = servletService
155-
.getRouter()
156-
.getRegistry()
157-
.getRegisteredRoutes()
158-
.stream()
159-
.map(RouteBaseData::getTemplate)
160-
.filter(s -> !s.isBlank())
161-
.map(this.requestUtil::applyUrlMapping)
162-
.map(this::handleUrlParameterInPath)
163-
.collect(Collectors.toSet());
164-
165-
LOG.debug("Allowed paths: {}", allowedPaths);
166-
167-
this.pathMaxLength = allowedPaths.stream()
168-
.mapToInt(s -> s.length() + (s.endsWith("*") ? this.defaultWildcardPathLengthAssumption : 0))
169-
.max()
170-
.orElse(this.defaultPathMaxLength);
171-
172-
this.allowedMatcher = new OrRequestMatcher(allowedPaths
173-
.stream()
174-
.map(PathPatternRequestMatcher.withDefaults()::matcher)
175-
.map(RequestMatcher.class::cast)
176-
.toList());
79+
this.allowedMatcher = this.createAllowedPathsRequestMatcher();
17780
}
17881

179-
protected String handleUrlParameterInPath(final String path)
82+
protected RequestMatcher createAllowedPathsRequestMatcher()
18083
{
181-
final String urlParamIdentifier = "/:___url_parameter";
182-
final int urlParamIndex = path.indexOf(urlParamIdentifier);
183-
if(urlParamIndex == -1)
184-
{
185-
return path;
186-
}
187-
188-
final String substring = path.substring(0, urlParamIndex);
189-
return substring + "/*"
190-
// Do a full level wildcard if there is more stuff (excluding the optional ?)
191-
// behind the path-part
192-
+ (path.length() - substring.length() - urlParamIdentifier.length() <= 1 ? "" : "*");
84+
return this.requestUtil::isSecuredFlowRoute;
19385
}
19486
}

0 commit comments

Comments
 (0)