1. 程式人生 > >SSO之CAS整合SpringSecurity

SSO之CAS整合SpringSecurity

前言:

關於CAS的客戶端搭建配置以及服務端的部署配置請參考前面文章。

一:引入CAS與SpringSecurity的Jar

<properties>
    <spring.version>4.2.4.RELEASE</spring.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!--安全框架security-->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>4.1.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>4.1.0.RELEASE</version>
    </dependency>
    <!--cas與springSecurity整合-->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-cas</artifactId>
        <version>4.1.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.jasig.cas.client</groupId>
        <artifactId>cas-client-core</artifactId>
        <version>3.3.3</version>
        <!--依賴排除log4j-->
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>log4j-over-slf4j</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <!-- 指定埠 -->
                <port>9113</port>
                <!-- 請求路徑 -->
                <path>/</path>
            </configuration>
        </plugin>
    </plugins>
</build>

二:web.xml增加SpringSecurity過濾器鏈配置

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-security.xml</param-value>
</context-param>
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

<!--springsecurity的過濾器鏈-->
<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>
<!-- 解決post亂碼 -->
<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>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<!--springmvc的前端控制器-->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 指定載入的配置檔案 ,通過引數contextConfigLocation載入-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

三:SpringSecurity配置檔案

<?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">

   <!--1.不攔截資源和路徑配置-->
   <http pattern="/index2.jsp" security="none"></http>
   <!--   entry-point-ref  入口點引用 -->
   <http use-expressions="false" entry-point-ref="casProcessingFilterEntryPoint">
      <intercept-url pattern="/**" access="ROLE_USER"/>
      <csrf disabled="true"/>
      <!-- custom-filter為過濾器, position 表示將過濾器放在指定的位置上,before表示放在指定位置之前  ,after表示放在指定的位置之後  -->
      <custom-filter ref="casAuthenticationFilter"  position="CAS_FILTER" />
      <custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/>
      <custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/>
   </http>

   <!-- CAS入口點 開始 -->
   <beans:bean id="casProcessingFilterEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
      <!-- 單點登入伺服器登入URL -->
      <beans:property name="loginUrl" value="http://localhost:9100/cas/login"/>
      <beans:property name="serviceProperties" ref="serviceProperties"/>
   </beans:bean>
   <beans:bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
      <!--service 配置自身工程的根地址+/login/cas   -->
      <beans:property name="service" value="http://localhost:9113/login/cas"/>
   </beans:bean>
   <!-- CAS入口點 結束 -->

   <!-- 認證過濾器 開始 -->
   <beans:bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
      <beans:property name="authenticationManager" ref="authenticationManager"/>
   </beans:bean>
   <!-- 認證管理器 -->
   <authentication-manager alias="authenticationManager">
      <authentication-provider  ref="casAuthenticationProvider">
      </authentication-provider>
   </authentication-manager>
   <!-- 認證提供者 -->
   <beans:bean id="casAuthenticationProvider"     class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
      <beans:property name="authenticationUserDetailsService">
         <beans:bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
            <beans:constructor-arg ref="userDetailsService" />
         </beans:bean>
      </beans:property>
      <beans:property name="serviceProperties" ref="serviceProperties"/>
      <!-- ticketValidator 為票據驗證器 -->
      <beans:property name="ticketValidator">
         <beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
            <beans:constructor-arg index="0" value="http://localhost:9100/cas"/>
         </beans:bean>
      </beans:property>
      <beans:property name="key" value="an_id_for_this_auth_provider_only"/>
   </beans:bean>
   <!-- 認證類 -->
   <beans:bean id="userDetailsService" class="com.xucj.demo.service.UserDetailsServiceImpl"/>

   <!-- 認證過濾器 結束 -->
   <!-- 單點登出  開始  -->
   <beans:bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>
   <beans:bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
      <beans:constructor-arg value="http://localhost:9100/cas/logout?service=http://localhost:9113/index.jsp"/>
      <beans:constructor-arg>
         <beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
      </beans:constructor-arg>
      <beans:property name="filterProcessesUrl" value="/logout/cas"/>
   </beans:bean>
   <!-- 單點登出  結束 -->
</beans:beans>

com.xucj.demo.service包下的自定義認證類:


import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.ArrayList;
import java.util.List;

/**
 * 自定義認證類
 */
public class UserDetailsServiceImpl implements UserDetailsService{
    /*
        *@Desc 自定義認證類,主要是查詢資料庫,返回使用者資訊
        *@param username 認證管理器收集的頁面上的使用者名稱
        *@return org.springframework.security.core.userdetails.UserDetails
        **/
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //查詢資料庫
        //使用者必須存在,並且狀態必須是稽核通過
        //1 username 2 password 3.許可權列表
        List<GrantedAuthority> authorities = new ArrayList<>();//許可權列表
        GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_SELLER");//許可權物件
        GrantedAuthority authority2 = new SimpleGrantedAuthority("ROLE_USER");//許可權物件
        authorities.add(authority);
        authorities.add(authority2);
        return new User(username,"",authorities);
    }
}

五:測試

新建index.jsp和index2.jsp,根據上面四的配置得知,index2.jsp不登入也不會被攔截,如下:

啟動專案,訪問:http://localhost:9113/可以跳轉到自定義的登入頁面,

根據四的配置可知,退出的路徑:/logout/cas

登出後跳轉到的路徑:http://localhost:9113/index.jsp