cas 3.5.3服務器搭建+spring boot集成+shiro模擬登陸(不修改現有shiro認證架構)

由於現有系統外部接入須要,須要支持三方單點登陸。因爲系統自己已是微服務架構,由多個業務獨立的子系統組成,因此有本身的用戶認證微服務(不是cas,咱們基礎設施已經夠多了,如今能不增長就不增長)。可是由於客戶和其餘接入(公有云網絡)緣由,沒法經過token+redis實現,因此還須要支持外部的cas。html

現有認證系統採用shiro實現,業務子系統採用shiro+token假登陸實現。如今要支持經過配置設置系統自身的認證子系統是否啓用三方cas登陸。這樣不管是使用本身的認證明現、仍是三方CAS,總體流程就徹底同樣。java

CAS服務器搭建

從cas 4開始,官方就已經再也不提供release war,轉而須要自行下載源碼打包,網上不少,這裏再也不闡述(下載依賴有點慢)。4.x以及以前的war能夠從https://mvnrepository.com/artifact/org.jasig.cas/cas-server-webapp下載。下載後,解壓到tomcat webapp目錄:git

啓動:github

 

 

修改下列配置:web

 

去除https認證:redis

在tomcat\webapps\cas\WEB-INF\deployerConfigContext.xml文件
      的p:httpClient-ref="httpClient"後面添加p:requireSecure="false" 
把tomcat\webapps\cas\WEB-INF\spring-configuration的
      ticketGrantingTicketCookieGenerator.xml文件裏面把p:cookieSecure="true"改成false;
      p:cookieMaxAge="-1"改成3600(-1是不保存cookie,3600秒是一個小時,保存登陸信息)
把tomcat\webapps\cas\WEB-INF\spring-configuration的
      warnCookieGenerator.xml的p:cookieSecure="true"改成false
      p:cookieMaxAge="-1"改成3600

 配置單點登出: spring

  將tomcat\webapps\cas\WEB-INF\cas-servlet.xml中${cas.logout.followServiceRedirects:false}括號裏的值改成trueapi

能夠配置簡單測試認證(去掉<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />註釋)或基於數據源認證(能夠參考https://www.cnblogs.com/wlwl/p/10056067.html)。tomcat

spring boot cas客戶端集成

庫依賴:服務器

        <dependency>
            <groupId>net.unicon.cas</groupId>
            <artifactId>cas-client-autoconfig-support</artifactId>
            <version>1.5.0-GA</version>
        </dependency>
        <dependency>
            <groupId>org.jasig.cas.client</groupId>
            <artifactId>cas-client-core</artifactId>
            <version>3.2.1</version>
            <exclusions>
                <exclusion>
                    <artifactId>servlet-api</artifactId>
                    <groupId>javax.servlet</groupId>
                </exclusion>
            </exclusions>
        </dependency>

application.properties中加上下列配置:

cas.server-url-prefix=http://localhost:8080/cas
cas.server-login-url=http://localhost:8080/cas/login
cas.client-host-url=http://localhost:18080/
cas.use-session=true
cas.validation-type=cas
casClientLogoutUrl=http://localhost:8080/cas/logout?service=http://localhost:18080/tabase/logout.html
import net.unicon.cas.client.configuration.EnableCasClient;

@EnableCasClient //啓用cas client
@CloudApplication
public class ConsumerStarter {
    public static void main(String[] args) {
        CloudBootstrap.run(ConsumerStarter.class, args);
    }
}

package com.hs;

import java.util.HashMap;
import java.util.Map;

import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CASAutoConfig {
    @Value("${cas.server-url-prefix}")
    private String serverUrlPrefix;
    @Value("${cas.server-login-url}")
    private String serverLoginUrl;
    @Value("${cas.client-host-url}")
    private String clientHostUrl;
 
    /**
     * 受權過濾器
     * @return
     */
    @Bean
    public FilterRegistrationBean filterAuthenticationRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new AuthenticationFilter());
        // 設定匹配的路徑
        registration.addUrlPatterns("/*");
        Map<String,String> initParameters = new HashMap<String, String>();
        initParameters.put("casServerLoginUrl", serverUrlPrefix);
        initParameters.put("serverName", clientHostUrl);
        //忽略的url,"|"分隔多個url
        initParameters.put("ignorePattern", "/logout/success|/index");
        registration.setInitParameters(initParameters);
        // 設定加載的順序
        registration.setOrder(1);
        return registration;
    }
}

 

shiro模擬登陸(不修改現有shiro認證架構)

cas登陸成功後,會給應用返回ticket,其中包含了用戶名。此時應用主頁會被shiro過濾器UserFilter攔截,在其中能夠判斷HttpServletRequest上是否有ticket的用戶名,有、且爲有效用戶名,就能夠用該用戶名模擬登陸了。這樣整個shiro認證流程幾乎沒有變化,也不須要修改FormAuthenticationFilter。

cas在2.x和3.x版本獲取用戶名不同,這一點須要注意。

2.x版本client獲取CAS傳遞過來的用戶名的方法:

// 如下三者均可以
session.getAttribute(CASFilter.CAS_FILTER_USER);
session.getAttribute("edu.yale.its.tp.cas.client.filter.user");

CASFilterRequestWrapper  reqWrapper=new CASFilterRequestWrapper(request);
reqWrapper.getRemoteUser());

3.x版本client獲取CAS傳遞過來的用戶名的方法:

HttpServletRequest request = ServletActionContext.getRequest();   
AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();   
String username = principal.getName();   
Long orgnId = Long.parseLong(principal.getAttributes().get("orgnId").toString());  

拿到後,就能夠模擬登錄了。

        boolean isAllowed = super.isAccessAllowed(request, response, mappedValue);
        //
        if (isAllowed) {

        } else if (Boolean.valueOf(BaseConfig.getConfig("ta.casEnable","false"))) {
            AttributePrincipal principal = (AttributePrincipal)((HttpServletRequest) request).getUserPrincipal();
            String username = principal.getName();
            Subject subject = getSubject(request, response);
            AuthenticationToken token = new UsernamePasswordToken();
            ((UsernamePasswordToken) token).setUsername(username);
            ((UsernamePasswordToken) token).setPassword(new char[] {'1'});
            subject.login(token);
            isAllowed = super.isAccessAllowed(request, response, mappedValue);
        }

shiro登出

在shiro的logoutFilter中調用session.invalidate()便可。而後返回casClientLogoutUrl配置的地址退出cas便可。

        /**
         * CAS添加開始
         */
        if (StringUtils.isNotBlank(BaseConfig.getConfig("casClientLogoutUrl"))) {
            ((HttpServletRequest)request).getSession().invalidate();
            redirectUrl = BaseConfig.getConfig("casClientLogoutUrl");
        }
        // CAS添加結束
        return redirectUrl;

 

此致,就完整的實現了cas+shiro模擬登陸。

CAS ticket過時策略,參考:https://www.cnblogs.com/gao241/p/3367869.html

CAS流程介紹,參考:https://www.cnblogs.com/xiatian0721/p/8136305.html

CAS官方架構參考:https://apereo.github.io/cas/5.3.x/planning/Architecture.html

相關文章
相關標籤/搜索