Reputation: 11
My hello world war file (Spring boot 3.1.1, jdk 17, jsf) was deployed in Tomcat 10.1.x. My xhtml files are under WEB-INF. Though I used correct username/password (log trace) to login at login.xhtml, the app just stayed at login screen instead of going to a default success url (test.xhtml). The security log trace had "Created SecurityContextImpl [Null authentication]", "HttpSessionSecurityContextRepository : Did not find SecurityContext in HttpSession using the SPRING_SECURITY_CONTEXT session attribute." It caused Granted Authorities=[ROLE_ANONYMOUS], then Access Denied. Security log trace:
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 604-04:00 TRACE 3980 --- [nio-8080-exec-8] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match request to [Is Secure] 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] 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>
I did some research: Spring Session - Security Context not found in session after redirect to target url
Spring boot Resource Not Found 404 error html
Make JSF resources publicly accessible with Spring Security
https://docs.spring.io/spring-security/reference/servlet/authentication/passwords/in-memory.html
Update: I tried to add a registry for /login. And rename login.xhtml to signin.xhtml
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
}
However, I got 405 METHOD_NOT_ALLOWED for /login
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
Update: I added this class. It worked.
@Controller
public class LoginController {
@GetMapping("/login")
String login() {
return "signin.xhtml";
}
}
Upvotes: 0
Views: 3670
Reputation: 820
I got a similar issue. After comparing with a working example, I found out the bean ChangeSessionIdAuthenticationStrategy was not executed. So, within flow exchange it cannot find the session and associate the user to Anonymous.
In my case I created a custom UsernamePasswordAuthenticationFilter which cause issue. Instead I created an AuthenticationProvider Bean to use the user/password differently.
I found this answer useful: StackOverflow
Upvotes: 0