尝试注销时,Spring安全性返回302

时间:2016-04-01 21:36:37

标签: java spring spring-security

我使用Spring安全性(4.0.2.RELEASE)来保护我的应用程序。

我可以正常登录并且我的身份验证的URL受到保护,但是当我尝试注销时,我会不断获得302 POST响应,然后重定向到我配置的failureUrl(“/ cms / login?error”)。

这是我的WebSecurityConfig类

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
   @Override
   protected void configure(HttpSecurity http) throws Exception
   {        
       http        
       .authorizeRequests()
           .antMatchers("/*").permitAll()
           .antMatchers("/cms/*").authenticated()
           .antMatchers("/cms/*/*").authenticated()
           .antMatchers("/cms/*/*/*").authenticated().and()
       .formLogin()
           .loginPage("/cms/login")
           .defaultSuccessUrl("/cms/login?success")
           .failureUrl("/cms/login?error")
           .permitAll().and()
       .logout()
           .logoutUrl("/cms/login?logout")
           .logoutSuccessUrl("/cms/login")
           .permitAll();
   }

   @Autowired
   public void configureGlobal(AuthenticationManagerBuilder auth)      throws Exception
   {
       auth.inMemoryAuthentication()
           .withUser("u")
           .password("p")
           .roles("USER");
   }

   @Bean
   public PasswordEncoder passwordEncoder()
   {
       return new BCryptPasswordEncoder();
   }
  }

这是我的登录控制器:

@Slf4j
@Controller
@RequestMapping(value = {"/cms", "/cms/login"})
public class CmsLoginController extends CmsBaseController
{   
    @RequestMapping
    public ModelAndView handleLogin(HttpServletResponse request,
                                    Model model,
                                    @RequestParam(value = LOGIN_SUCCESS, required = false) String success,
                                    @RequestParam(value = LOGIN_ERROR, required = false) String error,
                                    @RequestParam(value = LOGOUT, required = false) String logout)
    {   
        try
        {       
            if (success != null)
            {               
                setLoggedIn(true);
                request.sendRedirect(XXXXX);
            }

            if (error != null)
            {
                model.addAttribute(LOGIN_ERROR, "Invalid username and password!");
            }

            if (logout != null)
            {
                model.addAttribute(LOGOUT, "You've been logged out successfully.");
                setLoggedIn(false);
            }

            return new ModelAndView(CMS_CONTEXT + LOGIN_URL);
        }
        catch(Exception e)
        {
            setLoggedIn(false);
            log.error(e.toString(), e);

            return new ModelAndView(ERROR_VIEW_NAME);
        }   
    }
}    

为了记录,我最初使用注销功能正常工作,但我必须介绍一些已经破坏它的更改...

有什么想法? 谢谢

2 个答案:

答案 0 :(得分:0)

spring进行不必要的注销逻辑以进行重定向 我有点烦。

默认行为应该是直接的,而不是重定向,并且它们可以保留特殊情况的规定。

在配置方法中使用以下内容

.logout().logoutUrl("/api/logout")
            .logoutSuccessHandler(new LogoutSuccessHandler() {

                @Override
                public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
                        Authentication authentication) throws IOException, ServletException {
                    System.out.println("success");
                }
            });

此链接的积分 https://www.codeproject.com/Tips/521847/Logout-Spring-s-LogoutFilter

答案 1 :(得分:0)

我认为问题是CSRF过滤器。在Spring Security 4中,CSRF防护默认情况下处于打开状态,每个POST请求都需要一个CSRF令牌。

如果您从以前的Spring版本中迁移代码,那么很有可能这就是问题所在。

要进行快速测试,请将public static class EntityHelper { public static IEnumerable<UpdateFieldDefinition> GetUpdateDefinition<T>(this T entity) { return entity.GetType().GetProperties() .Where(x => { switch (x.Name) { case nameof(BaseEntity.Id): case nameof(BaseEntity.CreationDate): case nameof(BaseEntity.LastModifiedDate): case nameof(BaseEntity.CreatorId): case nameof(BaseEntity.LastModifierUserId): return false; default: return true; } }) .Select(x => new UpdateFieldDefinition(x.Name, x.GetValue(entity))); } } 添加到您的配置中。如果这样有效,则请转回CSRF保护并将CSRF令牌以某种方式添加到POST注销请求中。