2017-05-16 76 views
0

我正在使用Java Web令牌(JWT)在我的Web應用程序中進行身份驗證。我想創建一個/logout Rest端點,它刪除客戶端上的JSession cookie,使會話無效並執行其他任何必需的操作。在Spring中實現對單頁應用程序的註銷

前端是用React編寫的SPA。

我在擴展WebSecurityConfigurerAdapterWebSecurityConfig類以下configure方法:

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     .csrf().disable() 
     .authorizeRequests() 
      .antMatchers("/login").permitAll() 
     .and() 
     .authorizeRequests() 
      .antMatchers("/signup").permitAll() 
     .and() 
     .authorizeRequests() 
      .anyRequest().authenticated() 
     .and() 
     .addFilterBefore(
      new JWTAuthenticationFilter(userDetailsServiceBean()), 
      UsernamePasswordAuthenticationFilter.class); 
} 

我有下面的代碼,但它返回404 Not found誤差設置爲/login路徑。我想要獲得HTTP response200和一些清理。我該怎麼辦 ?

.logout().logoutUrl("/logout").logoutSuccessHandler(logoutHandler).logoutSuccessUrl("/login").invalidateHttpSession(true) 

回答

0

一些研究,我發現,如果我想使用無狀態的REST API的設計,我不應該使用任何Cookie,包括JSESSIONID後。

所以我改變了我的代碼:

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
     .and() 
     .csrf().disable() 
     .authorizeRequests() 
      .anyRequest().authenticated() 
     .and() 
     .addFilterBefore(
      new JWTAuthenticationFilter(userDetailsServiceBean()), 
      UsernamePasswordAuthenticationFilter.class); 
} 
0

你能不能先嚐試這樣的登錄請求。首先在您的WebSecurityConfig中添加JWTLoginFilter。從我的樣本項目

粘貼代碼:

http.csrf().disable() // disable csrf for our requests. 
    .authorizeRequests() 
    .antMatchers("/").permitAll() 
    .antMatchers(HttpMethod.POST,"/login").permitAll() 
    .anyRequest().authenticated() 
    .and() 
    // We filter the api/login requests 
    .addFilterBefore(new JWTLoginFilter("/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class) 
    // And filter other requests to check the presence of JWT in header 
    .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) 
    .addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class); 

你不會需要CORSFilter如果您的前端和後端都在同一服務器上。

另外發現下面JWTLoginFilter類

public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter 
    { 
    private TokenAuthenticationService tokenAuthenticationService; 
    public JWTLoginFilter(String url, AuthenticationManager authenticationManager) { 
    super(new AntPathRequestMatcher(url)); 
    setAuthenticationManager(authenticationManager); 
    tokenAuthenticationService = new TokenAuthenticationService(); 
} 

@Override 
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) 
throws AuthenticationException, IOException, ServletException { 
    AccountCredentials credentials = new ObjectMapper().readValue(httpServletRequest.getInputStream(), AccountCredentials.class); 
    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword()); 
    return getAuthenticationManager().authenticate(token); 
} 

@Override 
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) 
throws IOException, ServletException { 
    String name = authentication.getName(); 
    tokenAuthenticationService.addAuthentication(response, name); 
    } 
} 

AccountCredential類是包含兩個字段用戶名簡單POJO類和密碼,我用來接收請求。

另請注意,UsernamePasswordAuthenticationFilter我們正在使用的登錄請求'username'和'password'需要兩個字段。像{"username":"user1","password":"secret1"}

相關問題