JavaEE學習日誌(一百零六): SpringSecurity安全框架入門

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

  1. 在原先的基礎上,指定安全框架使用的頁面,注意login頁面請求的路徑,只能爲login
  2. 對登錄、失敗和favicon.ico進行放行
  3. 關閉跨站請求僞造
  4. 退出登錄的配置
<?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 {

}

四、實現接口

  1. 重寫loadUserByUsername方法,會將頁面中輸入的username傳遞過來
  2. 創建UserDao接口,根據username查詢用戶對象
  3. 當用戶不爲空時,創建角色集合對象,並添加角色對象(此處爲臨時角色對象)
  4. 創建UserDetails對象,將usernamepassword角色集合對象三個參數作爲構造方法傳入(User爲實現類)
  5. 返回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">
            <!--&lt;!&ndash;用戶服務對象&ndash;&gt;
            <security:user-service>
                &lt;!&ndash;用戶信息:臨時的賬號和密碼
                    {noop}:不使用加密
                    authorities:指定用戶的認證角色
                &ndash;&gt;
                <security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
            </security:user-service>-->

        </security:authentication-provider>
    </security:authentication-manager>

此時,配置完成,當在login界面中輸入數據庫中存在的用戶時,即可登錄成功
在這裏插入圖片描述

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