SpringSecurity安全框架
Spring Security是一個能夠爲基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Control ,DI:Dependency Injection 依賴注入)和AOP(面向切面編程)功能,爲應用系統提供聲明式的安全訪問控制功能,減少了爲企業系統安全控制編寫大量重複代碼的工作。
- “認證”,是爲用戶建立一個他所聲明的主體。主體一般是指用戶,設備或可以在你係 統中執行動作的其他系統。
- “授權”,指的是一個用戶能否在你的應用中執行某個操作,在到達授權判斷之前,身份的主題已經由身份驗證過程建立了。
安全框架入門
一、引入依賴
<!--引入安全框架web層的內容-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<!--引入安全框架的配置文件 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<!--引入安全框架的標籤庫-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.security.version}</version>
</dependency>
二、安全框架配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
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
">
<!--認證-->
<!--
配置攔截的規則
auto-config="使用自帶的頁面"
use-expressions="是否使用spel表達式",如果使用表達式:hasRole('ROLE_USER')
-->
<security:http auto-config="true" use-expressions="false">
<!-- 配置攔截的請求地址,任何請求地址都必須有ROLE_USER的權限 -->
<security:intercept-url pattern="/**" access="ROLE_USER"/>
</security:http>
<!-- 配置認證(登錄)信息:認證管理器 -->
<security:authentication-manager>
<!--認證信息的提供者-->
<security:authentication-provider>
<!--用戶服務對象-->
<security:user-service>
<!--用戶信息:臨時的賬號和密碼
{noop}:不使用加密
authorities:指定用戶的認證角色
-->
<security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
三、web.xml配置
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--通過全局參數引入配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-security.xml</param-value>
</context-param>
<!--委派代理過濾器鏈-->
<!--配置委派代理過濾器: filter-name必須是: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>
<!--創建spring容器對象-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
當訪問index.jsp時,就會進入認證頁面(默認)
使用自定義頁面
添加自定義頁面
配置spring-security.xml
- 在原先的基礎上,指定安全框架使用的頁面,注意login頁面請求的路徑,只能爲login
- 對登錄、失敗和favicon.ico進行放行
- 關閉跨站請求僞造
- 退出登錄的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
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
">
<!--對登錄和失敗頁面放行-->
<security:http pattern="/login.jsp" security="none"></security:http>
<security:http pattern="/error.jsp" security="none"></security:http>
<security:http pattern="/favicon.ico" security="none"></security:http>
<!--
配置攔截的規則
auto-config="使用自帶的頁面"
use-expressions="是否使用spel表達式",如果使用表達式:hasRole('ROLE_USER')
-->
<security:http auto-config="true" use-expressions="false">
<!-- 配置攔截的請求地址,任何請求地址都必須有ROLE_USER的權限 -->
<security:intercept-url pattern="/**" access="ROLE_USER"/>
<!--指定安全框架使用的頁面-->
<!--
login-page:指定登錄頁面
login-processing-url:登錄的請求路徑,登錄時必須使用該路徑
default-target-url:登錄成功後進入的頁面
authentication-failure-url:認證失敗要進入的頁面
-->
<security:form-login login-page="/login.jsp"
login-processing-url="/login"
default-target-url="/success.jsp"
authentication-failure-url="/error.jsp"
></security:form-login>
<!--關閉跨站請求僞造-->
<security:csrf disabled="true"></security:csrf>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/>
</security:http>
<!-- 配置認證(登錄)信息:認證管理器 -->
<security:authentication-manager>
<!--認證信息的提供者-->
<security:authentication-provider>
<!--用戶服務對象-->
<security:user-service>
<!--用戶信息:臨時的賬號和密碼
{noop}:不使用加密
authorities:指定用戶的認證角色
-->
<security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
安全框架集成到項目
不指定用戶
一、添加spring-security.xml
注意:需要對favicon.ico和靜態資源放行
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
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
">
<!--對登錄和失敗頁面放行-->
<security:http pattern="/login.jsp" security="none"></security:http>
<security:http pattern="/error.jsp" security="none"></security:http>
<security:http pattern="/favicon.ico" security="none"></security:http>
<security:http pattern="/css/**" security="none"></security:http>
<security:http pattern="/img/**" security="none"></security:http>
<security:http pattern="/plugins/**" security="none"></security:http>
<!--
配置攔截的規則
auto-config="使用自帶的頁面"
use-expressions="是否使用spel表達式",如果使用表達式:hasRole('ROLE_USER')
-->
<security:http auto-config="true" use-expressions="false">
<!-- 配置攔截的請求地址,任何請求地址都必須有ROLE_USER的權限 -->
<security:intercept-url pattern="/**" access="ROLE_USER"/>
<!--指定安全框架使用的頁面-->
<!--
login-page:指定登錄頁面
login-processing-url:登錄的請求路徑,登錄時必須使用該路徑
default-target-url:登錄成功後進入的頁面
authentication-failure-url:認證失敗要進入的頁面
-->
<security:form-login login-page="/login.jsp"
login-processing-url="/login"
default-target-url="/index.jsp"
authentication-failure-url="/login.jsp"
></security:form-login>
<!--關閉跨站請求僞造-->
<security:csrf disabled="true"></security:csrf>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/>
</security:http>
<!-- 配置認證(登錄)信息:認證管理器 -->
<security:authentication-manager>
<!--認證信息的提供者-->
<security:authentication-provider>
<!--用戶服務對象-->
<security:user-service>
<!--用戶信息:臨時的賬號和密碼
{noop}:不使用加密
authorities:指定用戶的認證角色
-->
<security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
二、web.xml
配置委派代理過濾器鏈,並引入spring-security.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--全局參數,指定配置文件的路徑-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/*.xml,classpath:spring-security.xml</param-value>
</context-param>
<!--編碼過濾器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<!--委派代理過濾器鏈-->
<!--配置委派代理過濾器: filter-name必須是: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>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--監聽器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
當訪問項目的任何一個路徑時,就會跳轉到login頁面
指定用戶
一、在數據庫中,添加sys_user表,並添加數據(注意oracle數據庫一定要提交!)
二、創建實體類SysUser,注意不能創建User,User爲安全框架的內置對象
三、創建UserService接口,繼承UserDetailsService
/**
* UserDetailsService:接口中提供了一個方法,loadUserByUsername
*/
public interface UserService extends UserDetailsService {
}
四、實現接口
- 重寫
loadUserByUsername
方法,會將頁面中輸入的username
傳遞過來 - 創建UserDao接口,根據
username
查詢用戶對象 - 當用戶不爲空時,創建角色集合對象,並添加角色對象(此處爲臨時角色對象)
- 創建UserDetails對象,將
username
、password
、角色集合對象
三個參數作爲構造方法傳入(User爲實現類) - 返回UserDetails對象
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserDao userDao;
/**
* 通過用戶名得到用戶對象
* 創建用戶詳情對象,返回
* @param username
* @return UserDetails:用戶詳情
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//根據用戶名獲取用戶(SysUser)對象
SysUser sysUser = userDao.findByUsername(username);
if(sysUser!=null){
//創建角色集合對象
Collection<GrantedAuthority> authorities = new ArrayList<>();
//創建臨時角色對象
SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_USER");
//對象添加到集合中
authorities.add(grantedAuthority);
/**
* 參數1:username
* 參數2:password
* 參數3:角色列表對象
*/
UserDetails user = new User(sysUser.getUsername(),"{noop}"+sysUser.getPassword(),authorities);
return user;
}
return null;
}
}
五、在配置文件中關聯用戶服務對象
<!-- 配置認證(登錄)信息:認證管理器 -->
<security:authentication-manager>
<!--認證信息的提供者:關聯用戶服務對象,提供賬號和密碼-->
<security:authentication-provider user-service-ref="userServiceImpl">
<!--<!–用戶服務對象–>
<security:user-service>
<!–用戶信息:臨時的賬號和密碼
{noop}:不使用加密
authorities:指定用戶的認證角色
–>
<security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
</security:user-service>-->
</security:authentication-provider>
</security:authentication-manager>
此時,配置完成,當在login界面中輸入數據庫中存在的用戶時,即可登錄成功