01-Spring Security框架學習

01-Spring Security框架學習

簡介

Spring Security 是什麼

Spring Security 爲基於 Java EE 的企業應用提供綜合的安全服務。尤其支持使用Spring Framework構建的項目,這是目前企業軟件開發的流行的Java EE解決方案。

Spring Security 解決那些問題

Java EE Servlet 規範或 EJB 規範的安全特性在典型的企業應用場景中缺乏深度;在系統環境中做大量的重複配置工作(例:判斷用戶是否登錄,是否具備管理員的權限等)。

一般來說,Web 應用的安全性包括用戶認證(Authentication)和用戶授權(Authorization)兩個部分。用戶認證指的是驗證某個用戶是否爲系統中的合法主體,也就是說用戶能否訪問該系統。用戶認證一般要求用戶提供用戶名和密碼。系統通過校驗用戶名和密碼來完成認證過程。用戶授權指的是驗證某個用戶是否有權限執行某個操作。在一個系統中,不同用戶所具有的權限是不同的。比如對一個文件來說,有的用戶只能進行讀取,而有的用戶可以進行修改。一般來說,系統會爲不同的用戶分配不同的角色,而每個角色則對應一系列的權限。這些概念非常通用,它們並不是 Spring Security 的特性。

Spring Security 的優點

認證級別

在認證級別,Spring Security 支持範圍廣泛的認證模型。大多數認證模型由第三方提供,或由相關標準制定組織(如 IETF)研製,同時Spring Security 提供它自己的認證功能。

  • HTTP BASIC headers認證 (基於IETF RFC標準)
  • HTTP Digest headers認證 (基於IETF RFC標準)
  • HTTP X.509 客戶端證書交換 (基於IETF RFC標準)
  • LDAP (一種非常常見的跨平臺認證需求,在大環境下尤甚)
  • 基於表單的認證 (通常用於簡單的用戶需求)
  • OpenID認證
  • 基於預定義的請求頭進行認證 (諸如計算機集羣)
  • JA-SIG 中央認證服務 (也稱爲CAS, 是一種流行的開源的單點登陸系統)
  • 爲RMI 和 HttpInvoker(一種Spring遠程協議)提供對用戶透明的認證機制
  • 自動的 "remember-me" 認證 (你可以勾選此選項,從而避免在一定時間內進行重複認證)
  • 匿名認證 (爲每個未經認證的用戶提供一個特殊的安全身份)
  • Run-as 認證 (同一個調用需要進行不同的安全校驗時非常有用)
  • Java認證與認證服務 - Java Authentication and Authorization Service (JAAS)
  • JEE
  • 認證 (如果你需要,你仍然可以使用容器託管
  • 認證)
  • Kerberos
  • Java開源單點登陸 - Java Open Source Single Sign On (JOSSO) *
  • OpenNMS網絡管理平臺 - OpenNMS Network Management Platform *
  • AppFuse *
  • AndroMDA *
  • Mule ESB *
  • Direct Web Request (DWR) *
  • Grails *
  • Tapestry *
  • JTrac *
  • Jasypt *
  • Roller *
  • Elastic Path *
  • Atlassian Crowd *
  • 你自己的權限系統 (參見後續內容)

    帶*表示由第三方提供

授權功能

Spring Security允許對授權功能進行深度設置。它關注於三個主要方面:web請求授權、方法調用授權以及域對象實例訪問授權

歷史背景

  • 2004年1月,已經大約有20人在使用此代碼。這些首批用戶開始建議將其作爲一個SourceForge項目,於是項目於2004年3月正式成立。
  • 2006年5月,1.0.0 final release版本正式發佈
  • 2007年年末的時候,正式成爲Spring Portfolio官方項目,並更名爲"Spring Security"。
    ...

Spring Security版本編號 MAJOR.MINOR.PATCH(主版本.小版本.補丁)

  • MAJOR的變更意味着大規模的API的更新,因此很多地方都不會兼容舊版本。
  • MINOR的變更儘可能保持源碼和編譯文件的兼容性,儘管可能有一些設計上的變更或者不兼容的更新。
  • PATCH通常完全向前向後兼容,主要用於修復一些bug與缺陷。

Spring Security 的入門案例

基本步驟

  1. 創建Maven的web項目,在pom.xml中導入依賴入下
<!-- spring-security 的依賴 -->
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-web</artifactId>
  <version>${spring.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-config</artifactId>
  <version>${spring.version}</version>
</dependency>
  1. web.xml 配置過濾器
<!-- 通過 ContextLoaderListener 定義 spring context 容器的xml文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/*.xml
</param-value>
</context-param>

<!-- springSecurity 指定的過濾器:springSecurityFilterChain(該過濾鏈過濾所有的連接) -->
<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>

<!-- web容器(監聽器)啓動加載容器上下文-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
  1. 創建用於演示的頁面,src/main/webapp/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
spring-security,hello world!
歡迎來到,spring-security的世界!
</body>
</html>
  1. 添加Spring Security 的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security.xsd">
  
  <!-- 頁面的鏈接規則 -->     
  <http use-expressions="false">
    <intercept-url pattern="/**" access="ROLE_ADMIN"/>
    <!-- 開啓表單提交功能 -->
    <form-login/>
  </http>
  <!-- 認證管理器 -->
  <authentication-manager>
    <authentication-provider>
      <user-service>
        <user name="admin" password="admin" authorities="ROLE_ADMIN"/>
      </user-service>
    </authentication-provider>
  </authentication-manager>
</beans:beans>

注意:該文件是本案例的重點,基本內容使用註釋。

  • 把security的頭信息的配置作爲了默認配置,那麼以後在進行編寫security的相關配置的時候就不需要前綴。

運行效果

image

出現問題解決

  1. 出現java.lang.NoSuchMethodError: org.springframework.util.AntPathMatcher.setCaseSensitive(Z)V的錯誤,如下詳細錯誤信息
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0': Cannot resolve reference to bean 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0' while setting constructor argument with key [4]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter]: Constructor threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.util.AntPathMatcher.setCaseSensitive(Z)V at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:382) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:157) at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:637) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:140) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1131) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1034) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351) ... 26 more Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter]: Constructor threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.util.AntPathMatcher.setCaseSensitive(Z)V at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1093) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1038) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351) ... 40 more Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter]: Constructor threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.util.AntPathMatcher.setCaseSensitive(Z)V at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1086) ... 48 more Caused by: java.lang.NoSuchMethodError: org.springframework.util.AntPathMatcher.setCaseSensitive(Z)V at org.springframework.security.web.util.matcher.AntPathRequestMatcher$SpringAntMatcher.createMatcher(AntPathRequestMatcher.java:268) at org.springframework.security.web.util.matcher.AntPathRequestMatcher$SpringAntMatcher.<init>(AntPathRequestMatcher.java:252) at org.springframework.security.web.util.matcher.AntPathRequestMatcher$SpringAntMatcher.<init>(AntPathRequestMatcher.java:245) at org.springframework.security.web.util.matcher.AntPathRequestMatcher.<init>(AntPathRequestMatcher.java:116) at org.springframework.security.web.util.matcher.AntPathRequestMatcher.<init>(AntPathRequestMatcher.java:84) at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.<init>(UsernamePasswordAuthenticationFilter.java:62) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147) ... 50 more

    問題原因分析:

    由於AntPathMatcher的類的方法在setCaseSensitive()在Spring-core 4.1.X 中不存在導致.
    參考答案:

    1. ontext-initialization-failed-nosuchmethoderror-antpathmatcher-setcasesensiti

    問題解決方式

    修改Spring和Spring Security的版本到4.2.3.RELEASE

項目

[項目剛剛開始,後期上傳至Git倉庫共享]


參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章