鍍金池/ 教程/ Java/ Spring Secrity與Hibernate基于角色登錄實(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)簽庫顯示視圖
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 Secrity與Hibernate基于角色登錄實(shí)例

這篇文章介紹了如何使用Hibernate設(shè)置來實(shí)現(xiàn)Spring Security基于角色登錄。程序會根據(jù)用戶分配的角色,使用Hibernate設(shè)置在用戶登錄后根據(jù)用戶角色重定向到不同的URL。

這篇文章是在 Spring Security Hibernate注釋實(shí)例 基礎(chǔ)上補(bǔ)充的, 并簡單地增加了基于角色的登錄功能。由于這個篇文章與 Spring Security Hibernate注解實(shí)例有 99% 是相同的,除了一些改變,我們就不在這里重復(fù)的代碼。僅做了一些簡單地更改如下。

首先我們來看看整個工程目錄的結(jié)構(gòu),如下圖所示 - 

第1步:創(chuàng)建一個新客戶成功處理程序

這個類的目標(biāo)是提供自定義的重定向功能。
package com.yiibai.springsecurity.configuration;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

@Component
public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{

	private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
	
    @Override
    protected void handle(HttpServletRequest request, 
      HttpServletResponse response, Authentication authentication) throws IOException {
        String targetUrl = determineTargetUrl(authentication);
 
        if (response.isCommitted()) {
            System.out.println("Can't redirect");
            return;
        }
 
        redirectStrategy.sendRedirect(request, response, targetUrl);
    }
    
    protected String determineTargetUrl(Authentication authentication) {
    	String url="";
    	
        Collection<? extends GrantedAuthority> authorities =  authentication.getAuthorities();
        
		List<String> roles = new ArrayList<String>();

		for (GrantedAuthority a : authorities) {
			roles.add(a.getAuthority());
		}

		if (isDba(roles)) {
			url = "/db";
		} else if (isAdmin(roles)) {
			url = "/admin";
		} else if (isUser(roles)) {
			url = "/home";
		} else {
			url="/accessDenied";
		}

		return url;
    }
 
    public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
        this.redirectStrategy = redirectStrategy;
    }
    protected RedirectStrategy getRedirectStrategy() {
        return redirectStrategy;
    }
    
	private boolean isUser(List<String> roles) {
		if (roles.contains("ROLE_USER")) {
			return true;
		}
		return false;
	}

	private boolean isAdmin(List<String> roles) {
		if (roles.contains("ROLE_ADMIN")) {
			return true;
		}
		return false;
	}

	private boolean isDba(List<String> roles) {
		if (roles.contains("ROLE_DBA")) {
			return true;
		}
		return false;
	}

} 

請注意我們是如何擴(kuò)展Spring SimpleUrlAuthenticationSuccessHandler類和覆蓋 handle() 方法,只是調(diào)用使用配置RedirectStrategy重定向[默認(rèn)在這種情況下]URL,它是用戶定義determineTargetUrl方法返回。 這個方法從當(dāng)前認(rèn)證對象提取登錄用戶的角色,然后構(gòu)造基于角色有相應(yīng)的URL。最后是RedirectStrategy 負(fù)責(zé)Spring Security 框架內(nèi)的所有重定向,將請求重定向到指定的URL。

第2步:注冊自定義成功處理程序使用[現(xiàn)有]Security配置

package com.yiibai.springsecurity.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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;
import org.springframework.security.core.userdetails.UserDetailsService;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

	@Autowired
	@Qualifier("customUserDetailsService")
	UserDetailsService userDetailsService;

	@Autowired
	CustomSuccessHandler customSuccessHandler;
	
	
	@Autowired
	public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailsService);
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
	  http.authorizeRequests()
	  	//.antMatchers("/", "/home").permitAll()
	  	.antMatchers("/", "/home").access("hasRole('USER')")
	  	.antMatchers("/admin/**").access("hasRole('ADMIN')")
	  	.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
	  	//.and().formLogin().loginPage("/login")
	  	.and().formLogin().loginPage("/login").successHandler(customSuccessHandler)
	  	.usernameParameter("ssoId").passwordParameter("password")
	  	.and().csrf()
	  	.and().exceptionHandling().accessDeniedPage("/Access_Denied");
	}

}
這里相比之前 Hibernate 文章中的變化是額外調(diào)用 successHandler()如下所示:

formLogin().loginPage("/login").successHandler(customSuccessHandler).
我們來看看 successHandler。這個類基于自定義邏輯負(fù)責(zé)最后的重定向,這對我們來說是用戶的重定向[home/admin/db]是根據(jù)他的角色[USER/ADMIN/DBA]。

此外,我們根據(jù)用戶角色保護(hù)了主頁,使例子更貼近現(xiàn)實(shí)。
剛剛在配置包添加這個類并將其注冊為成功處理程序來使用Security配置(如上圖所示)。
以上對應(yīng)的XML配置格式的安全配置是:
<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="permitAll" />
        <intercept-url pattern="/home" access="permitAll" />
        <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-success-handler-ref="customSuccessHandler"
                     authentication-failure-url="/Access_Denied" />
        <csrf/>
    </http>
 
    <authentication-manager >
        <authentication-provider user-service-ref="customUserDetailsService"/>
    </authentication-manager>
     
    <beans:bean id="customUserDetailsService" class="com.yiibai.springsecurity.service.CustomUserDetailsService" />
    <beans:bean id="customSuccessHandler"     class="com.yiibai.springsecurity.configuration.CustomSuccessHandler" />
    
</beans:beans>

構(gòu)建和部署應(yīng)用程序

現(xiàn)在構(gòu)造 war(通過 eclipse/m2eclipse)或通過Maven的命令行(mvn clean install)。部署WAR文件到Servlet3.0容器。由于這里我使用的是在 eclipse 中配置 Tomcat,可以直接發(fā)布到 Tomcat 服務(wù)容器中。如果不知道怎么使用,可以參考:http://www.yiibai.com/maven/create-a-maven-web-project-with-eclipse.html

運(yùn)行應(yīng)用程序

僅供參考,我們將使用在上一節(jié)中的所定義的數(shù)據(jù)庫表結(jié)構(gòu)及數(shù)據(jù)記錄。點(diǎn)擊查看數(shù)據(jù)庫表和記錄 。

打開瀏覽器并訪問 - http://localhost:8080/SpringSecurityHibernateRoleBasedLogin/ 

結(jié)果如下所示 - 

提供DBA登錄帳戶信息,這里使用 kenny 作為登錄名。

提交后登錄成功后,你會被直接跳轉(zhuǎn)到 /db 頁面, kenny具有DBA角色。如下圖中所示 - 

現(xiàn)在注銷,并填寫一個一般用戶角色的用戶名,執(zhí)行登錄測試跳轉(zhuǎn) -

這里為了演示,故意寫錯了登錄密碼,如下所示 - 

提供正確的用戶(USER )角色的憑據(jù),您將被重定向到主頁。

現(xiàn)在嘗試訪問管理頁面:http://localhost:8080/SpringSecurityHibernateRoleBasedLogin/admin 。您應(yīng)該看到拒絕訪問頁面。如下圖中所示 - 

現(xiàn)在,注銷和管理員(ADMIN)憑據(jù)登錄,這里使用一個叫作:sam 的用戶登錄,您將會被跳轉(zhuǎn)到URL:/admin。如下圖中所示 - 

最后,注銷登錄-

就這樣。下一篇文章我們將來學(xué)習(xí)在 Spring Security 中使用BCryptPasswordEncoder密碼編碼。

下載源代碼   
09-SpringSecurityHibernateRoleBasedLogin.zip

參考