CAS 单点登录 移动端获取TGT、ST 已经移动端登录页面不进行跳转的设置
一。设置移动客户端验证ST通过后,页面不进行302重定向跳转
修改web.xml
<!--***************************************************************** -->
<!-- 校验ticket的过滤器 -->
<filter>
<filter-name>ticketValidationFilter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<!-- SSO统一登录URL-->
<param-value>http://passport.hivescm.com/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<!--本客户端URL-->
<param-value>http://192.168.106.49:8080/order</param-value>
</init-param>
<init-param>
<param-name>useSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>redirectAfterValidation</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ticketValidationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
二。处理移动端通过ST访问另一个系统比较service通过
1.移动端获取TGT的类,查看源码TicketsResource ,进行修改返回json数据
package org.jasig.cas.support.rest; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.code.kaptcha.Constants;
import com.hivecas.model.ConstantUtils;
import com.hivecas.model.ResponseBean;
import com.hivecas.model.UsernamePasswordStrongCredential; import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.CasProtocolConstants;
import org.jasig.cas.CentralAuthenticationService;
import org.jasig.cas.authentication.AuthenticationContext;
import org.jasig.cas.authentication.AuthenticationContextBuilder;
import org.jasig.cas.authentication.AuthenticationSystemSupport;
import org.jasig.cas.authentication.AuthenticationException;
import org.jasig.cas.authentication.AuthenticationTransaction;
import org.jasig.cas.authentication.Credential;
import org.jasig.cas.authentication.DefaultAuthenticationContextBuilder;
import org.jasig.cas.authentication.DefaultAuthenticationSystemSupport;
import org.jasig.cas.authentication.principal.Service;
import org.jasig.cas.authentication.principal.ServiceFactory;
import org.jasig.cas.ticket.InvalidTicketException;
import org.jasig.cas.ticket.ServiceTicket;
import org.jasig.cas.ticket.TicketGrantingTicket;
import org.jasig.cas.ticket.registry.DefaultTicketRegistrySupport;
import org.jasig.cas.ticket.registry.TicketRegistrySupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.net.URI;
import java.util.Formatter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map; /**
* {@link RestController} implementation of CAS' REST API.
*
* This class implements main CAS RESTful resource for vending/deleting TGTs and vending STs:
*
* <ul>
* <li>{@code POST /v1/tickets}</li>
* <li>{@code POST /v1/tickets/{TGT-id}}</li>
* <li>{@code DELETE /v1/tickets/{TGT-id}}</li>
* </ul>
*
* @author Dmitriy Kopylenko
* @since 4.1.0
*/
@RestController("ticketResourceRestController")
public class TicketsResource { private static final Logger LOGGER = LoggerFactory.getLogger(TicketsResource.class); @Autowired
@Qualifier("centralAuthenticationService")
private CentralAuthenticationService centralAuthenticationService; @NotNull
@Autowired(required=false)
@Qualifier("defaultAuthenticationSystemSupport")
private AuthenticationSystemSupport authenticationSystemSupport = new DefaultAuthenticationSystemSupport(); @Autowired(required = false)
private final CredentialFactory credentialFactory = new DefaultCredentialFactory(); @Autowired
@Qualifier("webApplicationServiceFactory")
private ServiceFactory webApplicationServiceFactory; @Autowired
@Qualifier("defaultTicketRegistrySupport")
private TicketRegistrySupport ticketRegistrySupport = new DefaultTicketRegistrySupport(); private final ObjectMapper jacksonObjectMapper = new ObjectMapper(); /**
* Create new ticket granting ticket.
*
* @param requestBody username and password application/x-www-form-urlencoded values
* @param request raw HttpServletRequest used to call this method
* @return ResponseEntity representing RESTful response
* @throws JsonProcessingException in case of JSON parsing failure
*/
@RequestMapping(value = "/tickets", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ResponseBody
public final ResponseBean createTicketGrantingTicket(@RequestBody final MultiValueMap<String, String> requestBody,
final HttpServletRequest request) throws JsonProcessingException {
ResponseBean responseBean=new ResponseBean();
try{ final String loginType = requestBody.getFirst("loginType");
final Credential credential = this.credentialFactory.fromRequestBody(requestBody);
final AuthenticationContextBuilder builder = new DefaultAuthenticationContextBuilder(
this.authenticationSystemSupport.getPrincipalElectionStrategy());
final AuthenticationTransaction transaction =
AuthenticationTransaction.wrap(credential);
this.authenticationSystemSupport.getAuthenticationTransactionManager().handle(transaction, builder);
final AuthenticationContext authenticationContext = builder.build();
final TicketGrantingTicket tgtId = this.centralAuthenticationService.createMobileTicketGrantingTicket(authenticationContext,loginType);
final URI ticketReference = new URI(request.getRequestURL().toString() + '/' + tgtId.getId());
final Map<String, String> dataMap = new HashMap<>();
dataMap.put("action", ticketReference.toString());
responseBean.setData(dataMap);
responseBean.setStatus(ConstantUtils.response_Status.SUCCESS);
return responseBean;
}
catch(final AuthenticationException e) {
responseBean.setMsg("无权限");
responseBean.setStatus(ConstantUtils.response_Status.NO_AUTH);
return responseBean;
} catch (final BadRequestException e) {
responseBean.setStatus(ConstantUtils.response_Status.FAIL);
LOGGER.error(e.getMessage(), e);
return responseBean;
} catch (final Throwable e) {
responseBean.setStatus(ConstantUtils.response_Status.FAIL);
LOGGER.error(e.getMessage(), e);
return responseBean;
}
} /**
* Create new service ticket.
*
* @param requestBody service application/x-www-form-urlencoded value
* @param tgtId ticket granting ticket id URI path param
* @return {@link ResponseEntity} representing RESTful response
*/
@RequestMapping(value = "/tickets/{tgtId:.+}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ResponseBody
public final ResponseBean createServiceTicket(@RequestBody final MultiValueMap<String, String> requestBody,
@PathVariable("tgtId") final String tgtId) {
ResponseBean responseBean=new ResponseBean();
try {
final String serviceId = requestBody.getFirst(CasProtocolConstants.PARAMETER_SERVICE);
final AuthenticationContextBuilder builder = new DefaultAuthenticationContextBuilder(
this.authenticationSystemSupport.getPrincipalElectionStrategy()); final Service service = this.webApplicationServiceFactory.createService(serviceId);
final AuthenticationContext authenticationContext =
builder.collect(this.ticketRegistrySupport.getAuthenticationFrom(tgtId)).build(service); final ServiceTicket serviceTicketId = this.centralAuthenticationService.grantServiceTicket(tgtId,
service, authenticationContext);
responseBean.setStatus(ConstantUtils.response_Status.SUCCESS);
final Map<String, String> dataMap = new HashMap<>();
dataMap.put("serviceTicketId", serviceTicketId.getId());
responseBean.setData(dataMap);
return responseBean; } catch (final InvalidTicketException e) {
responseBean.setStatus(ConstantUtils.response_Status.NO_AUTH);
responseBean.setMsg("TGT不存在");
return responseBean;
} catch (final Exception e) {
LOGGER.error(e.getMessage(), e);
responseBean.setStatus(ConstantUtils.response_Status.FAIL);
return responseBean;
}
} /**
* Destroy ticket granting ticket.
*
* @param tgtId ticket granting ticket id URI path param
* @return {@link ResponseEntity} representing RESTful response. Signals
* {@link HttpStatus#OK} when successful.
*/
@RequestMapping(value = "/tickets/{tgtId:.+}", method = RequestMethod.DELETE)
@ResponseBody
public final ResponseBean deleteTicketGrantingTicket(@PathVariable("tgtId") final String tgtId) {
this.centralAuthenticationService.destroyTicketGrantingTicket(tgtId);
ResponseBean responseBean=new ResponseBean();
responseBean.setStatus(ConstantUtils.response_Status.SUCCESS);
responseBean.setMsg("删除成功");
return responseBean;
} public void setAuthenticationSystemSupport(final AuthenticationSystemSupport authenticationSystemSupport) {
this.authenticationSystemSupport = authenticationSystemSupport;
} public void setWebApplicationServiceFactory(final ServiceFactory webApplicationServiceFactory) {
this.webApplicationServiceFactory = webApplicationServiceFactory;
} public void setTicketRegistrySupport(final TicketRegistrySupport ticketRegistrySupport) {
this.ticketRegistrySupport = ticketRegistrySupport;
} public void setCentralAuthenticationService(final CentralAuthenticationService centralAuthenticationService) {
this.centralAuthenticationService = centralAuthenticationService;
} public CentralAuthenticationService getCentralAuthenticationService() {
return centralAuthenticationService;
} public AuthenticationSystemSupport getAuthenticationSystemSupport() {
return authenticationSystemSupport;
} public CredentialFactory getCredentialFactory() {
return credentialFactory;
} public ServiceFactory getWebApplicationServiceFactory() {
return webApplicationServiceFactory;
} public TicketRegistrySupport getTicketRegistrySupport() {
return ticketRegistrySupport;
} /**
* Default implementation of CredentialFactory.
*/
private static class DefaultCredentialFactory implements CredentialFactory { @Override
public Credential fromRequestBody(@NotNull final MultiValueMap<String, String> requestBody) {
final String username = requestBody.getFirst("username");
final String password = requestBody.getFirst("password");
final String loginType = requestBody.getFirst("loginType");
if(username == null || password == null||loginType==null) {
throw new BadRequestException("Invalid payload. 'username' and 'password' form fields are required.");
}
if(!StringUtils.equals(loginType, ConstantUtils.loginType.MOBILE)){
throw new BadRequestException("Invalid payload. 'loginType' is wrong.");
}
return new UsernamePasswordStrongCredential(username, password,loginType);
}
} /**
* Exception to indicate bad payload.
*/
private static class BadRequestException extends IllegalArgumentException {
private static final long serialVersionUID = 6852720596988243487L; /**
* Ctor.
* @param msg error message
*/
BadRequestException(final String msg) {
super(msg);
}
}
}
2.返回responsebean
package com.hivecas.model; import java.util.Map; public class ResponseBean {
//返回状态 1 成功 2 失败
public String status;
//返回数据
public Map data;
//返回信息
public String msg; public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Map getData() {
return data;
}
public void setData(Map data) {
this.data = data;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
3.在源码CentralAuthenticationServiceImpl添加createMobileTicketGrantingTicket方法,将移动登录的类型loginType 设置到TGT中
@Audit(
action="TICKET_GRANTING_TICKET",
actionResolverName="CREATE_TICKET_GRANTING_TICKET_RESOLVER",
resourceResolverName="CREATE_TICKET_GRANTING_TICKET_RESOURCE_RESOLVER")
@Timed(name = "CREATE_TICKET_GRANTING_TICKET_TIMER")
@Metered(name = "CREATE_TICKET_GRANTING_TICKET_METER")
@Counted(name="CREATE_TICKET_GRANTING_TICKET_COUNTER", monotonic=true)
public TicketGrantingTicket createMobileTicketGrantingTicket(final AuthenticationContext context,final String loginType)
throws AuthenticationException, AbstractTicketException {
final Authentication authentication = context.getAuthentication();
final TicketGrantingTicketFactory factory = this.ticketFactory.get(TicketGrantingTicket.class); final TicketGrantingTicket ticketGrantingTicket = factory.create(authentication,loginType); this.ticketRegistry.addTicket(ticketGrantingTicket); doPublishEvent(new CasTicketGrantingTicketCreatedEvent(this, ticketGrantingTicket)); return ticketGrantingTicket;
}
4.源码TicketGrantingTicket添加获取getLoginType方法
public interface TicketGrantingTicket extends Ticket { /** The prefix to use when generating an id for a Ticket Granting Ticket. */
String PREFIX = "TGT"; String getLoginType();
5.这就可以在客户端请求ST票据验证时,不进行service的url比较验证,直接通过。位置在源码CentralAuthenticationServiceImpl类中
@Audit(
action="SERVICE_TICKET_VALIDATE",
actionResolverName="VALIDATE_SERVICE_TICKET_RESOLVER",
resourceResolverName="VALIDATE_SERVICE_TICKET_RESOURCE_RESOLVER")
@Timed(name="VALIDATE_SERVICE_TICKET_TIMER")
@Metered(name="VALIDATE_SERVICE_TICKET_METER")
@Counted(name="VALIDATE_SERVICE_TICKET_COUNTER", monotonic=true)
@Override
public Assertion validateServiceTicket(final String serviceTicketId, final Service service) throws AbstractTicketException {
final RegisteredService registeredService = this.servicesManager.findServiceBy(service);
verifyRegisteredServiceProperties(registeredService, service); final ServiceTicket serviceTicket = this.ticketRegistry.getTicket(serviceTicketId, ServiceTicket.class);
if (serviceTicket == null) {
logger.info("Service ticket [{}] does not exist.", serviceTicketId);
throw new InvalidTicketException(serviceTicketId);
}
final TicketGrantingTicket root ;
try {
synchronized (serviceTicket) {
if (serviceTicket.isExpired()) {
logger.info("ServiceTicket [{}] has expired.", serviceTicketId);
throw new InvalidTicketException(serviceTicketId);
} root = serviceTicket.getGrantingTicket().getRoot();
if(root!=null){
String loginType=root.getLoginType();
if(StringUtils.isNotBlank(loginType)||StringUtils.equalsIgnoreCase(loginType, ConstantUtils.loginType.PC)){
if (!serviceTicket.isValidFor(service)) {
logger.error("Service ticket [{}] with service [{}] does not match supplied service [{}]",
serviceTicketId, serviceTicket.getService().getId(), service);
throw new UnrecognizableServiceForServiceTicketValidationException(serviceTicket.getService());
}
}
}
} // final TicketGrantingTicket root = serviceTicket.getGrantingTicket().getRoot();
final Authentication authentication = getAuthenticationSatisfiedByPolicy(
root, new ServiceContext(serviceTicket.getService(), registeredService));
final Principal principal = authentication.getPrincipal(); final RegisteredServiceAttributeReleasePolicy attributePolicy = registeredService.getAttributeReleasePolicy();
logger.debug("Attribute policy [{}] is associated with service [{}]", attributePolicy, registeredService); @SuppressWarnings("unchecked")
final Map<String, Object> attributesToRelease = attributePolicy != null
? attributePolicy.getAttributes(principal) : Collections.EMPTY_MAP; final String principalId = registeredService.getUsernameAttributeProvider().resolveUsername(principal, service);
final Principal modifiedPrincipal = this.principalFactory.createPrincipal(principalId, attributesToRelease);
final AuthenticationBuilder builder = DefaultAuthenticationBuilder.newInstance(authentication);
builder.setPrincipal(modifiedPrincipal); final Assertion assertion = new ImmutableAssertion(
builder.build(),
serviceTicket.getGrantingTicket().getChainedAuthentications(),
serviceTicket.getService(),
serviceTicket.isFromNewLogin()); doPublishEvent(new CasServiceTicketValidatedEvent(this, serviceTicket, assertion)); return assertion; } finally {
if (serviceTicket.isExpired()) {
this.ticketRegistry.deleteTicket(serviceTicketId);
}
}
} @Audit(
action="TICKET_GRANTING_TICKET",
actionResolverName="CREATE_TICKET_GRANTING_TICKET_RESOLVER",
resourceResolverName="CREATE_TICKET_GRANTING_TICKET_RESOURCE_RESOLVER")
@Timed(name = "CREATE_TICKET_GRANTING_TICKET_TIMER")
@Metered(name = "CREATE_TICKET_GRANTING_TICKET_METER")
@Counted(name="CREATE_TICKET_GRANTING_TICKET_COUNTER", monotonic=true)
@Override
public TicketGrantingTicket createTicketGrantingTicket(final AuthenticationContext context)
throws AuthenticationException, AbstractTicketException { final Authentication authentication = context.getAuthentication();
final TicketGrantingTicketFactory factory = this.ticketFactory.get(TicketGrantingTicket.class);
final TicketGrantingTicket ticketGrantingTicket = factory.create(authentication); this.ticketRegistry.addTicket(ticketGrantingTicket); doPublishEvent(new CasTicketGrantingTicketCreatedEvent(this, ticketGrantingTicket)); return ticketGrantingTicket;
}
CAS 单点登录 移动端获取TGT、ST 已经移动端登录页面不进行跳转的设置的更多相关文章
- CAS学习笔记二:CAS单点登录流程
背景 由于公司项目甲方众多,各甲方为了统一登录用户体系实现单点登录(SSO)开始要求各乙方项目对接其搭建的CAS单点登录服务,有段时间对CAS的流程很迷,各厂商还有基于CAS进行二次开发的情况,所以对 ...
- jfinal集成cas单点认证实践
本示例jfinal集成cas单点认证,采用获取到登录用户session信息后,在本地站点备份一份session信息,主要做以下几个步骤: 1.站点引入响应jar包: 2.在web.xml中配置对应过滤 ...
- 如何不做登录请求而获取cookie到Jmeter里
如何不做登录请求而获取cookie到Jmeter里? 登录被测系统后,按F12,找到如下位置,将这个表格所有信息都复制到Jmeter的HTTP Cookie管理器元件,这样就可以不需要登录,能继续发送 ...
- cas 单点登录服务端客户端配置
首先,下载 cas-server-3.5.2-release http://pan.baidu.com/s/1GJ8Gs cas-client-3.2.1-release http://pan.bai ...
- CAS单点登录(SSO)服务端的部署和配置---连接MySQL进行身份认证
一.修改系统host,加入 127.0.0.1 server.test.com127.0.0.1 client1.test.com127.0.0.1 client2.test.com 二.安装grad ...
- cas单点登录如何获取更多信息
现在有个新的系统(SpringMVC+Spring+Mybatis),我为它添加了一个单点登录功能.只是在本地客户端的web.xml文件里,添加了以下配置 <!-- 用于单点退出,该过滤器用于实 ...
- CAS单点登录学习(一):服务端搭建
下载先在网上下载cas-server-3.5.2,将里面的cas-server-webapp-3.5.2.war放到tomcat的webapps目录下. https设置cas单点登默认使用的是http ...
- cas系列(一)--cas单点登录基本原理
(这段时间打算做单点登录,因此研究了一些cas资料并作为一个系列记录下来,一来可能会帮助一些人,二来对我自己所学知识也是一个巩固.) 一.为什么要实现单点登录 随着信息化不断发展,企业的信息化过程是一 ...
- CAS单点登录的原理
1.首先了解几个概念 1).TGC:Ticket-granting cookie,存放用户身份认证凭证的cookie,在浏览器和CAS Server间通讯时使用.2).TGT:ticket grant ...
随机推荐
- Linux 中常用的命令
Linux中的常用命令: 终端快捷键: Ctrl + a/Home 切换到命令行开始 Ctrl + e/End 切换到命令行末尾 Ctrl + l 清除屏幕内容,效果等同于clear Ctrl + u ...
- [DeploymentService:290066]Error occurred while downloading files from admin server for deployment request "0". Underlying error is: "null"
weblogic 莫名无法启动: <Apr , :: PM CST> <Error> <Deployer> <BEA-> <Failed to i ...
- Java锁详解
http://blog.csdn.net/pzasdq/article/details/53128331 http://blog.csdn.net/truelove12358/article/deta ...
- IO多路复用 IO异步
一.概念说明 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的环境给出的答案是不同的.所以先限定一下本文的环境.本文讨论的背景是Linux环境下的network I ...
- c# 制作弹窗
1.右键选择添加,添加windows窗体 2.添加第几个窗体这就是Form几 3.具现化 窗口,然后调用 具现化窗口名+ShowDialog 就可以弹出新的窗口 这个功能需要使用,自己 ...
- Linux基础命令---添加组groupadd、删除组groupdel
groupadd 指定群组名称来建立新的群组账号,需要时可以从系统中取得新的群组值. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. ...
- JustOj 1910: 人见人爱A+B
[提交][状态][讨论版] 题目描述 北大的acm上面已经有10来道A+B的题目了,相信这些题目曾经是大家的最爱,希望今天的这个A+B能给大家带来好运,也希望这个题目能唤起大家对ACM曾经的热爱. ...
- Hadoop学习笔记之六:HDFS功能逻辑(2)
Lease(租约) HDFS(及大多数分布式文件系统)不支持文件并发写,Lease是HDFS用于保证唯一写的手段. Lease可以看做是一把带时间限制的写锁,仅持有写锁的客户端可以写文件. 租约的有效 ...
- 【linux应用】将一个大文件按行拆分成小文件
例如将一个BLM.txt文件分成前缀为 BLM_ 的1000个小文件,后缀为系数形式,且后缀为4位数字形式 先利用 wc -l BLM.txt #读出BLM.txt有多少行. 再利用 split 命令 ...
- Tomcat启动程序端口冲突、确认相应进程及杀死冲突进程的解决方案
一. 查看所有进程占用的端口 在开始-运行-cmd,输入:netstat –ano可以查看所有进程 二.查看占用指定端口的程序(1)命令窗口输出 命令:netstat –ano | findstr & ...