为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

让CAS支持客户端自定义登陆页面——服务器新篇

2018-01-24 22页 doc 59KB 37阅读

用户头像

is_842972

暂无简介

举报
让CAS支持客户端自定义登陆页面——服务器新篇让CAS支持客户端自定义登陆页面——服务器新篇 让CAS支持客户端自定义登陆页面——服务器新篇 最近公司研发产品,将基于CAS的SSO列为了研究方向之一,统一登录统一认证还是比较简单的,因为领导指示,还要适应分散登录统一认证,所以还是要努力去实现。 在网上搜了搜,有一篇“让CAS支持客户端自定义登陆页面”的文章,分服务器篇和客户端篇两个部分,思路符合的,也提供了挺详细的代码,但问题是该文章是基于spring web flow 1.X的,现在的CAS服务是3.4.10版本,其内部流程用的是spring web flow 2...
让CAS支持客户端自定义登陆页面——服务器新篇
让CAS支持客户端自定义登陆页面——服务器新篇 让CAS支持客户端自定义登陆页面——服务器新篇 最近公司研发产品,将基于CAS的SSO列为了研究方向之一,统一登录统一认证还是比较简单的,因为领导指示,还要适应分散登录统一认证,所以还是要努力去实现。 在网上搜了搜,有一篇“让CAS支持客户端自定义登陆页面”的文章,分服务器篇和客户端篇两个部分,思路符合的,也提供了挺详细的代码,但问题是该文章是基于spring web flow 1.X的,现在的CAS服务是3.4.10版本,其内部流程用的是spring web flow 2.X版本。 spring web flow 2.X和spring web flow 1.X不是向下兼容的,基本上流程代码是不能用了。我做了大量的修改,目前远程登录和远程退出都实现了,现在将符合spring web flow 2.X的做法记录下来,和需要的朋友们共享。 接下来我们讲解服务器端修改的详细过程: 1、修改/WEB-INF/web.xml,为cas增加一个/remoteLogin和//remoteLogout的映射,否则总是会转到login那个请求去了: cas /remoteLogin cas /remoteLogout 2、然后修改cas-servlet.xml文件,增加对/remoteLogin和/remoteLogout映射的处理,需要增加两个新流程: remoteLoginController remoteLogoutController 3、流程定义的xml文件:可以看到上面将请求指向了webflow配置文件 /WEB-INF/remoteLogin-webflow.xml和/WEB-INF/remoteLogout-webflow.xml,我们需要创 建此文件并配置其成为我们所需的流程。 以下是remoteLogin-webflow.xml全文: 以下是remoteLogout-webflow.xml全文: 4、流程首先由Action类进行处理,成功或失败都将转回 remoteCallbackView,这样就返回 了远程的登录页面。 4.1、登录处理Action类: package com.cas.web.flow; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.jasig.cas.authentication.principal.Service; import org.jasig.cas.web.support.ArgumentExtractor; import org.jasig.cas.web.support.CookieRetrievingCookieGenerator; import org.jasig.cas.web.support.WebUtils; import org.springframework.util.StringUtils; import org.springframework.webflow.action.AbstractAction; import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.RequestContext; /** * 远程登陆票据提供Action. * 根据InitialFlowSetupAction修改. * 由于InitialFlowSetupAction为final类,因此只能将代码复制过来再进行修改. */ public class RemoteLoginAction extends AbstractAction { /** CookieGenerator for the Warnings. */ @NotNull private CookieRetrievingCookieGenerator warnCookieGenerator; /** CookieGenerator for the TicketGrantingTickets. */ @NotNull private CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator; /** Extractors for finding the service. */ @NotNull @Size(min=1) private List argumentExtractors; /** Boolean to note whether we've set the values on the generators or not. */ private boolean pathPopulated = false; protected Event doExecute(final RequestContext context) throws Exception { final HttpServletRequest request = WebUtils.getHttpServletRequest(context); if (!this.pathPopulated) { final String contextPath = context.getExternalContext().getContextPath(); final String cookiePath = StringUtils.hasText(contextPath) ? contextPath : "/"; logger.info("Setting path for cookies to: " + cookiePath); this.warnCookieGenerator.setCookiePath(cookiePath); this.ticketGrantingTicketCookieGenerator.setCookiePath(cookiePath); this.pathPopulated = true; } context.getFlowScope().put("ticketGrantingTicketId", this.ticketGrantingTicketCookieGenerator.retrieveCookieValue(request)); context.getFlowScope().put("warnCookieValue", Boolean.valueOf(this.warnCookieGenerator.retrieveCookieValue(request))); final Service service = WebUtils.getService(this.argumentExtractors, context); if (service != null && logger.isDebugEnabled()) { logger.debug("Placing service in FlowScope: " + service.getId()); } context.getFlowScope().put("service", service); // 客户端必须传递loginUrl参数过来,否则无法确定登陆目标页面 if (StringUtils.hasText(request.getParameter("loginUrl"))) { context.getFlowScope().put("remoteLoginUrl", request.getParameter("loginUrl")); } else { request.setAttribute("remoteLoginMessage", "loginUrl parameter must be supported."); return error(); } // 若参数包含submit则进行提交,否则进行验证 if (StringUtils.hasText(request.getParameter("submit"))) { return result("submit"); } else { return result("checkTicketGrantingTicket"); } } public void setTicketGrantingTicketCookieGenerator( final CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator) { this.ticketGrantingTicketCookieGenerator = ticketGrantingTicketCookieGenerator; } public void setWarnCookieGenerator(final CookieRetrievingCookieGenerator warnCookieGenerator) { this.warnCookieGenerator = warnCookieGenerator; } public void setArgumentExtractors(final List argumentExtractors) { this.argumentExtractors = argumentExtractors; } } 4.2、退出处理Action类: package com.cas.web.flow; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.jasig.cas.CentralAuthenticationService; import org.jasig.cas.authentication.principal.Service; import org.jasig.cas.web.support.ArgumentExtractor; import org.jasig.cas.web.support.CookieRetrievingCookieGenerator; import org.jasig.cas.web.support.WebUtils; import org.springframework.util.StringUtils; import org.springframework.webflow.action.AbstractAction; import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.RequestContext; public class RemoteLogoutAction extends AbstractAction { @NotNull private CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator; @NotNull private CookieRetrievingCookieGenerator warnCookieGenerator; @NotNull private CentralAuthenticationService centralAuthenticationService; @NotNull @Size(min=1) private List argumentExtractors; private boolean pathPopulated = false; @Override protected Event doExecute(final RequestContext context) throws Exception { final HttpServletRequest request = WebUtils.getHttpServletRequest(context); final HttpServletResponse response = WebUtils.getHttpServletResponse(context); if (!this.pathPopulated) { final String contextPath = context.getExternalContext().getContextPath(); final String cookiePath = StringUtils.hasText(contextPath) ? contextPath : "/"; logger.info("Setting path for cookies to: " + cookiePath); this.warnCookieGenerator.setCookiePath(cookiePath); this.ticketGrantingTicketCookieGenerator.setCookiePath(cookiePath); this.pathPopulated = true; } context.getFlowScope().put("ticketGrantingTicketId", this.ticketGrantingTicketCookieGenerator.retrieveCookieValue(request)); context.getFlowScope().put("warnCookieValue", Boolean.valueOf(this.warnCookieGenerator.retrieveCookieValue(request))); final Service service = WebUtils.getService(this.argumentExtractors, context); if (service != null && logger.isDebugEnabled()) { logger.debug("Placing service in FlowScope: " + service.getId()); } context.getFlowScope().put("service", service); context.getFlowScope().put("remoteLoginUrl", request.getParameter("service")); final String ticketGrantingTicketId = this.ticketGrantingTicketCookieGenerator.retrieveCookieValue(request); if (ticketGrantingTicketId != null) { this.centralAuthenticationService.destroyTicketGrantingTicket(ticketGrantingTicketId); this.ticketGrantingTicketCookieGenerator.removeCookie(response); this.warnCookieGenerator.removeCookie(response); } return result("success"); } public void setTicketGrantingTicketCookieGenerator(final CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator) { this.ticketGrantingTicketCookieGenerator = ticketGrantingTicketCookieGenerator; } public void setWarnCookieGenerator(final CookieRetrievingCookieGenerator warnCookieGenerator) { this.warnCookieGenerator = warnCookieGenerator; } public void setArgumentExtractors(final List argumentExtractors) { this.argumentExtractors = argumentExtractors; } public void setCentralAuthenticationService(final CentralAuthenticationService centralAuthenticationService){ this.centralAuthenticationService = centralAuthenticationService; } } 4.3、cas的登录页面,username和password是传递给 这个变量的,判断用户登录信息也以这个变量传递给 org.jasig.cas.web.flow.AuthenticationViaFormAction的submit方法来进行,很遗憾, 这个变量没法中间赋值(反正我不会),所以我重构了一个方法: public final String submit(final RequestContext context, final MessageContext messageContext) throws Exception { // Validate login ticket final String authoritativeLoginTicket = WebUtils.getLoginTicketFromFlowScope(context); final String providedLoginTicket = WebUtils.getLoginTicketFromRequest(context); if (!authoritativeLoginTicket.equals(providedLoginTicket)) { this.logger.warn("Invalid login ticket " + providedLoginTicket); final String code = "INVALID_TICKET"; messageContext.addMessage(new MessageBuilder().error().code(code).arg(providedLoginTicket).defaultText(code).build()); return "error"; } final String ticketGrantingTicketId = WebUtils.getTicketGrantingTicketId(context); final Service service = WebUtils.getService(context); final HttpServletRequest request = WebUtils.getHttpServletRequest(context); org.jasig.cas.authentication.principal.UsernamePasswordCredentials credentials = new org.jasig.cas.authentication.principal.UsernamePasswordCredentials(); credentials.setPassword(request.getParameter("password")); credentials.setUsername(request.getParameter("username")); if (StringUtils.hasText(context.getRequestParameters().get("renew")) && ticketGrantingTicketId != null && service != null) { try { final String serviceTicketId = this.centralAuthenticationService.grantServiceTicket(ticketGrantingTicketId, service, credentials); WebUtils.putServiceTicketInRequestScope(context, serviceTicketId); putWarnCookieIfRequestParameterPresent(context); return "warn"; } catch (final TicketException e) { if (e.getCause() != null && AuthenticationException.class.isAssignableFrom(e.getCause().getClass())) { populateErrorsInstance(e, messageContext); return "error"; } this.centralAuthenticationService.destroyTicketGrantingTicket(ticketGrantingTicketId); if (logger.isDebugEnabled()) { logger.debug("Attempted to generate a ServiceTicket using renew=true with different credentials", e); } } } try { WebUtils.putTicketGrantingTicketInRequestScope(context, this.centralAuthenticationService.createTicketGrantingTicket(credentials)); putWarnCookieIfRequestParameterPresent(context); return "success"; } catch (final TicketException e) { populateErrorsInstance(e, messageContext); return "error"; } } 这个方法直接从request里获得username和password,然后验证。 5、配置remoteCallbackView显示节点,修改src/default_views.properties文件,增加 remoteCallbackView配置: ### 配置远程回调页面 remoteCallbackView.(class)=org.springframework.web.servlet.view.JstlView remoteCallbackView.url=/WEB-INF/view/jsp/default/ui/remoteCallbackView.jsp 6、创建/WEB-INF/view/jsp/default/ui/remoteCallbackView.jsp文件: <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri=";%> <%@ taglib prefix="spring" uri=";%> ${remoteLoginMessage} 到此,服务器端修改完成,下一篇介绍客户端如何构建
/
本文档为【让CAS支持客户端自定义登陆页面——服务器新篇】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索