I'm trying to create a simple spring boot app with spring security, with custom login form.
Issue: The app directly opens the default login page instead of the custom login view & it could not resolve any of the other thymeleaf views too.
Directly accessing all other views (/home
, /error
) renders the error: This localhost page can't be found.
Opening http://localhost:8080/login
takes only to the default login page & not the custom one.
Note: The html templates are placed under /src/main/resources/templates folder - which is the default place springboot looks into.
The key thing here is that I am using the
@EnableWebSecurity
annotation, withSecurityFilterChain
bean (which is introduced inSpring Security 5.4
), like this:
@EnableWebSecurity public class WebSecurityConfig { @Bean public SecurityFilterChain configure(HttpSecurity http) throws Exception { ... }
instead of the more common (but, has been deprecated since
Spring Security 5.7.0-M2
) way of extending theWebSecurityConfigurerAdapter
class as below.@Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { ... }
It seems the latter works fine without any issues.
Few of the solutions suggested in various forums - which I have already tried.
- Keep the project structure in a way that all the other packages are placed under the base package (the one with the main class with
@SprintBootApplication
annotation). - Use
@ComponentScan={<your_base_package>}
- if packages are in the order mentioned in point 1. Or,@ComponentScan={<package-1>, <package-2>, etc}
, if the packages are independent of each other.
Both the above solutions were suggested to avoid the 404 error & view not resolved issues. - Use
@RestController
instead of@Controller
.
This was suggested both for WhiteLabel error, and when the view name is returned just as a string, instead of a view. - Keep the mapping url value in the controller methods (like,
/login
) & the the view name different. If the mapping url as/login
, change the view name asloginpage.html
(or, something different).
This was suggested for circular path issues - when resolving view names. - Some suggested using
@RequestMapping("/login")
at class-level, rather than method-level. Although, I didn't see any difference with either approach.
Note that all of the above are based on WebSecurityConfigurerAdapter
& not on SecurityFilterChain
.
The only references from the official documentation/blogs, that I could find for this requirement (custom login with
SecurityFilterChain
) were these two:Extract from the logs - that I found relative/worth-noting.
Check the "..invalid session id..." and "..Failed to authorize filter invocation..." parts.2022-08-18 12:09:43.297 INFO 16596 --- [http-nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 10 ms 2022-08-18 12:09:43.334 DEBUG 16596 --- [http-nio-8080-exec-1] o.s.security.web.FilterChainProxy : Securing GET / 2022-08-18 12:09:43.351 DEBUG 16596 --- [http-nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext 2022-08-18 12:09:43.363 DEBUG 16596 --- [http-nio-8080-exec-1] ****o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext 2022-08-18 12:09:43.364 DEBUG 16596 --- [http-nio-8080-exec-1] o.s.s.w.session.SessionManagementFilter : Request requested invalid session id EF53E44688D581C69527A5442A987DB6 2022-08-18 12:09:43.394 DEBUG 16596 --- [http-nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [GET /] with attributes [authenticated] 2022-08-18 12:09:43.445 DEBUG 16596 --- [http-nio-8080-exec-1] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:8080/ to session**** 2022-08-18 12:09:43.448 DEBUG 16596 --- [http-nio-8080-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.HeaderContentNegotiationStrategy@51020050, matchingMediaTypes=[application/xhtml xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]] 2022-08-18 12:09:43.450 DEBUG 16596 --- [http-nio-8080-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@416ee886 2022-08-18 12:09:43.454 DEBUG 16596 --- [http-nio-8080-exec-1] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:8080/login 2022-08-18 12:09:43.459 DEBUG 16596 --- [http-nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext 2022-08-18 12:09:43.466 DEBUG 16596 --- [http-nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext 2022-08-18 12:09:43.466 DEBUG 16596 --- [http-nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request 2022-08-18 12:09:43.487 DEBUG 16596 --- [http-nio-8080-exec-2] o.s.security.web.FilterChainProxy : Securing GET /login
Complete log here: https://codeshare.io/dwlLDK
(Seems it'd live for only 24 hrs. Pls. let me know if you couldn't access it).Edit(2022-08-22): An excerpt from the
application.properties
file (just the thymeleaf & security config) - which is the reason for the issue (as explained in the accepted [self-identified] answer).# thymeLeaf spring.thymeleaf.enabled=true spring.thymeleaf.cache=false spring.thymeleaf.check-template=true spring.thymeleaf.check-template-location=true spring.thymeleaf.prefix=classpath:/templates spring.thymeleaf.suffix=.html #security server.error.whitelabel.enabled=false
CodePudding user response:
I have an example Spring Boot application here: https://github.com/Aliuken/JobVacanciesApp_Java11
Hope that it helps.
CodePudding user response:
I fixed the issue myself.
(Adding it as an accepted answer, so that it's easy for people who stumble upon this page.)
The actual issue was a missing trailing
/
in the thymeleaf prefix config, in theapplication.properties
file:spring.thymeleaf.prefix=classpath:/templates
.This should have been
spring.thymeleaf.prefix=classpath:/templates/
.Once I added it, it started recognizing the templates (including the custom login template/view).