Spring Security 3 - 总是返回错误 302

新手上路,请多包涵

我使用 Spring 4 创建一个简单的应用程序。最近,我将 Spring Security 3 添加到项目中,但总是得到错误代码 302(因此它总是重定向到 主页)。

这是我的 安全配置

 @Configuration
@EnableWebMvcSecurity
@ComponentScan(basePackages = { "com.moon.repository" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser("hello").password("world").roles("USER");
}

@Override
public void configure(WebSecurity web) throws Exception {
    web
    .ignoring().antMatchers("/resources/**", "/views/**");
}

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()
            .antMatchers("/","/home").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/home")
            .loginProcessingUrl("/acct/signin")
            .and()
            .logout()
            .permitAll();
}

}

我有一个名为 AccountController 的控制器:

 @Controller
@RequestMapping(value = "/acct")
public class AccountController {

private final Logger logger = LoggerFactory.getLogger(AccountController.class);

@RequestMapping(value = "/signin", method = RequestMethod.POST)
public String signin(@RequestParam("username") String username,
        @RequestParam("password") String password) {

    logger.info("======== [username:{0}][password:{1}] ========", username, password);

    if ("error@1.1".equalsIgnoreCase(username)) {
        return "error";
    } else {
        return "demo";
    }
}

}

我的WEB-INF结构:

 WEB-INF
----views
--------home.jsp
--------demo.jsp
--------error.jsp

流程是这样的:

  1. 用户访问网站 http://mylocal:8080/moon => 它显示 home.jsp
  2. 用户按下登录 按钮,它会弹出一个子窗口,要求输入用户名和密码 => 仍在 home.jsp
  3. 用户按下提交按钮 => 我假设它将转到 /acct/signin 并返回 /demo,但我在 Google Chrome 中看到错误 302,然后它再次转到 /home

有任何想法吗 ?我被困了整整 2 天,现在我几乎绝望了……

非常感谢大家来看我的问题

=================================== 第一次更新============= ======================

更新: home.jsp 中的表单

<form:form role="form" method="POST" action="acct/signin"
class="form-signin">
<div class="row">
    <div class="col-lg-5">
        <input name="username" size="20" type="email"
            class="form-control" placeholder="Email address" required
            autofocus>
            <input name="password" type="password"
                    class="form-control" placeholder="Password" required>
                <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    </div>
</div>
</form:form>

===================================第二次更新============= ======================

我试图实现 UserDetailsService(不使用内存中的身份验证)但仍然……同样的问题 - 错误 302

AppUserDetailsServiceImpl.java

 @Component
public class AppUserDetailsServiceImpl implements UserDetailsService {

    private final Logger logger = LoggerFactory.getLogger(AppUserDetailsServiceImpl.class);

    @Override
    public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {

        logger.info("loadUserByUsername username=" + username);
        logger.info("======== {} ========",SecurityContextHolder.getContext().getAuthentication());

        if (!username.equals("hello")) {
            throw new UsernameNotFoundException(username + " not found");
        }

        // creating dummy user details
        return new UserDetails() {

            private static final long serialVersionUID = 2059202961588104658L;

            @Override
            public boolean isEnabled() {
                return true;
            }

            @Override
            public boolean isCredentialsNonExpired() {
                return true;
            }

            @Override
            public boolean isAccountNonLocked() {
                return true;
            }

            @Override
            public boolean isAccountNonExpired() {
                return true;
            }

            @Override
            public String getUsername() {
                return username;
            }

            @Override
            public String getPassword() {
                return "world";
            }

            @Override
            public Collection<? extends GrantedAuthority> getAuthorities() {
                List<SimpleGrantedAuthority> auths = new java.util.ArrayList<SimpleGrantedAuthority>();
                auths.add(new SimpleGrantedAuthority("USER"));
                return auths;
            }
        };
    }

日志显示:

 [14/08/19 15:16:32:200][INFO ][com.moon.repository.AppUserDetailsServiceImpl][loadUserByUsername](24) loadUserByUsername username=hello
[14/08/19 15:16:32:200][INFO ][com.moon.repository.AppUserDetailsServiceImpl][loadUserByUsername](25) ======== org.springframework.security.authentication.UsernamePasswordAuthenticationToken@f1e4f742: Principal: com.moon.repository.AppUserDetailsServiceImpl$1@e3dc1b1; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@12afc: RemoteIpAddress: 127.0.0.1; SessionId: 023BC9A8B997ECBD826DD7C33AF55FC7; Granted Authorities: USER ========

原文由 chialin.lin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.8k
2 个回答

我相信 Spring 会将您重定向到 /home 因为您实际上并没有通过登录过程对用户进行身份验证。

  1. 您通过 http://mylocal:8080/moon 返回home.jsp视图
  2. 您单击登录按钮,提交您的登录表单由于没有显式声明表单登录,Spring Security 将显示用户名和密码提示框,供最终用户输入其凭据
  3. 然后将这些凭据发布到登录处理 URL ( /acct/signin ),您恰好在 —b5566d6df976713b32c642f5e6-da3 中有一个与 — AccountController signin 方法的映射
  4. 这样的控制器无法以 Spring 的方式对用户进行身份验证,但仍通过返回字符串将请求重定向到 /demo
  5. /demo 路径被保护( .anyRequest().authenticated() )给任何未经身份验证的用户,由于当前用户确实未经身份验证,Spring Security会自动将请求重定向到登录页面
  6. 你最终在 /home ( .loginPage("/home") )

使用 InMemoryUserDetailsManagerConfigurer (请参阅 inMemoryAuthentication javadoc),您只能通过配置的凭据成功登录。如果你想要一个成熟的身份验证系统,你必须为你的 Spring Security 配置提供一个 UserDetailsS ervice 实现(通过 userDetailsService 方法)。


编辑:在与 chialin.lin 的对话之后,似乎缺少的配置是一个 defaultSuccessfulUrl ,让 Spring Security 知道一旦通过身份验证将用户重定向到哪里。

原文由 m4rtin 发布,翻译遵循 CC BY-SA 3.0 许可协议

对我来说,我来自一个有点不同的用例,但在它完美工作之前“突然”遇到了同样的问题。

我的 Setup Spring 带有一个 ExtJs 前端,我现在在其中构建一个 rest 界面。

一切都非常好,然后突然间我开始收到 http 状态 302 响应(WTH?)

由于我按照以下示例通过代码实现: https ://octoperf.com/blog/2018/03/08/securing-rest-api-spring-security/

有一个 SimpleUrlAuthenticationSuccessHandler 的声明。

参见 4.4 SecurityConfig ,其中 TokenAuthenticationFilter 是用类 NoRedirectStrategy 构造的;参见 4.1 重定向策略

反过来,在我的 AbstractAuthenticationProcessingFilter 扩展中没有设置这个 NoRedirectStrategy 它会显示 http 302 响应。

原文由 Dirk Schumacher 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题