You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot Security登录异常:HttpSession无SecurityContext,权限被拒

Spring Boot + JSF + Spring Security 登录后无法跳转问题解决

问题场景

基于Spring Boot 3.1.1、JDK 17、JSF开发的war包部署在Tomcat 10.1.x环境中,xhtml文件存放于WEB-INF目录下。使用正确用户名/密码在login.xhtml登录后,应用停留在登录页,无法跳转到默认成功页面test.xhtml。安全日志显示未找到HttpSession中的SecurityContext,最终权限被判定为ROLE_ANONYMOUS,触发Access Denied异常。

关键日志信息

533-04:00 DEBUG 3980 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy : Secured POST /login
543-04:00 DEBUG 3980 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : POST "/sbwar2/login", parameters={username:[user], password:[password], _csrf:[9cqHDzmNlsgTvrwCjfBK1gKrEB8YVEBLfuM0Te5Q3Lhh1DjTwq-yPA-49Pk-2t007t1-4TqbPScvN3FmG4YMfNpiut5Rtlvi]}
549-04:00 DEBUG 3980 --- [nio-8080-exec-8] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
604-04:00 DEBUG 3980 --- [nio-8080-exec-8] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
608-04:00 DEBUG 3980 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
609-04:00 TRACE 3980 --- [nio-8080-exec-8] w.c.HttpSessionSecurityContextRepository : Did not find SecurityContext in HttpSession 1204F5B756E65B39DA16CFE184630C21 using the SPRING_SECURITY_CONTEXT session attribute
610-04:00 TRACE 3980 --- [nio-8080-exec-8] .s.s.w.c.SupplierDeferredSecurityContext : Created SecurityContextImpl [Null authentication]
614-04:00 TRACE 3980 --- [nio-8080-exec-8] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=1204F5B756E65B39DA16CFE184630C21], Granted Authorities=[ROLE_ANONYMOUS]]
651-04:00 TRACE 3980 --- [nio-8080-exec-8] o.s.s.w.a.ExceptionTranslationFilter : Sending AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=1204F5B756E65B39DA16CFE184630C21], Granted Authorities=[ROLE_ANONYMOUS]] to authentication entry point since access is denied
org.springframework.security.access.AccessDeniedException: Access Denied
at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:98) ~[spring-security-web-6.1.1.jar:6.1.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ......................................

相关代码

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((requests) -> requests
                .requestMatchers("/", "/home","/jakarta.faces.resource/**", "/login", "/login.xhtml").permitAll()               
                .anyRequest().authenticated()
            )
            .formLogin((form) -> form
                    .loginPage("/login.xhtml")
                    .permitAll()
                    .defaultSuccessUrl("/test.xhtml", true)
                    .failureUrl("/login.xhtml?error-true")      
            )
            .cors(cors -> cors.disable())
            .logout((logout) -> logout.permitAll());
        return http.build();
    }
    @Bean
    public UserDetailsService users() {
        UserDetails user = User.builder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(user);
    }   
}

login.xhtml

<form action="${request.contextPath}/login" method="POST">
<div align="center"><h:outputLabel styleClass="fa fa-2x" value="Sign in"/></div><br/>                       
<div align="center">
    <h:outputLabel class="alert alert-danger" value="Invalid user name or password" rendered="${not empty SPRING_SECURITY_LAST_EXCEPTION.message}"/>
</div>                           
<div class="input-group input-sm">
    <label class="input-group-addon" for="username"><i class="fa fa-user"></i></label>
    <input type="text" class="form-control" id="username" name="username" placeholder="Username" required="true"  autofocus="true"/>
</div>
<div class="input-group input-sm">
    <label class="input-group-addon" for="password"><i class="fa fa-lock"></i></label> 
    <input type="password" class="form-control" id="password" name="password" placeholder="Password" required="true"/>
</div>
<input type="hidden" name="${_csrf.parameterName}"  value="${_csrf.token}" />
<div class="form-group">
    <input type="submit" class="btn btn-block btn-primary btn-default" value="Log in"/>
</div>
</form>

test.xhtml

<h:body>
This is a test
</h:body>

尝试过程及问题

尝试添加视图控制器并将login.xhtml重命名为signin.xhtml:

@Configuration
public class MvcConfig implements WebMvcConfigurer {
   @Override
   public void addViewControllers(ViewControllerRegistry registry) {
      registry.addViewController("/login").setViewName("login");
   }
}

此时访问/login出现405 METHOD_NOT_ALLOWED错误:

DEBUG 11512 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : Secured POST /login
DEBUG 11512 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : POST "/sbwar2/login", parameters={username:[user], password:[password],
......
WARN 11512 --- [nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' is not supported]
DEBUG 11512 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : Completed 405 METHOD_NOT_ALLOWED

最终解决方法

添加如下控制器类:

@Controller
public class LoginController {
   @GetMapping("/login")
   String login() {
      return "signin.xhtml";
   } 
}

内容的提问来源于stack exchange,提问作者dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 18:40:03