日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

单点

發布時間:2023/12/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单点 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

單點登陸


單點登陸相關知識
理解Cookie和Session機制
單點登陸時序圖

cas-clicet-core-3.1.10.jar(cas客戶端)源碼分析
項目背景:

  • 基于springboot集成cas客戶端
  • 沒有使用springboot自帶集成方式,使用傳統原始的集成方式
  • 由于cas服務端版本比較低,客戶端使用的版本比較低

一、先了解如何集成,如何使用
1、cas配置參數實體@Configuration

@Getter @Setter public class CasConfiguration {//cas登錄路徑@Value("${cas.casServerUrlPrefix}${cas.casServerLoginUrl}")private String casServerLoginUrl;@Value("${cas.casServerUrlPrefix}${cas.casServerLogoutUrl}")private String casServerLogoutUrl;//cas客戶端服務器@Value("${cas.clientServerName}${cas.clientService}")private String clientService;//登錄成功地址@Value("${cas.clientServerName}${cas.clientService}${cas.clientLoginSuccessUrl}")private String clientLoginSuccessUrl;//白名單@Value("${cas.whiteList}")private String whiteList;//cas服務器@Value("${cas.casServerUrlPrefix}")private String casServerUrlPrefix;//cas客戶端服務器根目錄@Value("${cas.clientServerName}")private String clientServerName;}

2、動態參數配置在application.yml中

cas:#cas服務器地址casServerUrlPrefix: http://111.198.186.80:18080/cas#本地地址clientServerName: http://127.0.0.1:9090#登錄路徑casServerLoginUrl: /login#注銷路徑casServerLogoutUrl: /logout#項目名稱,上下文clientService: /project-test#成功后返回路徑clientLoginSuccessUrl: /vue/index.html#白名單whiteList: /login/**.**/css/**

3、配置多個過濾器

/** @Description:cas客戶端過濾器配置* @Author: wangwei* @Date:2020/3/27 10:46*/ @Configuration public class CasFilter {@AutowiredCasConfiguration casConfiguration;/** @Description:退出登錄過濾器,需要放在最前面* @Param:[]* @Return: org.springframework.boot.web.servlet.FilterRegistrationBean* @Throws:* @Author: wangwei* @Date:2020/3/31 15:44*/@Beanpublic FilterRegistrationBean CasSingleSignOutFilter() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();//配置攔截器參數mapMap<String, String> map = new HashMap<>(16);SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();filterRegistrationBean.setFilter(singleSignOutFilter);map.put("casServerUrlPrefix", casConfiguration.getCasServerUrlPrefix());filterRegistrationBean.setInitParameters(map);String url = "/*";filterRegistrationBean.addUrlPatterns(url);filterRegistrationBean.setName("CasSingleSignOutFilter");filterRegistrationBean.setOrder(1);return filterRegistrationBean;}//配置 SingleSignOutHttpSessionListener@Beanpublic ServletListenerRegistrationBean<org.jasig.cas.client.session.SingleSignOutHttpSessionListener> casListener() {return new ServletListenerRegistrationBean<>(new org.jasig.cas.client.session.SingleSignOutHttpSessionListener());}/** @Description:CAS認證filter casServerLoginUrl參數:表示CAS Server登錄URL,后面追加appResId參數,表明應用類型(公文系統暫時使用GONGWEN,備案系統使用BHXT)。service參數:表示在通過CAS Server認證后的返回頁面。 localLoginUrl參數:本地登錄URL。 renew參數:請不要修改。whiteList參數:不進行認證檢查的URI,使用分號進行分割。如果以/為結尾,則表示該路徑下的所有URI均不進行認證檢查。* @Param:[]* @Return: org.springframework.boot.web.servlet.FilterRegistrationBean* @Throws:* @Author: wangwei* @Date:2020/3/27 11:10*/@Beanpublic FilterRegistrationBean CasAuthenticationFilter() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();//配置攔截器參數mapMap<String, String> map = new HashMap<>(16);WhiteListJwtAndAuthenticationFilter casAuthenticationFilter = new WhiteListJwtAndAuthenticationFilter();filterRegistrationBean.setFilter(casAuthenticationFilter);map.put("casServerLoginUrl", casConfiguration.getCasServerLoginUrl());map.put("service", casConfiguration.getClientLoginSuccessUrl());map.put("localLoginUrl", casConfiguration.getClientLoginSuccessUrl());map.put("renew", "false");map.put("whiteList", casConfiguration.getWhiteList());filterRegistrationBean.setInitParameters(map);String url = "/*";filterRegistrationBean.addUrlPatterns(url);filterRegistrationBean.setName("casAuthenticationFilter");filterRegistrationBean.setOrder(2);return filterRegistrationBean;}/** @Description:CAS驗證filter serverName參數:應用根路徑。 CAS Http請求Wrapper filter:在通過CAS認證或驗證通過后,將user id賦值到request中remoteUser中* @Param:[]* @Return: org.springframework.boot.web.servlet.FilterRegistrationBean* @Throws:* @Author: wangwei* @Date:2020/3/27 11:10*/@Beanpublic FilterRegistrationBean CasValidationFilter() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();//配置攔截器參數mapMap<String, String> map = new HashMap<>(16);CustomCas30ProxyReceivingTicketValidationFilter casValidationFilter = new CustomCas30ProxyReceivingTicketValidationFilter();filterRegistrationBean.setFilter(casValidationFilter);map.put("casServerUrlPrefix", casConfiguration.getCasServerUrlPrefix());map.put("serverName", casConfiguration.getClientServerName());filterRegistrationBean.setInitParameters(map);String url = "/*";filterRegistrationBean.addUrlPatterns(url);filterRegistrationBean.setName("casValidationFilter");filterRegistrationBean.setOrder(3);return filterRegistrationBean;}@Beanpublic FilterRegistrationBean CasHttpServletRequestFilter() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();//配置攔截器參數mapHttpServletRequestWrapperFilter casHttpServletRequestFilter = new HttpServletRequestWrapperFilter();filterRegistrationBean.setFilter(casHttpServletRequestFilter);String url = "/*";filterRegistrationBean.addUrlPatterns(url);filterRegistrationBean.setName("casHttpServletRequestFilter");filterRegistrationBean.setOrder(4);return filterRegistrationBean;}}

4、CustomCas30ProxyReceivingTicketValidationFilter過濾器

public class CustomCas30ProxyReceivingTicketValidationFilter extends Cas10TicketValidationFilter {/** @Description:校驗成功后設置sesion* @Param:[request, response, assertion]* @Return: void* @Throws:* @Author: wangwei* @Date:2020/3/29 10:40*/@Overrideprotected void onSuccessfulValidation(HttpServletRequest request, HttpServletResponse response, Assertion assertion) {String dcpLoginInfo = (String) assertion.getPrincipal().getName();javax.servlet.http.HttpSession session=request.getSession(false);if(session!=null){session.setAttribute("systemUser",dcpLoginInfo);}}}

5、WhiteListJwtAndAuthenticationFilter 復寫認證過濾器,添加了白名單,跳過cas認證的條件

public class WhiteListJwtAndAuthenticationFilter extends AbstractCasFilter {private String casServerLoginUrl;private boolean renew = false;private boolean gateway = false;private List<String> whiteList;private GatewayResolver gatewayStorage = new DefaultGatewayResolverImpl();public WhiteListJwtAndAuthenticationFilter() {}@Overrideprotected void initInternal(FilterConfig filterConfig) throws ServletException {if (!this.isIgnoreInitConfiguration()) {super.initInternal(filterConfig);this.setCasServerLoginUrl(this.getPropertyFromInitParams(filterConfig, "casServerLoginUrl", (String)null));this.log.trace("Loaded CasServerLoginUrl parameter: " + this.casServerLoginUrl);this.setRenew(this.parseBoolean(this.getPropertyFromInitParams(filterConfig, "renew", "false")));this.log.trace("Loaded renew parameter: " + this.renew);this.setGateway(this.parseBoolean(this.getPropertyFromInitParams(filterConfig, "gateway", "false")));this.log.trace("Loaded gateway parameter: " + this.gateway);this.setWhiteList(this.parseStringList(this.getPropertyFromInitParams(filterConfig, "whiteList", "")));String gatewayStorageClass = this.getPropertyFromInitParams(filterConfig, "gatewayStorageClass", (String)null);if (gatewayStorageClass != null) {try {this.gatewayStorage = (GatewayResolver)Class.forName(gatewayStorageClass).newInstance();} catch (Exception var4) {this.log.error(var4, var4);throw new ServletException(var4);}}}}private List<String> parseStringList(String whiteListStr) {String[] whiteListArray = whiteListStr.split(",");if (whiteListArray != null && whiteListArray.length > 0) {List<String> whiteList = new ArrayList(whiteListArray.length);String[] arr$ = whiteListArray;int len$ = whiteListArray.length;for(int i$ = 0; i$ < len$; ++i$) {String s = arr$[i$];whiteList.add(s);}return whiteList;} else {return null;}}/** @Description:白名單路徑匹配* @Author: wangwei* @Date:2020/5/14 17:11*/private boolean isSkipCheck(String uri, String contextPath) {PathMatcher pathMatcherToUse = new AntPathMatcher();if (!ObjectUtils.isEmpty(this.whiteList)) {for(int i = 0; i< whiteList.size(); i++) {String pattern = whiteList.get(i);if (pathMatcherToUse.match(pattern, uri)) {return true;}}}return false;}@Overridepublic void init() {super.init();CommonUtils.assertNotNull(this.casServerLoginUrl, "casServerLoginUrl cannot be null.");}@Overridepublic final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest)servletRequest;HttpServletResponse response = (HttpServletResponse)servletResponse;HttpSession session = request.getSession(false);Assertion assertion = session != null ? (Assertion)session.getAttribute("_const_cas_assertion_") : null;if (assertion != null) {filterChain.doFilter(request, response);} else {String contextPath = request.getContextPath();String uri = request.getRequestURI().substring(contextPath.length(),request.getRequestURI().length());//獲取參數String headerFlag = request.getHeader("flagCas");String urlFlag = request.getParameter("flagCas");//判斷是否為白名單if (this.isSkipCheck(uri, contextPath)) {filterChain.doFilter(request, response);//根據參數判斷是否需要cas認證} else if("no".equals(headerFlag)||"no".equals(urlFlag)){filterChain.doFilter(request, response);}else {String serviceUrl = this.constructServiceUrl(request, response);String ticket = CommonUtils.safeGetParameter(request, this.getArtifactParameterName());boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);if (!CommonUtils.isNotBlank(ticket) && !wasGatewayed) {this.log.debug("no ticket and no assertion found");String modifiedServiceUrl;if (this.gateway) {this.log.debug("setting gateway attribute in session");modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);} else {modifiedServiceUrl = serviceUrl;}if (this.log.isDebugEnabled()) {this.log.debug("Constructed service url: " + modifiedServiceUrl);}String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, this.getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);if (this.log.isDebugEnabled()) {this.log.debug("redirecting to \"" + urlToRedirectTo + "\"");}response.sendRedirect(urlToRedirectTo);} else {filterChain.doFilter(request, response);}}}}public final void setRenew(boolean renew) {this.renew = renew;}public final void setGateway(boolean gateway) {this.gateway = gateway;}public final void setCasServerLoginUrl(String casServerLoginUrl) {this.casServerLoginUrl = casServerLoginUrl;}public final void setGatewayStorage(GatewayResolver gatewayStorage) {this.gatewayStorage = gatewayStorage;}public void setWhiteList(List<String> whiteList) {this.whiteList = whiteList;} }

二、結合實現,以及流程圖,分析客戶端源碼,請參考CasFilter文件

1、WhiteListJwtAndAuthenticationFilter過濾器(這是復寫了jar包中AuthenticationFilter過濾器,主要的改造的是添加了白名單,添加了跳過cas單點認證方式)

@Overridepublic final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest)servletRequest;HttpServletResponse response = (HttpServletResponse)servletResponse;HttpSession session = request.getSession(false);//判斷有沒有sessionAssertion assertion = session != null ? (Assertion)session.getAttribute("_const_cas_assertion_") : null;//session有數據說明本地已經登錄了,直接跳轉路徑if (assertion != null) {filterChain.doFilter(request, response);} else {/*否則用戶沒有登錄1、判斷是不是白名單路徑,如果是白名單路徑放行2、判斷是否關閉單點登錄驗證,這樣用戶就可以使用自己的登錄認證方式,這樣就既可以使用單點登錄,也可以使用本地登錄3、如果上面兩個條件都不滿足3.1判斷用戶是戶是否有token值,如果有放行(有token值說明用戶已經經過cas服務認證登錄了,并且返回了token值)3.2如果沒有token值重定向cas認證登錄*/String contextPath = request.getContextPath();String uri = request.getRequestURI().substring(contextPath.length(),request.getRequestURI().length());//獲取參數String headerFlag = request.getHeader("flagCas");String urlFlag = request.getParameter("flagCas");//判斷是否為白名單if (this.isSkipCheck(uri, contextPath)) {filterChain.doFilter(request, response);//根據參數判斷是否需要cas認證} else if("no".equals(headerFlag)||"no".equals(urlFlag)){filterChain.doFilter(request, response);}else {String serviceUrl = this.constructServiceUrl(request, response);String ticket = CommonUtils.safeGetParameter(request, this.getArtifactParameterName());boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);if (!CommonUtils.isNotBlank(ticket) && !wasGatewayed) {this.log.debug("no ticket and no assertion found");String modifiedServiceUrl;if (this.gateway) {this.log.debug("setting gateway attribute in session");modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);} else {modifiedServiceUrl = serviceUrl;}if (this.log.isDebugEnabled()) {this.log.debug("Constructed service url: " + modifiedServiceUrl);}String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, this.getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);if (this.log.isDebugEnabled()) {this.log.debug("redirecting to \"" + urlToRedirectTo + "\"");}response.sendRedirect(urlToRedirectTo);} else {filterChain.doFilter(request, response);}}}}

2、Cas10TicketValidationFilter過濾繼承的AbstractTicketValidationFilter過濾器(登錄成功了返回token,驗證token是否有效)

public final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {if (this.preFilter(servletRequest, servletResponse, filterChain)) {HttpServletRequest request = (HttpServletRequest)servletRequest;HttpServletResponse response = (HttpServletResponse)servletResponse;String ticket = CommonUtils.safeGetParameter(request, this.getArtifactParameterName());/*重點:***********************************************************這個攔截器只攔截帶有token值的路徑,這樣就實現了只在用戶登錄成功后返回token值驗證token值有效后,不會每一個請求都驗證token的有效性,這樣安全性得到了保證,也不會頻繁訪問cas服務端驗證有效性重點:************************************************************/if (CommonUtils.isNotBlank(ticket)) {if (this.log.isDebugEnabled()) {this.log.debug("Attempting to validate ticket: " + ticket);}try {Assertion assertion = this.ticketValidator.validate(ticket, this.constructServiceUrl(request, response));if (this.log.isDebugEnabled()) {this.log.debug("Successfully authenticated user: " + assertion.getPrincipal().getName());}request.setAttribute("_const_cas_assertion_", assertion);if (this.useSession) {request.getSession().setAttribute("_const_cas_assertion_", assertion);}this.onSuccessfulValidation(request, response, assertion);} catch (TicketValidationException var8) {response.setStatus(403);this.log.warn(var8, var8);this.onFailedValidation(request, response);if (this.exceptionOnValidationFailure) {throw new ServletException(var8);}}if (this.redirectAfterValidation) {this.log.debug("Redirecting after successful ticket validation.");response.sendRedirect(response.encodeRedirectURL(this.constructServiceUrl(request, response)));return;}}filterChain.doFilter(request, response);}}

3、SingleSignOutFilter,單點登錄注銷過濾器

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest)servletRequest;String artifact;if ("POST".equals(request.getMethod())) {artifact = CommonUtils.safeGetParameter(request, "logoutRequest");if (CommonUtils.isNotBlank(artifact)) {if (log.isTraceEnabled()) {log.trace("Logout request=[" + artifact + "]");}String sessionIdentifier = XmlUtils.getTextForElement(artifact, "SessionIndex");if (CommonUtils.isNotBlank(sessionIdentifier)) {HttpSession session = SESSION_MAPPING_STORAGE.removeSessionByMappingId(sessionIdentifier);if (session != null) {String sessionID = session.getId();if (log.isDebugEnabled()) {log.debug("Invalidating session [" + sessionID + "] for ST [" + sessionIdentifier + "]");}try {session.invalidate();} catch (IllegalStateException var10) {log.debug(var10, var10);}}return;}}} else {artifact = CommonUtils.safeGetParameter(request, this.artifactParameterName);if (CommonUtils.isNotBlank(artifact)) {HttpSession session = request.getSession(true);if (log.isDebugEnabled()) {log.debug("Storing session identifier for " + session.getId());}try {SESSION_MAPPING_STORAGE.removeBySessionById(session.getId());} catch (Exception var11) {}SESSION_MAPPING_STORAGE.addSessionById(artifact, session);} else {log.debug("No Artifact Provided; no action taking place.");}}filterChain.doFilter(servletRequest, servletResponse);}

總結

以上是生活随笔為你收集整理的单点的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。