一。设置移动客户端验证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;
}

最新文章

  1. APP产品交互设计资源汇总(不断更新中...)
  2. SQL语句总结
  3. Office 多版本共存
  4. 将List&lt;T&gt;转化成 DataTable--调整可空类型的转化错误
  5. Android布局管理器(表格布局)
  6. 蓝牙(BLE)应用框架接口设计和应用开发——以TI CC2541为例
  7. Android自定义View 构造方法 遇到的一些问题
  8. 老李分享:android手机测试之适配(1)
  9. 不使用synchronized和lock 锁实现线程安全单例
  10. [SQL]LeetCode185. 部门工资前三高的员工 | Department Top Three Salaries
  11. maven wrapper使用本地maven
  12. No Directionality widget found.错误记录。
  13. Android开发工程师文集-1 小时学会SQLite
  14. TMainMenu - 隐藏与显示菜单
  15. Restful framework【第八篇】频率组件
  16. 【linux kernel】 中断处理-中断上半部【转】
  17. 【mybatis】多次查询缓存的问题
  18. nginx 80 端口默认被占用
  19. iOS程序启动原理---iOS-Apple苹果官方文档翻译
  20. a:hover伪类在ios移动端浏览器内无效的解决方法

热门文章

  1. sqoop使用经验总结及问题汇总
  2. 如何干净卸载mysql
  3. UVA 11488 Hyper Prefix Sets (字典树)
  4. JustOj 1036: 习题6.11 迭代法求平方根
  5. [转载]Oracle左连接、右连接、全外连接以及(+)号用法
  6. kali linux 压缩文件解压缩命令(包含7z)
  7. 怎样从外网访问内网Node.js?
  8. NUL和NULL
  9. django自定义错误响应
  10. Linux查看机器和硬盘的SN