E
E
EgorSvinarev2021-07-18 16:09:42
Java
EgorSvinarev, 2021-07-18 16:09:42

Why is authorization not happening in Spring security?

Good day. I am writing a pet project using the Spring family of frameworks. I came across the following problem when configuring application security through Spring Security: when submitting a form from a template written in Thymeleaf, it redirects to the authorization page specified in the config, as if authentication was not performed. The authentication process is based on credentials from the database.
Here I am

config
:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Bean
  public BCryptPasswordEncoder getPasswordEncoder() {
    return new BCryptPasswordEncoder();
  }
  
  @Autowired
  public AuthenticationProvider authProvider;
  
    @Override
    protected void configure(HttpSecurity security) throws Exception
    {
    	security.csrf().disable()
    		.authorizeRequests()
    			.antMatchers("/").permitAll()
    			.antMatchers("/login").permitAll()
    			.antMatchers("/register").permitAll()
    			.antMatchers("/account").hasAnyAuthority("ADMIN", "STUDENT", "TEACHER")
    			.antMatchers("/scripts/**", "/css/**", "/img/**", "/fonts/**").permitAll()
    		.anyRequest().authenticated()
    		.and()
    			.formLogin()
    			.loginPage("/auth")
    			.defaultSuccessUrl("/account")
    			.permitAll()
    		.and()
    			.logout()
    			.permitAll()
    			.logoutSuccessUrl("/");
    			
    }
    
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    	auth.authenticationProvider(authProvider);
    }
    
}

I also attach the implementation of the interface
AuthProvider

@Component
public class AuthProviderAdapter implements AuthenticationProvider {

  @Autowired
  private BCryptPasswordEncoder encoder;
  
  @Autowired
  private UserDetailsService service;
  
  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    String username = authentication.getName();
    String password = authentication.getCredentials().toString();
    
    System.out.println(username);
    System.out.println(password);
    
    UserDetails u = service.loadUserByUsername(username);
  
    if (!encoder.matches(u.getPassword(), password)) {
      throw new BadCredentialsException("Invalid credentials.");
    }
    
    return new UsernamePasswordAuthenticationToken(username, password, u.getAuthorities());
  }

  @Override
  public boolean supports(Class<?> authentication) {
    return authentication.equals(UsernamePasswordAuthenticationToken.class);
  }	
}



shape on thymeleaf

<form action="@{/login}" class="form_" id="auth__form" method="post">
  <div class="auth__fields">
    <input type="text" class="field" placeholder="Логин" name="login"><br>
    <input type="password" class="field" placeholder="Пароль" name="password">
  </div>
    <div class="auth__error" th:if="${errorCode}">
      <span th:text="${info}"></span>
    </div>
    <div class="auth__links">
      <a href="#toregister" class="link">Зарегистрироваться</a><br>
      <a href="#tochangepassword" class="link">Вы забыли пароль?</a><br>
    </div>
</form>



and
controllers

@Controller
@RequestMapping(value = "/login")
public class LoginController {

  @PostMapping
  public void login() {
    System.out.println("YES");
  }
  
}

@Controller
@RequestMapping(value = "/auth")
public class AuthPageController {

  @GetMapping
  public String getView() {
    return "auth";
  }
  
  @PostMapping
  public void abc() {
    System.out.println(1);
  }
  
}



I need the data specified in the form to be passed to the AuthProvider, and authorization is performed based on the Authentication object returned from the authenticate method. I tried to find the answer in the book Spring Security in Action, but, unfortunately, there is an example only with the standard login-page that comes with Spring security, and in-memory-authentication.
I would appreciate any advice and links.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
O
Orkhan, 2021-07-18
@EgorSvinarev

Good afternoon.
I'll make a bold assumption:
Here, here you allowed sending requests to url/login

.antMatchers("/").permitAll()
    			.antMatchers("/login").permitAll()

And here you say that the authentication page is /auth
.loginPage("/auth")
In the form you send a request to action="@{/auth}"A, you are simply not allowed to send a request to the specified url and you will receive 403 permission denied.
Add to config:
.antMatchers("/auth").permitAll()

E
EgorSvinarev, 2021-07-19
@EgorSvinarev

Found an error. I forgot to put the prefix from thymeleaf in the action attribute, and requests were sent to the wrong url

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question