SpringMVC 3.1集成Spring Security 3.1


這篇算是一個入門文章,昨天看見有網友提問,spring mvc集成spring security 的時候出錯,揣測了一下問題木有解決。我就幫忙給搭建了一個集成框架他說可以,他告訴我這樣的文章網上少。今天我就分享在這里供入門學習。spring mvc我木有用過,所以我們這里重點講解如何集成spring security ,spring security是一個非常好的開源權限框架(具體了解自己google,或者到spring 官網,這里我給一個DOC3.1:http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity.html)。 可以說不僅僅包含了權限,里面有一套完整的授權認證系統包括:權限、防止session攻擊、支持信道安全、支持LDAP認證、支持OpenID、同時支 持CAS集成單點登錄等等,個人用過spring security 2.0基本大致一樣,當時中文資源那個少啊,尤其集成SSH+spring security 更是少的可憐,最后還是硬着頭皮上,最后拿下了這個框架,最起碼了解了。當時就寫了一個SSH+spring security的文章,還被某網站引用。好了廢話不扯,我們今天在來集成一個springmvc3.1+spring security3.1.我們step by step go。

step1:搭建SpringMVC。

如果你會搭建或者搭建好了spring MVC那這一步可以略過了。首先下載spring mvc3.1 jar這個到官網下載或者google,需要的jar如圖:

截圖01

然后創建一個包新建一個spring mvc 的class、我的如下:

復制代碼
@Controller 
public class RestConstroller { 
    
    public RestConstroller() {} 
     
    @RequestMapping(value = "/welcome", method = RequestMethod.GET)  
    public String registPost() {  
        return "/hello";  
    } 

}
復制代碼

 

上面采用spring 注解方式實例化class,這個我不多講,spring mvc也沒用過不敢亂點。官網有例子你自己照着做。http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/validation.html#format-configuring-FormattingConversionService

接着新建了一個view試圖放了一個hello.jsp

然后新建一個spring-servlet.xml 這個是spring mvc的一個配置文件。

復制代碼
<?xml version="1.0" encoding="UTF-8"?>      
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    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.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd 
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context.xsd">         
        
     <!-- 啟動注解驅動的Spring MVC功能,注冊請求url和注解POJO類方法的映射-->  
     <mvc:annotation-driven />  
     <!-- 啟動包掃描功能,以便注冊帶有@Controller、@Service、@repository、@Component等注解的類成為spring的bean -->  
     <context:component-scan base-package="com.mvc.test" />  <!--這個包根據自己的項目來配置,我的是com.mvc.test--> 
     <!-- 對模型視圖名稱的解析,在請求時模型視圖名稱添加前后綴 -->  
     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/view/" p:suffix=".jsp" />    
</beans> 

然后配置web.xml:

     <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <!-- 應用上下文配置文件 -->  
        <param-value>/WEB-INF/spring-servlet.xml</param-value>  
    </context-param>  
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener> 

  <!-- 配置spring核心servlet -->  
  <servlet>  
      <servlet-name>spring</servlet-name>  
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
      <load-on-startup>1</load-on-startup>  
  </servlet>  
  <!-- url-pattern配置為/ 攔截 -->  
  <servlet-mapping>  
      <servlet-name>spring</servlet-name>  
      <url-pattern>/</url-pattern>  
  </servlet-mapping>  
復制代碼

 

項目具體結構:

截圖02

好了現在可以啟動了,我這里啟動的時候很不幸報錯了,一看,缺少logger的jar,添加commons-logging-1.1.jar,ok啟動訪問http://localhost:8080/SpringMVC/welcome成功、

到這里spring mvc配置完成。下面我們的重點集成spring security 3.1

step 2 spring mvc3.1集成spring security 3.1

首先要講一點大版本集成要注意一點,大版本號要保持一直,第一位的往往都是大版本號,小版本號影響不大。為什么要這樣講,當時我在集成SSH 的時候spring 用的是spring 2.X,然后去下載了一個spring security 3.X的死活不成功。后來在一片老外的文章中發現了,具體地址我忘記了,spring 2.X +spring security 2.X才能集成功,spring 3.X +spring security 3.X才能集成成功。現在想想真夠二的、哈哈,好了小插曲過后,我們繼續。

首先下載spring security 3.1jar,地址:http://www.springsource.org/spring-community-download。我這里有曾今下載的,就不用了、jar結構如下:

截圖03

紅色的呢,是源碼包,我們不用加入,藍色圈中的是兩個例子、你可以部署學習一下。其他的就是我們需要的jar,可以根據包名稱發現各個包都是一個spring security 的特性,一般來說我們把jar都加進去,隨着項目需要都會用到的。

接下來我們需要新建一個applicationContext-security.xml文件,這個是spring security 配置必須的一個文件。內容如下:

復制代碼
<?xml version="1.0" encoding="UTF-8"?> 
<b:beans xmlns="http://www.springframework.org/schema/security" 
    xmlns:b="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-3.0.xsd 
                        http://www.springframework.org/schema/security 
                        http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 
       <!-- 開啟默認的攔截器 --> 
      <http auto-config='true'> 
         <!-- 允許訪問的uri --> 
        <intercept-url pattern="/**" access="ROLE_USER" />    
       </http> 
       
       <!-- 權限管理者 -->     
       <authentication-manager> 
           <!-- 權限提供者 --> 
        <authentication-provider> 
          <!-- 可提供登陸訪問的用戶 --> 
          <user-service> 
            <user name="haha" password="haha" authorities="ROLE_USER, ROLE_ADMIN" /> 
            <user name="xixi" password="xixi" authorities="ROLE_USER" /> 
          </user-service> 
        </authentication-provider> 
      </authentication-manager> 
   
</b:beans>
復制代碼

 

里面大概解釋了一下,其中http節點里面默認的開啟的幾個必須的攔截器,下面的user-service 就是可以登陸訪問的用戶列表,我們這里沒有用數據庫所以就這樣配置了,如果使用數據庫 配置一個dataSource即可,包括后面的authorities都是通過數據庫管理用戶權限的,這里我們暫時入門不做深入講解。

然后我們需要一個spring security 的過濾器配置、web.xml完整配置。

復制代碼
<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <!-- 應用上下文配置文件 -->  
        <param-value>/WEB-INF/spring-servlet.xml,/WEB-INF/applicationContext-security.xml</param-value> 
    </context-param> 
      
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener> 
    
    <!-- spring securit start --> 
    <filter> 
      <filter-name>springSecurityFilterChain</filter-name> 
      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
    </filter> 
    <filter-mapping> 
      <filter-name>springSecurityFilterChain</filter-name> 
      <url-pattern>/*</url-pattern> 
    </filter-mapping> 
    <!-- spring securit start --> 
          
    <!-- 配置spring核心servlet -->  
    <servlet>  
        <servlet-name>spring</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
    <!-- url-pattern配置為/,不帶文件后綴,會造成其它靜態文件(js,css等)不能訪問。如配為*.do,則不影響靜態文件的訪問 -->  
    <servlet-mapping>  
        <servlet-name>spring</servlet-name>  
        <url-pattern>/</url-pattern>  
    </servlet-mapping> 

    
    <welcome-file-list> 
      <welcome-file>index.jsp</welcome-file> 
   </welcome-file-list> 
</web-app>
復制代碼

 

其中springSecurityFilterChain  過濾器必須放在最前面,因為spring security的安全機制是保護在web最外層的安全框架,所以你的任何訪問都要經過spring security 投票機制授權才可以訪問的,否則不允許訪問。只有登陸用戶才可以訪問。

contextConfigLocation配置就是掃描我們的spring mvc和spring security配置文件。

具體完整的目錄結構如下:

截圖04

下面我們啟動web看看會發生什么神奇的事情。下面我們訪問http://localhost:8080/SpringMVC/welcome

截圖06

奇跡發生了,我們並沒有創建登陸頁面,那這個登陸頁面哪里來的呢?哈哈,不要着急,慢慢來講,看看url spring_security_login ,還記得我們前面配置的spring security 的配置文件的<http>這個配置默認會開啟幾個過濾器,其中有一個就是攔截發現我們沒登陸然后查找登陸頁面,但為什么自動出來呢?其是它為 我們默認了一個登陸頁面,登陸頁面我們可以指定一個,前面我們沒指定所以檢查發現沒有它就默認了一個登陸頁面給我們,下面我們登陸看看會發生什么情況。 (什么你不知道賬號密碼?其實就是我們spring security配置的那個賬號密碼)。

輸入賬號密碼結果:

截圖07

跳轉到了我們剛剛要訪問的uri了,中間還會檢查我們的賬號是否有權,有權才會訪問成功,無權則會轉到無權訪問頁面。好了,到這里spring mvc+spring security 集成就完成了,剩下的工作就是一步一步的慢慢學習spring security 來使用更多的完善的功能。簡單吧,就這點東西。

到這里我們再試試如果登錄一個不存在的賬號會發生什么情況、我輸入了一個admin、結果出現如下圖:

截圖08

spring security已經幫我們檢查了,賬號不存在,他會把我們繼續重定向到登錄頁面,知道登錄成功,否則你永遠都面對的是這個登錄頁面。

好了今天主要分享的就這點,師傅引進門修行靠個人。不過我想了想,還是再分享一點有用的、有的人會想如果我的登錄頁面需要自定義怎么辦?下面我們就講講。

首先自定義登陸,我們需要修改applicationContext-security.xml 配置文件,修改如下:

復制代碼
    <!-- 開啟默認的攔截器 --> 
      <http auto-config='true'> 
         <!-- 允許訪問的uri --> 
         <intercept-url pattern="/**" access="ROLE_USER" /> 
         <!-- 登陸頁面配置 --> 
          <form-login login-page="/login.jsp" default-target-url="/index.jsp" authentication-failure-url="/login.jsp?error=true"/> 
       </http> 
       
       <!-- 權限管理者 -->     
       <authentication-manager> 
           <!-- 權限提供者 --> 
        <authentication-provider> 
          <!-- 可提供登陸訪問的用戶 --> 
          <user-service> 
            <user name="haha" password="haha" authorities="ROLE_USER, ROLE_ADMIN" /> 
            <user name="xixi" password="xixi" authorities="ROLE_USER" /> 
          </user-service> 
        </authentication-provider> 
      </authentication-manager>
復制代碼

 

其中就多加 了一個form 配置節點,從命名可以看出login-page就是你的登陸頁面,default-target-url是默認的登陸成功后的頁 面,authentication-failure-url就是當你輸入非法賬號或者密碼自動重定向到login.jsp.

接下來創建我們自定義的登陸頁面,我的就是login.jsp,有人到這里會想,form接下來該如何寫呢?怎么寫才能被攔截呢?如下:

   

    <h1>user login</h1> 
    <form action="j_spring_security_check" method="post"> 
        用戶名<input type="text" name="j_username"/><br/> 
        密碼<input type="password" name="j_password"/><br/> 
        <input type="submit" value="submit"/> 
    </form>

 

action="j_spring_security_check"必須這樣寫,否則攔截器攔截不到。登陸的字段j_username j_password必須這樣寫,否則你的登陸攔截器獲取不到value。當然你也可以自定義,但前提是你必須繼承 UsernamePasswordAuthenticationFilter 過濾器去重寫一下,這里我們就不麻煩了,而且一般情況下我們不需要重寫,就用它提供的即可。好了,到這里我們可以啟動服務器了。我們再次訪問:http://localhost:8080/SpringMVC/welcome看看會發生神馬變化。如圖:

截圖10

咦?這是什么情況?url變了,是我們要訪問的登陸地址。可是頁面的登陸form呢?不要着急,這種情況我當時見多了,第一反應login.jsp 沒有被放行,攔截下來了、受保護的資源。前面我們不是講過spring  security 是保護在web最外層的嘛,訪問任何資源需要投票,授權才能訪問的,這個也不例外。

好了,知道神馬情況了,我們修改吧!修改如下部分片段即可:

      

復制代碼
     <!-- 開啟默認的攔截器 --> 
      <http auto-config='true'> 
         <!--對login.jsp放行,不用保護--> 
         <intercept-url pattern="/login.jsp" filters="none" /> 
         <!-- 允許訪問的uri --> 
         <intercept-url pattern="/**" access="ROLE_USER" /> 
         <!-- 登陸頁面配置 --> 
         <form-login login-page="/login.jsp" default-target-url="/index.jsp" authentication-failure-url="/login.jsp?error=true"/> 
       </http> 
復制代碼

 


然后我們啟動服務器再次訪問http://localhost:8080/SpringMVC/welcome

不幸的事情又發生了,控制台報錯,服務器啟動失敗!如下圖:

截圖11

截圖12

其實大概的意思是講下面的這個配置作廢了。

<!--對login.jsp放行,不用保護-->
<intercept-url pattern="/login.jsp" filters="none" />這個配置是spring security 2.X中的,3.X以后作廢了,使用新的方式了。但最起碼你讓我不能再次調用撒,這樣我就知道沒有這個標簽了,可以理解的是,廢棄相關配置要耗費很大的精 力,動一發而牽全身,所以它還可以調用,但是運行的時候就不能。不過錯誤告訴我們怎么使用新的標簽了,就是新建一個節點標簽,屬性 security="none" 來放行,好了,我們修改一下。修改部分配置如下:

    

復制代碼
       <!-- spring securit 3.X新的資源放行配置方式,不受保護的資源 -->                   
       <http pattern="/login.jsp" security="none"/>              
                        
       <!-- 開啟默認的攔截器 --> 
       <http auto-config='true'> 
          <!-- 允許訪問的uri --> 
          <intercept-url pattern="/**" access="ROLE_USER" /> 
          <!-- 登陸頁面配置 --> 
          <form-login login-page="/login.jsp" default-target-url="/index.jsp" authentication-failure-url="/login.jsp?error=true"/> 
        </http>
復制代碼

 

在http節點上面再加一個節點,然后配置不需要攔截的。pattern屬性的意思就是通過正則表達式來匹配的。security="none"就 是不安全的,意思就是不受spring security保護的資源,這里還要提一點,就是.jpg、.gif、.swf、.css、.js/等等資源文件都會被攔截下來,即使他是包含在一個已 經放行的jsp頁面或者uri的request、怎么理解?就是比如:我們的login.jsp放行了,但是我們沒有放行.jpg這樣的圖片資源,當我們 訪問login.jsp的時候圖片是不顯示的,因為它沒有被放行,從這里可以看出spring security是非常嚴格的檢查機制。假如我們要放行那些怎么辦?

spring security 2.X中配置如下:

     

復制代碼
  <http auto-config='true'> 
      <!-- public 資源文件 –> 
      <intercept-url pattern="/**/*.jpg" filters="none" />  
      <intercept-url pattern="/**/*.png" filters="none" />  
      <intercept-url pattern="/**/*.gif" filters="none" /> 
      <intercept-url pattern="/**/*.ico" filters="none" /> 
      <intercept-url pattern="/**/*.css" filters="none" /> 
      <intercept-url pattern="/**/*.js" filters="none" />


       <!-- 允許訪問的uri --> 
       <intercept-url pattern="/**" access="ROLE_USER" /> 
       <!-- 登陸頁面配置 --> 
       <form-login login-page="/login.jsp" default-target-url="/index.jsp" authentication-failure-url="/login.jsp?error=true"/> 
     </http>
復制代碼

 

當然我們這里講spring security 3.X,所以3.X的如下:

復制代碼
<http pattern="/**/*.jpg" security="none"/>              
<http pattern="/**/*.png" security="none"/>              
<http pattern="/**/*.gif" security="none"/> 
<http pattern="/**/*.ico" security="none"/>              
<http pattern="/**/*.css" security="none"/> 
<http pattern="/**/*.js" security="none"/>    
<!-- spring securit 3.X新的資源放行配置方式,不受保護的資源 -->                   
<http pattern="/login.jsp" security="none"/>             

  <http auto-config='true'> 
  
     <!-- 允許訪問的uri --> 
     <intercept-url pattern="/**" access="ROLE_USER" /> 
     <!-- 登陸頁面配置 --> 
     <form-login login-page="/login.jsp" default-target-url="/index.jsp" authentication-failure-url="/login.jsp?error=true"/> 
   </http>
復制代碼

 

上面的pattern="/**/*.jpg" 配置意思就是放行,項目中所有的.jpg資源,以后的以此類推的原理。你亦可以放行某一個文件下的,具體就是正則表達式的配置。

好了,我們還是回到剛剛修改的放行資源試試,再次啟動服務器訪問:http://localhost:8080/SpringMVC/welcome

截圖13

當我們再次訪問的時候login.jsp已經出來了、這個時候我們登陸,成功后直接跳轉到/welcome 的響應頁面。結果如圖;

截圖14

這里我們沒有配置用戶資源訪問權限,所以訪問的資源直接可以訪問,如果配置了訪問權限登陸成功后,spring security還會檢查是否有權訪問,無權重定向。

 

好了到這里,今天分享的入門到此完畢。后面有時間再慢慢分享,這個框架還是很值得學習的。功能比較強大,官方文檔比較全面,可以好好研讀一下,感謝抽寶貴的時間閱讀。

 

轉自:http://www.cnblogs.com/Beyond-bit/p/springmvc_and_springsecurity.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM