1.前言
這里專門 做 spring security 登出操作 的 詳細記錄
2.操作
(1)目錄結構
(2)在security 攔截規則配置文件添加退出登錄支持
源碼

package com.example.security5500.securityConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; //@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private DbUserDetailsService dbUserDetailsService; //攔截規則設置 @Override protected void configure(HttpSecurity http) throws Exception { // http // .authorizeRequests() // // 匹配 "/" 路徑,不需要權限即可訪問 // .antMatchers("/").permitAll() // //匹配 "/user" 及其以下所有路徑,都需要 "USER" 權限 //// .antMatchers("/user/**").hasAuthority("USER") // .and() // //登錄地址為 "/login",登錄成功默認跳轉到頁面 "/hai" // .formLogin().loginPage("/login").defaultSuccessUrl("/hai") // //退出登錄的地址為 "/logout",退出成功后跳轉到頁面 "/login" // .and() // //退出登錄的地址為 "/logout",退出成功后跳轉到頁面 "/login" // .logout().logoutUrl("/logout").logoutSuccessUrl("/login"); // // 默認啟用 CSRF ,必須post才可以訪問/logout http //允許基於使用HttpServletRequest限制訪問 .authorizeRequests() //設置不攔截頁面,可直接通過,路徑訪問 "/", "/index", "/home" 則不攔截, //"/hhk/**" 的意思是 "/hhk" 及其以下所有路徑 .antMatchers("/", "/index", "/home","/hhk/**") //是允許所有的意思 .permitAll() //其他頁面都要攔截,【需要在最后設置這個】 .anyRequest().authenticated() .and() //設置自定義登錄頁面 .formLogin() //指定自定義登錄頁面的訪問虛擬路徑 .loginPage("/login") .permitAll() .and() // 添加退出登錄支持。當使用WebSecurityConfigurerAdapter時,這將自動應用。默認情況是,訪問URL”/ logout”,使HTTP Session無效 // 來清除用戶,清除已配置的任何#rememberMe()身份驗證,清除SecurityContextHolder,然后重定向到”/login?success” .logout() // //指定的登出操作的虛擬路徑,需要以post方式請求這個 http://localhost:5500/mylogout 才可以登出 ,也可以直接清除用戶認證信息達到登出目的 .logoutUrl("/mylogout") //登出成功后訪問的地址 .logoutSuccessUrl("/home"); // .permitAll(); } /** * 添加 UserDetailsService, 實現自定義登錄校驗 */ @Override protected void configure(AuthenticationManagerBuilder builder) throws Exception { //注入用戶信息,每次登錄都會來這查詢一次信息,因此不建議每次都向mysql查詢,應該使用redis builder.userDetailsService(dbUserDetailsService); } /** * 密碼加密 */ @Bean public static PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } }
(3)前端以表單的形式登出
3.測試
啟動后,
直接 點擊 登出即可
如果把不配置security 的攔截規則 ,將會默認使用get 方式 請求 /logout 來登出 ,會進入一個界面 ,需要鼠標點擊
4.后端自定義登出
package com.example.security5500.controller; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Controller public class UserController { //登出操作 @RequestMapping({"/doLogout"}) public String logout(HttpServletRequest request, HttpServletResponse response) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null) {//清除認證 new SecurityContextLogoutHandler().logout(request, response, auth); } //重定向到指定頁面 return "redirect:/login"; } }
請求這個也可以登出 ,原理是獲取授權對象然后清除認證,再重定向到指定頁面