簡體   English   中英

Spring Security無法注銷

[英]Spring security cannot logout

我在Spring引導應用程序中自定義了Spring安全性實現。 因此,我有依賴關系,並且有一個名為SecurityImpl的類,該類為我實現了登錄訪問。 當我進入瀏覽器時,系統會正確提示我輸入警告。 登錄時,我可以正確訪問我的Spring Controller的所有@RequestMapping。 但我始終保持登錄狀態。 即使我從瀏覽器中刪除了JSESSIONID,當我發出另一個http請求時,我也被允許並創建一個新的JSESSIONID並將其發送到我的瀏覽器。

一件奇怪的事情是,即使我是第一次使用登錄名訪問,即使以合法方式生成了Cookie,其過期日期也都是:1969-12-31T23:59:59.000Z

我試圖使會話無效,從服務器中刪除cookie,以各種方式登出,但什么也沒有。 登錄后,我總是被允許的。

這是我的SecurityImpl.java類,用於配置Spring Security:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Configuration
@Component
public class SecurityImpl extends WebSecurityConfigurerAdapter implements AuthenticationProvider {

  public static final String ROLE_ADMIN = "ROLE_ADMIN";
  public static final String ROLE_USER = "ROLE_USER";

  @Autowired UtenteDao utenteDao;

  /* authentication provider part */

  @Override
  public Authentication authenticate(Authentication auth) throws AuthenticationException {

    String username = auth.getName();
    String password = auth.getCredentials().toString();
    String ruolo = "";

    Optional<Utente> utenteOptional = utenteDao.findByCodiceFiscaleAndPassword(username, password);

    if(utenteOptional.isPresent()){
        ruolo = utenteOptional.get().getRuolo();
    }
    if(ROLE_ADMIN.equals(ruolo)) {
        List<GrantedAuthority> grantedAuths = new ArrayList<>();
        grantedAuths.add(new SimpleGrantedAuthority(ROLE_USER));
        grantedAuths.add(new SimpleGrantedAuthority(ROLE_ADMIN));
        return new UsernamePasswordAuthenticationToken(username, password, grantedAuths);
    } else if(ROLE_USER.equals(ruolo)){
        List<GrantedAuthority> grantedAuths = new ArrayList<>();
        grantedAuths.add(new SimpleGrantedAuthority(ROLE_USER));
        return new UsernamePasswordAuthenticationToken(username, password, grantedAuths);
    } else {
        throw new BadCredentialsException("Autenticazione fallita");
    }
  }

  @Override
  public boolean supports(Class<?> auth) {
    return auth.equals(UsernamePasswordAuthenticationToken.class);
  }



  /* websecurity adapter part: erase it if you don't want login alert but default spring login web page */

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(this); //this because it is either a WebSecurityAdapter than an AuthenticationProvider
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().authenticated()
            .and()
            .httpBasic()
            .and()
            .logout().clearAuthentication(true).logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/test")
            .deleteCookies("JSESSIONID")
            .invalidateHttpSession(true);
  }

  /*  per non filtrare con il login alcuni path  */
  @Override
  public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/test");
  }

}

它不起作用:當我進入/ logout時,我被正確地重定向到/ test,但是當我請求一個禁止的路徑時,無需任何登錄即可被允許。

然后我在@RestController中嘗試了一些解決方案:

@RequestMapping("/logout")
public String logoutPage (UsernamePasswordAuthenticationToken token) {
    token.eraseCredentials();
    token.setAuthenticated(false);
    SecurityContextHolder.getContext().setAuthentication(null);
    return "<h1>Logout effettuato con successo.</h1>";
}

然后我嘗試:

@RequestMapping(value = "/logout")
public String loadApp(HttpServletRequest request) {
    HttpSession session= request.getSession(false);
    SecurityContextHolder.clearContext();
    if(session != null) {
        session.invalidate();
    }
    return "<h1>Logout effettuato con successo.</h1>";
}

然后,我拼命嘗試:

@RequestMapping("/logout")
public String logoutDo(HttpServletRequest request){
    HttpSession session= request.getSession(false);
    SecurityContextHolder.clearContext();
    session= request.getSession(false);
    if(session != null) {
        session.invalidate();
    }
    for(Cookie cookie : request.getCookies()) {
        cookie.setMaxAge(0);
    }
    return "<h1>Logout effettuato con successo.</h1>";
}

我嘗試使用這些方法,並同時從瀏覽器中刪除了我的cookie。 我還嘗試了使用注釋@PreAuthorize對禁止的方法進行預授權,以防它們被允許使用(當您打開新的瀏覽器時,在首次登錄之前,即使沒有@PreAuthorize也不允許使用它們,但是在進行登錄時,IS永遠!)

問題是缺少showForm()的用法。 沒有它,是的,我將憑據插入顯示給我的Javascript警報中。 但是無法注銷。

因此,代碼將以這種方式更改:

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

    http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .httpBasic()
            .and()
            .logout().clearAuthentication(true).logoutRequestMatcher(new AntPathRequestMatcher("/logout")) 
            .logoutSuccessUrl("/test") 
            .deleteCookies("JSESSIONID")
            .invalidateHttpSession(true);


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM