Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security 5 authentication always return 302

I'm using Spring-Security 5 to secure my web app. I access /login.jsp and fill in username and password, and then click "Log in" to submit the form, and then was redirected to /login.jsp. I see the reponse status code of that http traffic in fiddler is 302.

SecurityConfig class:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private DataSource dataSource;

    @Autowired
    protected SecurityConfig(DataSource dataSource
    ) {
        this.dataSource = dataSource;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login.jsp")
                .loginProcessingUrl("/login")
                .permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery("select name userName, password, enabled from user where name=?")
                .authoritiesByUsernameQuery("select name userName 'ROLE_USER' from user where name=?")
        ;
    }
}

login.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c"
           uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<c:url value="/login" var="loginUrl"/>
<form action="${loginUrl}" method="post"> 1
    <c:if test="${param.error != null}"> 2
        <p>
            Invalid username and password.
        </p>
    </c:if>
    <c:if test="${param.logout != null}"> 3
        <p>
            You have been logged out.
        </p>
    </c:if>
    <p>
        <label for="username">Username</label>
        <input type="text" id="username" name="username"/> 4
    </p>
    <p>
        <label for="password">Password</label>
        <input type="password" id="password" name="password"/> 5
    </p>
    <button type="submit" class="btn">Log in</button>
</form>
</body>
</html>
like image 716
AlpacaMan Avatar asked May 03 '18 14:05

AlpacaMan


People also ask

How does authentication work in Spring Security?

The Spring Security Architecture There are multiple filters in spring security out of which one is the Authentication Filter, which initiates the process of authentication. Once the request passes through the authentication filter, the credentials of the user are stored in the Authentication object.

Does Spring Security use default login form?

In this configuration Spring Security will render a default log in page. Most production applications will require a custom log in form. The configuration below demonstrates how to provide a custom log in form. public SecurityFilterChain filterChain(HttpSecurity http) { http .

What is the default authentication manager in Spring Security?

Spring Boot provides a default global AuthenticationManager (with only one user) unless you pre-empt it by providing your own bean of type AuthenticationManager . The default is secure enough on its own for you not to have to worry about it much, unless you actively need a custom global AuthenticationManager .


3 Answers

This is because spring default authentication success handler looks for a url to redirect. What one can do is use a custom AuthenticationSuccessHandler

i have used below and no redirects are happening.

public class AppAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{
    protected void handle(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
    }

}

Then define the bean and give it in the configure method for security

@Bean
public AuthenticationSuccessHandler appAuthenticationSuccessHandler(){
     return new AppAuthenticationSuccessHandler();
}

Configure method

http
  .authorizeRequests()
  .antMatchers("/login*")
  .permitAll()
  .anyRequest()
  .authenticated()
  .and()
  .formLogin()
  .successHandler(appAuthenticationSuccessHandler());
like image 189
BJ5 Avatar answered Oct 11 '22 15:10

BJ5


I had this problem until I turned csrf-check off by including .csrf().disable() in configure (HttpSecurity) method. If you don't have it off then provide csrf token as hidden form field.

... though I see that you have it off disabled

like image 26
Andrey M. Stepanov Avatar answered Oct 11 '22 15:10

Andrey M. Stepanov


  • the "loginPage url" same of the "form action"
  • show me code

java config:

http.formLogin().loginPage("/login.html")

html

<form action="/login.html" method="post"> 

you just need write controller for "/login.html", by http GET method, Leave the rest to “spring”

docs: https://docs.spring.io/spring-security/site/docs/5.3.6.RELEASE/reference/html5/#servlet-authentication-form

the UsernamePasswordAuthenticationFilter match /login.html by http POST method

My English is not good, Hope I can help you

like image 31
Feng Zhang Avatar answered Oct 11 '22 14:10

Feng Zhang