Hi I am working on a Spring boot web application in which I am using Spring security and for views I am using JSP pages. when trying to access the pages configured with permitall() that is home page and login page I am getting this error on the browser and nothing is printed on the console. so after adding a logger, I got to know that the controller function is getting called repeatedly below is my code and console screenshot for reference can you please let me know what I am doing wrong here?
Application.properties file for JSP pages
server.error.path=/error
spring.mvc.view.prefix: /WEB-INF/views/
spring.mvc.view.suffix: .jsp
PageController
@Controller
@RequestMapping(value = "/swadeshiBank/v1")
public class PageController {
public static final Logger logger = LogManager.getLogger(PageController.class);
private static final String loginPage = "login";
@GetMapping(value = "/")
public String homePage(){
logger.info("Request Came to home :");
return "home";
}
@GetMapping(value = "/login")
public String getLoginPage(){
logger.info("Request Came to login :");
return loginPage;
}
}
Security Configuration
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/", "/swadeshiBank/v1/", "/swadeshiBank/v1/login").permitAll() // Public pages
.requestMatchers("/swadeshiBank/v1/account-details").authenticated() // Authenticated users
.requestMatchers("/swadeshiBank/v1/admin").hasRole("ADMIN") // Admin users
.requestMatchers("/swadeshiBank/v1/management").hasRole("MANAGER") // Manager users
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/swadeshiBank/v1/login")
.loginProcessingUrl("/swadeshiBank/v1/login") // URL to submit the login form
.defaultSuccessUrl("/swadeshiBank/v1/account-details", true)
.permitAll()
)
.logout(logout -> logout
.logoutRequestMatcher(new AntPathRequestMatcher("/swadeshiBank/v1/logout"))
.logoutSuccessUrl("/swadeshiBank/v1/login?logout")
.invalidateHttpSession(true)
.permitAll()
);
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user")
.password("{noop}password")
.roles("USER")
.build());
manager.createUser(User.withUsername("admin")
.password("{noop}admin")
.roles("ADMIN")
.build());
manager.createUser(User.withUsername("manager")
.password("{noop}manager")
.roles("MANAGER")
.build());
return manager;
}
}
Project Structure
Can you please help me here? additionally, Current behaviour what I noticed when I type
http://localhost:8080/ in browser it takes me to http://localhost:8080/swadeshiBank/v1/login but I want the landing page should be http://localhost:8080/swadeshiBank/v1/ and login page should only appear when I click on login button.
When you set your spring-security logger to DEBUG
, you can see that spring tries to access login.jsp
as a secured resource, meaning it locks the file behind its security features.
Since the file-url /WEB-INF/views/login.jsp
is not recognized by any request-matchers you defined, it is only allowed for authenticated users, as that is what you set for anyRequest()
in your http.authorizeHttpRequests()
lambda-function. This still allows the /login
url to be accessed without authentication, but the request to the login.jsp
file is getting blocked by spring. Whenever spring blocks a request, it redirects the user to the login-page. Since you re-routed the /login
url to your custom endpoint, this would loop forever if there weren't a hard limit for the amount of redirects.
To solve your issue, it should suffice to add the /WEB-INF/views/login.jsp
resource-endpoint to your request-matchers that have the permitAll()
option, like so:
// Class and stuff above
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/", "/swadeshiBank/v1/", "/swadeshiBank/v1/login", "/WEB-INF/views/login.jsp").permitAll() // Public pages
.requestMatchers("/swadeshiBank/v1/account-details").authenticated() // Authenticated users
.requestMatchers("/swadeshiBank/v1/admin").hasRole("ADMIN") // Admin users
.requestMatchers("/swadeshiBank/v1/management").hasRole("MANAGER") // Manager users
.anyRequest().authenticated()
)
// Your form-login-settings
// Your logout-settings
return http.build();
}
// Stuff below the method