2016-12-02 67 views
0

我试图设置一个非常基本的spring引导身份验证的应用程序。我在客户端设置授权标题并将其发送到后端。我可以验证客户端是否发送了正确的标题。Spring Boot Authorization Basic Header Never Changes

后端正确地接收在第一次尝试登录的标题。但是,如果登录凭证不正确,那么后续请求会保留初始请求的头部(缓存它或某物)。

我使用Redis的缓存会话。我的配置如下:

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired AuthenticationEntryPoint authenticationEntryPoint; 
    @Autowired CsrfTokenRepository csrfTokenRepository; 


    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .exceptionHandling() 
      .authenticationEntryPoint(authenticationEntryPoint) 
      .and() 
     .csrf() 
      .disable() 
     .authorizeRequests().antMatchers("**") 
      .permitAll() 
      .anyRequest() 
      .authenticated() 
      ; 
    } 
} 

的AuthenticationEntryPoint

public class AuthenticationEntryPointBean { 
@Bean 
    AuthenticationEntryPoint authenticationEntryPoint() { 
     return new RestAuthenticationEntryPoint(); 
    } 
} 

任何方向,将不胜感激。

**编辑** 添加缓存设置

@Configuration 
@EnableRedisHttpSession 
public class HttpSessionConfig { 

    @Bean 
    public JedisConnectionFactory connectionFactory() { 
     return new JedisConnectionFactory(); // <2> 
    } 
} 

而且我想无效缓存,但似乎并没有工作

@CrossOrigin 
@RequestMapping(value="/auth/login", method = RequestMethod.GET, produces="application/json") 
public @ResponseBody String login(@RequestHeader(name = "authorization") String authorization, HttpSession session, HttpServletRequest request) 
    { 
     try 
     { 
      authorization = authorization.substring("Basic ".length()); 
      String decoded = new String(Base64.getDecoder().decode(authorization),"UTF-8"); 

      Gson gson = new Gson(); 
      LoginRequest login = gson.fromJson(decoded,LoginRequest.class); 

      UserAuthenticationEntity entity = service.getSecurityContext(login).orElseThrow(() -> 
       new BadCredentialsException("Authentication Failed.") 
      ); 

      session.setMaxInactiveInterval((int)TimeUnit.MINUTES.toSeconds(expiresInMinutes)); 
      SecurityContextHolder.getContext().setAuthentication(new EntityContext(entity,expiresInMinutes)); 

      String response = gson.toJson(BasicResponse.SUCCESS); 
      return response; 
     } 
     catch (Exception e) 
     { 
      session.invalidate(); 
      e.printStackTrace(); 
      throw new AuthenticationCredentialsNotFoundException("Authentication Error"); 
     } 
    } 
+0

你可能需要在这个问题你的缓存配置。一种非常规的猜测是,缓存配置不正确,因此它不知道在失败登录时使缓存内容无效,因此它只是返回缓存的会话信息。 – Ickster

+0

包含在编辑 –

回答

1

添加以下到我的网络安全配置似乎在做伎俩。

.requestCache() 
.requestCache(new NullRequestCache()) 

我不确定这样做有什么副作用。我把它捡起来关闭一个博客https://drissamri.be/blog/2015/05/21/spring-security-and-spring-session/

如果有任何更深入地了解,如果这是个好习惯还是坏的做法我将不胜感激任何意见。

我最后的Web安全配置如下所示:

http 
     .exceptionHandling() 
      .authenticationEntryPoint(authenticationEntryPoint) 
      .and() 
     .csrf() 
      .disable() 
     .authorizeRequests().antMatchers("**") 
      .permitAll() 
      .anyRequest() 
      .authenticated() 
      .and() 
     .requestCache() 
      .requestCache(new NullRequestCache()) 
      .and() 
     .sessionManagement() 
      .sessionFixation() 
      .newSession() 
      ; 
+0

是的,这几乎是你所需要的。如果没有'.requestCache(new NullRequestCache())',* request *被缓存,这就是为什么第二次登录尝试显示出相同的参数。 – Ickster