Spring Security redirecting custom login page to itself - Too Many Redirects - spring-boot

I'm currently developing a custom login-page for my Spring Boot Application but I just can't get it to work. Using the default one works fine but as soon as I try to use my custom file, it just repeatedly redirects me until my Browser give up.
Other posts suggest permitting access to the login-path to erveryone but this also doesn't seem to work.
Here is my code:
WebSecurityConfig
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
And Controller for login-page
#Controller
public class WebController {
#GetMapping("/login")
public String login () {
return "login";
}
}
Any ideas what I'm missing?

You are probably using a lot of CSS and JS file link links, according to your code Spring Boot must first authenticate all the links, which is why it redirects to your login page many times.
add following code to bypass security authentication of resource link
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers("/bower_components/**", "/dist/**", "/plugins/**"); //write your resource directory name
}

Related

Simple Spring Security Authentication [duplicate]

Can't navigate from index.html to any other page, when clicking the button to navigate a blank login file is downloaded. I think this problem is linked to security file because at the beginning I didn't had it but after adding it many things have been broken.
This is the html code :
Log In
And this is security file :
#Configuration
#EnableWebSecurity
public class Security extends WebSecurityConfigurerAdapter{
// https://spring.io/guides/gs/securing-web/
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/","/register","/login","/css/**", "/js/**", "/images/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder(11);
}
}
There is a login.html file in templates.
As soon as you override the default login page by specifying .loginPage(some_string), then the Spring Security default login configuration will be deactivated.
It does not matter what the value of some_string is, it is considered a custom login page even if the value is "/login".
In other words, with your current configuration, when you are overriding the default login page, Spring Security expects you to create the mapping for your custom login endpoint.
As Ratul Sharker said in the comment above, you need to add a #GetMapping("/login") that returns your custom login page.

Spring boot how to have Thymeleaf web page and REST API with different authentications Schemes

Like the question said, how we can configure Spring Security to have form authentication for the Thymeleaf web page part of the project, and JWT authentication for the REST API part of the project?, because we like to have both projects on the same container and not to have to resource to external Tomcat Application Server to have the same Security Config (SSL, Ciphers, Certificates, ETC.).
So far we don't found how to do it, but if you can have a Thymeleaf and REST API on the same project i think it is possible to configure Spring Security to have to ways of authentication on the project.
You can have this behavior by adding two WebSecurityConfigurerAdapter beans as follows:
#Order(1) - /api/** protected by basic auth, in your case JWT
authentication.
#Order(2) - /website/** protected by form login, in your case
Thymeleaf login.
View docs for Spring Boot and sample code here.
#EnableWebSecurity
public class SecurityConfig {
#Configuration
#Order(1)
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().hasRole("API_USER")
.and()
.httpBasic();
}
}
#Configuration
#Order(2)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/website/**").hasRole("ADMIN")
.and()
.formLogin()
.and()
.logout().permitAll()
;
}
}
}

Spring Security - Redirect to custom login page without going through controller

I am currently using Spring Boot + Spring Security to develop a simple website that need user to login to access it. I have created my own custom static login page under resources/templates1/bruceLogin1.html. Any unathenticated access to my website to first be redirected to the login page URL which is http://localhost:8080/templates1/bruceLogin1.html
Note: that I am NOT creating any controller for this login URL, hence I am expecting the bruceLogin1.html to be accessed directly bypassing controller. Because i directly allow access to this html page without going thru controller, I assume no view resolver (e.g thymleaf) is required.
I open my browser, and enter http://localhost:8080/blablabl, and browser redirect me to http://localhost:8080/templates1/bruceLogin1.html , but sadly, i got error
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat Jan 11 12:40:37 SGT 2020
There was an unexpected error (type=Not Found, status=404).
No message available
Below is my configuration,
#SpringBootApplication
#EnableWebSecurity
public class SpringSecurityCatalogApplication implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(SpringSecurityCatalogApplication.class, args);
}
#EnableWebSecurity
#Order(Ordered.HIGHEST_PRECEDENCE)
class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/templates1/bruceLogin1.html")
.permitAll();
}
}
}
Think instead of putting under resources/template1 folder, i will just put the custom login page into either resources/static or resources/public folder.
Then configure as shown below
#EnableWebSecurity
#Order(Ordered.HIGHEST_PRECEDENCE)
class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/bruceLogin1.html")
.permitAll();
}
}
Open browser and access any URL, you will be redirected to http://localhost:8080/bruceLogin1.html. And thats it!
Note that this does not require any controller nor view resolver.

Spring Boot+Thymeleaf doesn't resolve login.html

I have basically copied the tutorial to use Spring Web Security with Spring Boot and Thymeleaf. https://spring.io/guides/gs/securing-web/
For configuration:
#Configuration
public class WebConfig implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/").setViewName("home");
}}
For security in public class WebSec extends WebSecurityConfigurerAdapter:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.antMatchers("/users*").hasRole("ADMIN")
.antMatchers("/users/*").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll();
}
All html files are under
/src/main/resources/templates
Now, home.html is found nicely. However whenever anything requires the login page, the login.html in the same folder is not found and the error is:
Error resolving template "login", template might not exist or might not be accessible by any of the configured Template Resolvers
I'm not sure how to proceed from here.
Solution: Do not call your template files the same as your routes. The problem can be solved by naming the file login_template.html or something. Or even better, change the line:
registry.addViewController("/login").setViewName("login");
to just
registry.addViewController("/login");
I found a hint to this behaviour in the javadocs for ViewControllerRegistration.setViewName.

Spring Boot 2 Security downloading font file upon login

I've setup a spring boot 2 application with a login form, however, when you login, instead of redirecting to /admin like it's supposed to, it downloads a font file referenced by the stylesheet via an #import.
Here is my security setup;
#Configuration
#EnableWebSecurity()
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserService userService;
#Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
// These pages don't require the user to be logged in
http.authorizeRequests()
.antMatchers("/", "/login", "/logout", "/report/**").permitAll()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.anyRequest().authenticated();
// When the user has logged in as XX.
// But access a page that requires role YY,
// AccessDeniedException will be thrown.
http.authorizeRequests().and().exceptionHandling().accessDeniedPage("/403");
// Config for Login Form
http.authorizeRequests().and().formLogin()//
// Submit URL of login page.
.loginProcessingUrl("/j_spring_security_check") // Submit URL
.loginPage("/login")//
.defaultSuccessUrl("/admin")//
.failureUrl("/login?error=true")//
.usernameParameter("username")//
.passwordParameter("password")
// Config for Logout Page
.and().logout().logoutUrl("/logout").logoutSuccessUrl("/login?logout=true");
}
}
Where am I going wrong? From what I can see, I'm enabling access to Spring resources that are stored in the static folder.
I figured this one out, I read the code that allows access to resources and noticed it said 'atCommonLocations', and guess this adds access to folders such as css, js, img, images etc. I had fonts in a folder labelled webfonts, so I updated my security configuration;
http.authorizeRequests()
.antMatchers("/", "/login", "/logout", "/report/**", "/webfonts/**").permitAll()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.anyRequest().authenticated();

Resources