1515 */
1616package 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 ;
2318import jakarta .servlet .http .HttpServletRequest ;
2419import 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 ;
3121import org .springframework .beans .factory .annotation .Autowired ;
3222import org .springframework .http .HttpMethod ;
33- import org .springframework .security .web .servlet .util .matcher .PathPatternRequestMatcher ;
34- import org .springframework .security .web .util .matcher .OrRequestMatcher ;
3523import org .springframework .security .web .util .matcher .RequestMatcher ;
3624import 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 ;
4126import com .vaadin .flow .spring .security .RequestUtil ;
4227import com .vaadin .flow .spring .security .VaadinDefaultRequestCache ;
4328
5035@ Component
5136public 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