我试图在Sping Boot 3.1.1上使用Spring Security和MVC视图运行新应用程序,但不知道如何正确编写安全规则。我的控制器如下:
@Controller
@RequestMapping("/")
public class StubController {
@GetMapping("test")
public ModelAndView test() {
return new ModelAndView("test");
}
}
我尝试了多种安全配置选项。下面是不工作的选项(给出403错误),除非我添加/WEB-INF/view/test.jsp
:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(requests -> requests
.requestMatchers("/login*").permitAll()
.requestMatchers("/test").hasAuthority(Permission.TEST.getAuthority()))
.formLogin(Customizer.withDefaults())
.logout(Customizer.withDefaults());
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
基于此,我发现需要两个Map才能使其工作:在requestMatchers中列出"/test"
和"/WEB-INF/view/test.jsp"
页面(我在config中为test设置了.jsp作为mvc视图后缀,并将/WEB-INF/view/作为前缀)。我做了一些搜索,发现在Spring Security中有一个MVC处理的接口,所以我也尝试了这种方式:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
MvcRequestMatcher mvcMatcher = new MvcRequestMatcher.Builder(introspector).pattern("/test");
http.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(requests -> requests
.requestMatchers("/login*").permitAll()
.requestMatchers(mvcMatcher).hasAuthority(Permission.TEST.getAuthority()))
.formLogin(Customizer.withDefaults())
.logout(Customizer.withDefaults());
return http.build();
}
它的工作方式与前面的代码片段不同。
那么我在问什么--如何正确地为这种情况编写规则,避免通配符或带有“.jsp”后缀的模式重复?如果你能解释一下它是如何工作的。我完全失去了在这一点上,因为我发现很少有帮助的来源对这个问题,所以任何帮助将不胜感激!
更新:添加了跟踪日志(也用.jsp替换了原始的.html以进行测试,并稍微更改了描述)
2023-06-29T01:47:49.991+03:00 INFO 16428 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-06-29T01:47:49.991+03:00 INFO 16428 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-06-29T01:47:49.991+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.multipart.support.StandardServletMultipartResolver@5dd369cc
2023-06-29T01:47:49.991+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver@20e61bf
2023-06-29T01:47:49.991+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.theme.FixedThemeResolver@1ce7b45c
2023-06-29T01:47:49.991+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Detected DefaultRequestToViewNameTranslator
2023-06-29T01:47:49.993+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Detected SessionFlashMapManager
2023-06-29T01:47:49.993+03:00 DEBUG 16428 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2023-06-29T01:47:49.993+03:00 INFO 16428 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
2023-06-29T01:47:50.005+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.session.DisableEncodeUrlFilter@7fddfcb1, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@7a03309b, org.springframework.security.web.context.SecurityContextHolderFilter@6f3fb6bb, org.springframework.security.web.header.HeaderWriterFilter@6edddb96, org.springframework.security.web.authentication.logout.LogoutFilter@91b5ed5, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@4bd9d049, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@3c4a5564, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@16073dd1, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@46befeb1, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@19e01051, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@4df8278e, org.springframework.security.web.access.ExceptionTranslationFilter@4653896, org.springframework.security.web.access.intercept.AuthorizationFilter@502b2f45]] (1/1)
2023-06-29T01:47:50.006+03:00 DEBUG 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Securing GET /test
2023-06-29T01:47:50.007+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking DisableEncodeUrlFilter (1/13)
2023-06-29T01:47:50.007+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking WebAsyncManagerIntegrationFilter (2/13)
2023-06-29T01:47:50.010+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderFilter (3/13)
2023-06-29T01:47:50.011+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking HeaderWriterFilter (4/13)
2023-06-29T01:47:50.014+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking LogoutFilter (5/13)
2023-06-29T01:47:50.014+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.s.w.a.logout.LogoutFilter : Did not match request to Or [Ant [pattern='/logout', GET], Ant [pattern='/logout', POST], Ant [pattern='/logout', PUT], Ant [pattern='/logout', DELETE]]
2023-06-29T01:47:50.015+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking UsernamePasswordAuthenticationFilter (6/13)
2023-06-29T01:47:50.015+03:00 TRACE 16428 --- [nio-8080-exec-1] w.a.UsernamePasswordAuthenticationFilter : Did not match request to Ant [pattern='/login', POST]
2023-06-29T01:47:50.015+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking DefaultLoginPageGeneratingFilter (7/13)
2023-06-29T01:47:50.015+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking DefaultLogoutPageGeneratingFilter (8/13)
2023-06-29T01:47:50.015+03:00 TRACE 16428 --- [nio-8080-exec-1] .w.a.u.DefaultLogoutPageGeneratingFilter : Did not render default logout page since request did not match [Ant [pattern='/logout', GET]]
2023-06-29T01:47:50.015+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking RequestCacheAwareFilter (9/13)
2023-06-29T01:47:50.015+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.s.w.s.HttpSessionRequestCache : matchingRequestParameterName is required for getMatchingRequest to lookup a value, but not provided
2023-06-29T01:47:50.015+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderAwareRequestFilter (10/13)
2023-06-29T01:47:50.017+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking AnonymousAuthenticationFilter (11/13)
2023-06-29T01:47:50.017+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking ExceptionTranslationFilter (12/13)
2023-06-29T01:47:50.017+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking AuthorizationFilter (13/13)
2023-06-29T01:47:50.017+03:00 TRACE 16428 --- [nio-8080-exec-1] estMatcherDelegatingAuthorizationManager : Authorizing SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@268cfcc4]
2023-06-29T01:47:50.029+03:00 TRACE 16428 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to ru.trainithard.learningapp.controller.StubController#test()
2023-06-29T01:47:50.031+03:00 TRACE 16428 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to ru.trainithard.learningapp.controller.StubController#test()
2023-06-29T01:47:50.032+03:00 TRACE 16428 --- [nio-8080-exec-1] estMatcherDelegatingAuthorizationManager : Checking authorization on SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@268cfcc4] using AuthorityAuthorizationManager[authorities=[TEST]]
2023-06-29T01:47:50.034+03:00 TRACE 16428 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : Retrieved SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=ru.trainithard.learningapp.model.User@54391ce, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=B02D0007163E6B581F541EA6F79511C1], Granted Authorities=[MANAGE_USERS, TEST]]] from SPRING_SECURITY_CONTEXT
2023-06-29T01:47:50.034+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Did not set SecurityContextHolder since already authenticated UsernamePasswordAuthenticationToken [Principal=ru.trainithard.learningapp.model.User@54391ce, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=B02D0007163E6B581F541EA6F79511C1], Granted Authorities=[MANAGE_USERS, TEST]]
2023-06-29T01:47:50.035+03:00 DEBUG 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Secured GET /test
2023-06-29T01:47:50.037+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/test", parameters={}, headers={masked} in DispatcherServlet 'dispatcherServlet'
2023-06-29T01:47:50.039+03:00 TRACE 16428 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to ru.trainithard.learningapp.controller.StubController#test()
2023-06-29T01:47:50.054+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.web.method.HandlerMethod : Arguments: []
2023-06-29T01:47:50.056+03:00 TRACE 16428 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerAdapter : Applying default cacheSeconds=-1
2023-06-29T01:47:50.065+03:00 DEBUG 16428 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, */*;q=0.8, application/signed-exchange;v=b3;q=0.7]
2023-06-29T01:47:50.065+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.web.servlet.view.InternalResourceView: name 'test'; URL [/WEB-INF/view/test.jsp]]
2023-06-29T01:47:50.065+03:00 DEBUG 16428 --- [nio-8080-exec-1] o.s.w.servlet.view.InternalResourceView : View name 'test', model {}
2023-06-29T01:47:50.068+03:00 DEBUG 16428 --- [nio-8080-exec-1] o.s.w.servlet.view.InternalResourceView : Forwarding to [/WEB-INF/view/test.jsp]
2023-06-29T01:47:50.070+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.session.DisableEncodeUrlFilter@7fddfcb1, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@7a03309b, org.springframework.security.web.context.SecurityContextHolderFilter@6f3fb6bb, org.springframework.security.web.header.HeaderWriterFilter@6edddb96, org.springframework.security.web.authentication.logout.LogoutFilter@91b5ed5, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@4bd9d049, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@3c4a5564, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@16073dd1, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@46befeb1, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@19e01051, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@4df8278e, org.springframework.security.web.access.ExceptionTranslationFilter@4653896, org.springframework.security.web.access.intercept.AuthorizationFilter@502b2f45]] (1/1)
2023-06-29T01:47:50.070+03:00 DEBUG 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Securing GET /WEB-INF/view/test.jsp
2023-06-29T01:47:50.070+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking DisableEncodeUrlFilter (1/13)
2023-06-29T01:47:50.070+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking WebAsyncManagerIntegrationFilter (2/13)
2023-06-29T01:47:50.070+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderFilter (3/13)
2023-06-29T01:47:50.071+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking HeaderWriterFilter (4/13)
2023-06-29T01:47:50.071+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking LogoutFilter (5/13)
2023-06-29T01:47:50.071+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.s.w.a.logout.LogoutFilter : Did not match request to Or [Ant [pattern='/logout', GET], Ant [pattern='/logout', POST], Ant [pattern='/logout', PUT], Ant [pattern='/logout', DELETE]]
2023-06-29T01:47:50.071+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking UsernamePasswordAuthenticationFilter (6/13)
2023-06-29T01:47:50.071+03:00 TRACE 16428 --- [nio-8080-exec-1] w.a.UsernamePasswordAuthenticationFilter : Did not match request to Ant [pattern='/login', POST]
2023-06-29T01:47:50.071+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking DefaultLoginPageGeneratingFilter (7/13)
2023-06-29T01:47:50.071+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking DefaultLogoutPageGeneratingFilter (8/13)
2023-06-29T01:47:50.072+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking RequestCacheAwareFilter (9/13)
2023-06-29T01:47:50.072+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.s.w.s.HttpSessionRequestCache : matchingRequestParameterName is required for getMatchingRequest to lookup a value, but not provided
2023-06-29T01:47:50.072+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderAwareRequestFilter (10/13)
2023-06-29T01:47:50.072+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking AnonymousAuthenticationFilter (11/13)
2023-06-29T01:47:50.072+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking ExceptionTranslationFilter (12/13)
2023-06-29T01:47:50.072+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking AuthorizationFilter (13/13)
2023-06-29T01:47:50.072+03:00 TRACE 16428 --- [nio-8080-exec-1] estMatcherDelegatingAuthorizationManager : Authorizing SecurityContextHolderAwareRequestWrapper[ FirewalledRequest[ SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@268cfcc4]]]
2023-06-29T01:47:50.077+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to HandlerExecutionChain with [ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]] and 4 interceptors
2023-06-29T01:47:50.078+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to HandlerExecutionChain with [ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]] and 4 interceptors
2023-06-29T01:47:50.080+03:00 TRACE 16428 --- [nio-8080-exec-1] estMatcherDelegatingAuthorizationManager : Denying request since did not find matching RequestMatcher
2023-06-29T01:47:50.080+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Did not set SecurityContextHolder since already authenticated UsernamePasswordAuthenticationToken [Principal=ru.trainithard.learningapp.model.User@54391ce, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=B02D0007163E6B581F541EA6F79511C1], Granted Authorities=[MANAGE_USERS, TEST]]
2023-06-29T01:47:50.080+03:00 TRACE 16428 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter : Sending UsernamePasswordAuthenticationToken [Principal=ru.trainithard.learningapp.model.User@54391ce, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=B02D0007163E6B581F541EA6F79511C1], Granted Authorities=[MANAGE_USERS, TEST]] to access denied handler since access is denied
----- at this point exception acess denied is thrown -----
1条答案
按热度按时间xqnpmsa81#
我终于找到解决办法了。根据Spring 6.0之后的文档,Spring Security开始默认评估所有servlet请求。我已经解决了将
.dispatcherTypeMatchers(DispatcherType.FORWARD).permitAll()
行添加到安全配置的问题。