【问题标题】:Spring Security 5 authentication always return 302Spring Security 5 身份验证总是返回 302
【发布时间】:2018-10-13 22:29:14
【问题描述】:

我正在使用 Spring-Security 5 来保护我的 Web 应用程序。我访问/login.jsp并填写用户名和密码,然后单击“登录”提交表单,然后被重定向到/login.jsp。我看到fiddler中那个http流量的响应状态码是302。

SecurityConfig 类:

@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>

【问题讨论】:

    标签: spring spring-mvc spring-security


    【解决方案1】:
    • “loginPage url”与“表单操作”相同
    • 显示代码

    java 配置:

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

    html

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

    你只需要为“/login.html”编写控制器,通过http GET方法,剩下的交给“spring”

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

    UsernamePasswordAuthenticationFilter /login.html 匹配 http POST method

    我的英文不好,希望能帮到你

    【讨论】:

      【解决方案2】:

      我不知道这个问题是否一直存在,但如果这可以帮助某人......

      对我有用的是替换

      .formLogin()
      

      通过

      .httpBasic();
      

      在我的 WebSecurityConfigurerAdapter 类中。

      所以我的安全配置看起来像这样:

      protected void configure(final HttpSecurity http) throws Exception {
          http.authorizeRequests()
                  .antMatchers("/login", "/actuator/**", "/clients/refresh", "/oauth/token/revokeById/**", "/tokens/**")
                  .permitAll()
                  .anyRequest()
                  .authenticated()
                  .and()
                  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                  .and()
                  .httpBasic();
      }
      

      【讨论】:

        【解决方案3】:

        这是因为 Spring 默认的身份验证成功处理程序会查找要重定向的 url。 可以做的是使用自定义 AuthenticationSuccessHandler

        我在下面使用过,但没有发生重定向。

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

        然后定义bean并在configure方法中给出安全性

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

        配置方法

        http
          .authorizeRequests()
          .antMatchers("/login*")
          .permitAll()
          .anyRequest()
          .authenticated()
          .and()
          .formLogin()
          .successHandler(new appAuthenticationSuccessHandler());
        

        【讨论】:

        • 您需要从 successHander() 调用中删除“new”。
        【解决方案4】:

        我遇到了这个问题,直到我通过在 configure (HttpSecurity) 方法中包含 .csrf().disable() 来关闭 csrf-check。 如果您没有关闭它,则提供 csrf 令牌作为隐藏表单字段。

        ...虽然我看到你已禁用它

        【讨论】:

          【解决方案5】:

          使用successHandler 将referer 设置为true。这对我有用。否则我也会得到 302。

          在securityConfig中需要添加如下代码。

          @Override
          protected void configure(HttpSecurity http) throws Exception {
          http
            .authorizeRequests()
            .antMatchers("/login*")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .successHandler(new RefererRedirectionAuthenticationSuccessHandler ());
          }
          
          
          import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
          import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
          
          public class RefererRedirectionAuthenticationSuccessHandler extends 
          SimpleUrlAuthenticationSuccessHandler
              implements AuthenticationSuccessHandler {
          
          public RefererRedirectionAuthenticationSuccessHandler() {
              super();
              setUseReferer(true);
          }
          
          }
          
          }
          

          查看以下链接: http://www.baeldung.com/spring-security-redirect-login

          【讨论】:

            猜你喜欢
            • 2019-01-07
            • 1970-01-01
            • 1970-01-01
            • 2014-10-11
            • 2018-12-15
            • 2015-04-18
            • 2019-01-14
            • 2021-04-02
            • 2022-01-15
            相关资源
            最近更新 更多