鍍金池/ 教程/ Java/ Spring Security注銷登錄實(shí)例
Spring Security自定義表單登錄注釋示例
Spring Secrity與Hibernate基于角色登錄實(shí)例
Spring Security自定義表單登錄實(shí)例
Secure Spring REST API使用OAuth2
Spring Security與Hibernate整合以及XML實(shí)例
Spring Security入門程序示例
Spring Security+Hibernate密碼編碼器Bcrypt實(shí)例
Spring Security標(biāo)簽庫(kù)顯示視圖
Spring Security基于角色登錄實(shí)例
Spring Security使用@PreAuthorize,@PostAuthorize, @Secured方法安全
Secure Spring REST API使用基本認(rèn)證
Spring Security入門程序注釋示例
Spring Security+Hibernate記住我實(shí)例
Spring MVC4 + Spring Security4 + Hibernate實(shí)例
Spring Security注銷登錄實(shí)例
AngularJS+Spring Security使用基本身份驗(yàn)證
Spring Security教程

Spring Security注銷登錄實(shí)例

這篇教程文章將向您展示如何以編程方式注銷 Spring Security 用戶。使用瀏覽器的后退按鈕也能很好顯示。要整個(gè)工程完成代碼編寫并運(yùn)行后,主頁(yè)面如下圖所示 -


首先我們先來(lái)看看工程結(jié)構(gòu),這里使用的是注釋方式來(lái)實(shí)現(xiàn)的。如下圖中所示 - 

一般情況下,在你的視圖中應(yīng)該提供一個(gè)簡(jiǎn)單的注銷鏈接來(lái)注銷用戶,類似如下所示: 
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>Admin page</title>
</head>
<body>
	Dear <strong>${user}</strong>, Welcome to Admin Page.
	<a href="<c:url value="/logout" />">Logout</a>
</body>
</html> 

沒(méi)有什么特別的東西?,F(xiàn)在,我們只需要在映射控制器到  /logout 注銷鏈接。創(chuàng)建一個(gè)新的方法如下所示: 

	@RequestMapping(value="/logout", method = RequestMethod.GET)
	public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		if (auth != null){    
			new SecurityContextLogoutHandler().logout(request, response, auth);
		}
		return "redirect:/login?logout";//You can redirect wherever you want, but generally it's a good practice to show login screen again.
	}
 

在這里,首先我們確定,如果用戶在認(rèn)證之后使用 SecurityContextHolder.getContext().getAuthentication() 。如果是這樣,那么我們調(diào)用 SecurityContextLogoutHandler().logout(request, response, auth) 注銷用戶。 

注銷調(diào)用執(zhí)行以下操作:
  • HTTP的會(huì)話失效,那么解除綁定到它的任何對(duì)象;
  • 將刪除 SecurityContext 的身份驗(yàn)證,以防止并發(fā)請(qǐng)求的問(wèn)題;
  • 顯式地清除當(dāng)前線程上下文值;
就這樣,不需要在應(yīng)用程序中的任何其他地方處理注銷。請(qǐng)注意,你甚至不需要做任何特殊的Spring配置(XML或基于注釋),信息如下圖所示:
package com.yiibai.springsecurity.configuration;

import org.springframework.beans.factory.annotation.Autowired;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

	
	@Autowired
	public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
		auth.inMemoryAuthentication().withUser("yiibai").password("123456").roles("USER");
		auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
		auth.inMemoryAuthentication().withUser("dba").password("123456").roles("ADMIN","DBA");
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
	  
	  http.authorizeRequests()
	  	.antMatchers("/", "/home").permitAll()
	  	.antMatchers("/admin/**").access("hasRole('ADMIN')")
	  	.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
	  	.and().formLogin().loginPage("/login")
	  	.usernameParameter("ssoId").passwordParameter("password")
	  	.and().exceptionHandling().accessDeniedPage("/Access_Denied");
	}
}
如在上面提到的,沒(méi)有特殊配置來(lái)處理注銷。
以上如果使用 XML 來(lái)配置 Security ,那么格式如下:
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd">
     
    <http auto-config="true" >
        <intercept-url pattern="/" access="hasRole('USER')" />
        <intercept-url pattern="/home" access="hasRole('USER')" />
        <intercept-url pattern="/admin**" access="hasRole('ADMIN')" />
        <intercept-url pattern="/dba**" access="hasRole('ADMIN') and hasRole('DBA')" />
        <form-login  login-page="/login" 
                     username-parameter="ssoId" 
                     password-parameter="password" 
                     authentication-failure-url="/Access_Denied" />
    </http>
 
    <authentication-manager >
        <authentication-provider>
            <user-service>
                <user name="yiibai"  password="123456"  authorities="ROLE_USER" />
                <user name="admin" password="123456" authorities="ROLE_ADMIN" />
                <user name="dba"   password="123456" authorities="ROLE_ADMIN,ROLE_DBA" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
    
</beans:beans>
在本系列教程中的應(yīng)用程序代碼,在之后的文章都是基于這個(gè)教程的。所以如果打算往后學(xué)習(xí)其它教程,請(qǐng)務(wù)必清楚理解此文章代碼和邏輯,以及相關(guān)配置或原理。

發(fā)布并運(yùn)行

如需要自己動(dòng)手實(shí)踐,可在文章底部提供的下載鏈接并點(diǎn)擊下載本示例代碼,這個(gè)項(xiàng)目的完整代碼。它是在Servlet 3.0的容器(Tomcat7/8,本文章使用 Tomcat7)上構(gòu)建和部署運(yùn)行的。
打開您的瀏覽器,在地址欄中輸入網(wǎng)址:http://localhost:8080/SpringSecurityCustomLogout/ ,默認(rèn)的頁(yè)面將顯示如下 - 

現(xiàn)在訪問(wèn) http://localhost:8080/SpringSecurityCustomLogout/admin,系統(tǒng)將提示您登錄,如下圖中所示 - 

提供用戶名和密碼(admin/123456)并點(diǎn)擊提交,就會(huì)看到管理頁(yè)面。如下圖中所示 -

點(diǎn)擊注銷,將會(huì)自動(dòng)跳轉(zhuǎn)到登錄頁(yè)。如下圖中所示 - 

點(diǎn)擊瀏覽器后退按鈕,將會(huì)留在登錄屏幕。如下所示 -

而已。下一篇文章將學(xué)習(xí)如何顯示基于已登錄用戶的角色,使用Spring Security  標(biāo)簽顯示 JSP/視圖等等。

下載源代碼