问题
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <title>登录界面</title> <link href="../css/styles.css" rel="stylesheet" type="text/css" /> <link href="../css/demo.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="../js/requestAnimationFrame.js"></script> <script type="text/javascript" src="../js/jquery-2.1.1.min.js"></script> <script type="text/javascript" src="../js/Star.js"></script> <script type="text/javascript" src="../js/Particle.js"></script> <script type="text/javascript" src="../js/Smoke.js"></script> <script type="text/javascript" src="../js/jquery-ui.min.js"></script> <script src="../js/Treatment.js" type="text/javascript"></script> <script src="../js/jquery.mockjax.js" type="text/javascript"></script> </head> <body> <div style="position: absolute;z-index: 1;"> <canvas id="canvas_app" class="first"></canvas> </div> <div class='login' style="position: absolute;z-index: 10;"> <div class='login_title'> <span><center><h3>用户登录</h3></center></span> </div> <div class='login_fields'>
<!-- 使用form表单提交 https://mmoayyed.unicon.net:8433/cas/v1/tickets/login访问cas server提供的这个接口,借此来实现用户登录 -->
<form action="https://mmoayyed.unicon.net:8433/cas/v1/tickets/login" id="loginForm" method="POST"> <!--<form action="<%=request.getContextPath()%>/hello/restLogin" id="loginForm" method="POST">--> <!--<form action="http://app1.cas.com:9001/hello/restLogin" id="loginForm" method="POST">--> <div class='login_fields'> <div class='login_fields__user'> <div class='icon'> <img alt="" src='img/user_icon_copy.png'> </div> <input name="username" id="username" placeholder='用户名' maxlength="16" type='text' autocomplete="off"/> <div class='validation'> <img alt="" src='img/tick.png'> </div> </div> <div class='login_fields__password'> <div class='icon'> <img alt="" src='img/lock_icon_copy.png'> </div> <input name="password" id="password" placeholder='密码' maxlength="16" type='text' autocomplete="off"> <div class='validation'> <img alt="" src='img/tick.png'> </div> </div> <div class='login_fields__password'> <div class='icon'> <img alt="" src='img/lock_icon_copy.png'> </div> <input name="email" id="email" placeholder='邮箱' maxlength="16" type='text' autocomplete="off"> <div class='validation'> <img alt="" src='img/tick.png'> </div> </div> <div class='login_fields__password'> <div class='icon'> <img alt="" src='img/lock_icon_copy.png'> </div> <input name="telephone" id="telephone" placeholder='手机' maxlength="16" type='text' autocomplete="off"> <div class='validation'> <img alt="" src='img/tick.png'> </div> </div> <div class='login_fields__password'> <div class='icon'> <img alt="" src='img/key.png'> </div> <input name="capcha" id="capcha" placeholder='验证码' maxlength="4" type='text'> <div class='validation' style="opacity: 1; right: -5px;top: -3px;"> <canvas class="J_codeimg" id="myCanvas" onclick="Code();">对不起,您的浏览器不支持canvas,请下载最新版浏览器!</canvas> </div> </div> <div class='login_fields__password'> <input name="Service" type='hidden' value="http://app1.cas.com:9001"> </div> <div class='login_fields__submit'> <input type='submit' onClick="checkCode()" value='登录'> </div> </div> </form> </div> </div> </div> <script type="text/javascript"> var canGetCookie = 0;//是否支持存储Cookie 0 不支持 1 支持 //默认账号密码 var CodeVal = 0; Code(); function Code() { if(canGetCookie == 1){ createCode("AdminCode"); var AdminCode = getCookieValue("AdminCode"); showCheck(AdminCode); } else{ showCheck(createCode("")); } } function showCheck(a) { CodeVal = a; var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); ctx.clearRect(0, 0, 1000, 1000); ctx.font = "80px 'Hiragino Sans GB'"; ctx.fillStyle = "#E8DFE8"; ctx.fillText(a, 0, 100); } $(document).keypress(function (e) { // 回车键事件 if (e.which == 13) { $('input[type="button"]').click(); } }); $('input[name="password"]').focus(function () { $(this).attr('type', 'password'); }); $('input[type="text"]').focus(function () { $(this).prev().animate({ 'opacity': '1' }, 200); }); $('input[type="text"],input[type="password"]').blur(function () { $(this).prev().animate({ 'opacity': '.5' }, 200); }); function checkCode() { if($("#username").val().length==0||$("#password").val().length==0){ alert("用户名或密码不能为空"); } else if($("#code").val().length==0){ alert("验证码不能为空"); } else if($("#code").val().toUpperCase()!=CodeVal.toUpperCase()){ alert("验证码错误!"); } } </script> </body> </html> <script> $(window).resize(resizeCanvas); $(window).load(onloadFun); var model = { //数据配置 hue: 237, stars: [], starImg: null, count: 0, smoke: null, maxStars: 4000, } var canvas = $("#canvas_app"); var ctx = canvas.get(0).getContext("2d"); var starImg; function init() { createStar(); //星星 createSmoke(); //烟雾 animation(); } function animation() { ctx.globalCompositeOperation = 'source-over'; ctx.globalAlpha = 0.3; ctx.fillStyle = 'hsla(' + model.hue + ', 64%, 6%, 1)'; ctx.fillRect(0, 0, $(window).get(0).innerWidth, $(window).get(0).innerHeight) ctx.globalCompositeOperation = 'lighter'; for (var i = 1, l = model.stars.length; i < l; i++) { model.stars[i].draw(ctx, model.starImg); }; model.smoke.update(ctx); window.requestAnimationFrame(animation); } function createStar() { //圆点 var canvas2 = document.createElement('canvas'); model.starImg = canvas2; var ctx2 = canvas2.getContext("2d"); canvas2.width = 88; canvas2.height = 88; var half = canvas2.width / 2; var gradient2 = ctx2.createRadialGradient(half, half, 0, half, half, half); gradient2.addColorStop(0.01, '#fff'); gradient2.addColorStop(0.1, 'hsl(' + model.hue + ', 61%, 50%)'); gradient2.addColorStop(0.15, 'hsl(' + model.hue + ', 64%, 80%)'); gradient2.addColorStop(0.26, 'transparent'); ctx2.fillStyle = gradient2; ctx2.beginPath(); ctx2.arc(half, half, half, 0, Math.PI * 2); ctx2.fill(); for (var i = 0; i < model.maxStars; i++) { var star = new Star($(window).get(0).innerWidth, $(window).get(0).innerHeight, model.maxStars); model.stars[i] = star; } } function createSmoke() { model.smoke = new Smoke(); } function resizeCanvas() { canvas.attr("width", $(window).get(0).innerWidth); canvas.attr("height", $(window).get(0).innerHeight); ctx.fillRect(0, 0, canvas.width(), canvas.height()); //图片 $(".second").attr("width", $(window).get(0).innerWidth); $(".second").attr("height", $(window).get(0).innerHeight); } function onloadFun() { init(); resizeCanvas(); } </script>
编写https://mmoayyed.unicon.net:8433/cas/v1/tickets/login 接口,也就是重写TicketGrantingTicketResource这个实现类,重写的实现类名为:CutomTicketGrantingTicketResource
@PostMapping(value = "/v1/tickets/login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) public ResponseEntity<String> createTicketGrantingTicket(@RequestBody(required=false) final MultiValueMap<String, String> requestBody, final HttpServletRequest request, final HttpServletResponse response) { try { TicketGrantingTicket tgtId = createTicketGrantingTicketForRequest(requestBody, request); var cookies = request.getCookies(); if(cookies!=null){ System.out.println("您上次的访问时间是"); for(int i=0;i<cookies.length;i++){ Cookie cookie = cookies[i]; System.out.println("cookie的名字"+cookie.getName()); System.out.println("cookie的值"+cookie.getValue()); } }else { System.out.println("这是您第一次访问本站"); } return createResponseEntityForTicket(request, tgtId); } catch (final AuthenticationException e) { return RestResourceUtils.createResponseEntityForAuthnFailure(e, request, applicationContext); } catch (final BadRestRequestException e) { return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); } catch (final Exception e) { return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } }
https://mmoayyed.unicon.net:8433/cas/v1/tickets/login/{tgtId:.+} {tgtId:.+}这个是tgt的值
@PostMapping(value = "/v1/tickets/login/{tgtId:.+}", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) public ResponseEntity<String> createServiceTicket(final HttpServletRequest httpServletRequest, @RequestBody(required = false) final MultiValueMap<String, String> requestBody, @PathVariable("tgtId") final String tgtId) { try { Authentication authn = this.ticketRegistrySupport.getAuthenticationFrom(tgtId); AuthenticationCredentialsThreadLocalBinder.bindCurrent(authn); if (authn == null) { throw new InvalidTicketException(tgtId); } Service service = this.argumentExtractor.extractService(httpServletRequest);//AbstractWebApplicationService(id=http://localhost:8081/cas-sample-java-webapp, originalUrl=http://localhost:8081/cas-sample-java-webapp, artifactId=null, principal=null, source=service, loggedOutAlready=false, format=XML, attributes={}) if (service == null) { throw new IllegalArgumentException("Target service/application is unspecified or unrecognized in the request"); } //getParameter 返回的是String, 用于读取提交的表单中的值; if (BooleanUtils.toBoolean(httpServletRequest.getParameter(CasProtocolConstants.PARAMETER_RENEW))) { List<Credential> credential = this.credentialFactory.fromRequest(httpServletRequest, requestBody); if (credential == null || credential.isEmpty()) { throw new BadRestRequestException("No credentials are provided or extracted to authenticate the REST request"); } AuthenticationResult authenticationResult = authenticationSystemSupport.handleAndFinalizeSingleAuthenticationTransaction(service, credential); return this.serviceTicketResourceEntityResponseFactory.build(tgtId, service, authenticationResult); } else { DefaultAuthenticationResultBuilder builder = new DefaultAuthenticationResultBuilder(); AuthenticationResult authenticationResult = builder .collect(authn) .build(this.authenticationSystemSupport.getPrincipalElectionStrategy(), service); System.out.println("service"+service+"*****tgtId*******"+tgtId+"*****authenticationResult*******"+authenticationResult); return this.serviceTicketResourceEntityResponseFactory.build(tgtId, service, authenticationResult); } } catch (final InvalidTicketException e) { return new ResponseEntity<>(tgtId + " could not be found or is considered invalid", HttpStatus.NOT_FOUND); } catch (final AuthenticationException e) { return RestResourceUtils.createResponseEntityForAuthnFailure(e, httpServletRequest, applicationContext); } catch (final BadRestRequestException e) { return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); } catch (final Exception e) { return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } finally { AuthenticationCredentialsThreadLocalBinder.clear(); } }
编写完成后,要对该实现类进行配置并注入,配置类参考:CasRestConfiguration 将 TicketGrantingTicketResource替换为我们自己的实现类CutomTicketGrantingTicketResource
那么对st验证的操作,也是同样的操作
最后关于注入配置spring.factories文件,使我们自己的实现类生效,(这里要将我们的实现类和配置类一起诸如该文件才可以生效,参考大神说法是:与之前自定义实现使用自己的数据库来存储用户名密码的诸如方式不同,自定义实现使用自己的数据库验证只需要实现配置类的注入,因为是给内部使用的;而现在我们写的接口都是给外部使用的,所以注入的时候要把全部都写进去,注入形式不再描述):
此时进行验证操作:这里注意的是cas 默认的认证类型是:UsernamePasswordCredential,如果cas server的认证类型为自定义的,此时会报错,验证通不过
点击登陆之后的界面为:
*********CustomerHandlerAuthentication执行*********
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
2019-01-28 16:26:07,214 INFO [org.apereo.cas.authentication.PolicyBasedAuthenticationManager] - <Authenticated principal [111] with attributes [{}] via credentials [[UsernamePasswordCredential(username=111, source=null)]].>
2019-01-28 16:26:07,223 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: 111
WHAT: Supplied credentials: [UsernamePasswordCredential(username=111, source=null)]
ACTION: AUTHENTICATION_SUCCESS
APPLICATION: CAS
WHEN: Mon Jan 28 16:26:07 CST 2019
CLIENT IP ADDRESS: 127.0.0.1
SERVER IP ADDRESS: 127.0.0.1
=============================================================
>
2019-01-28 16:26:07,347 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: 111
WHAT: TGT-2-*****lGyY-3GlcUADESKTOP-NEPM8G8
ACTION: TICKET_GRANTING_TICKET_CREATED
APPLICATION: CAS
WHEN: Mon Jan 28 16:26:07 CST 2019
CLIENT IP ADDRESS: 127.0.0.1
SERVER IP ADDRESS: 127.0.0.1
=============================================================
>
您上次的访问时间是Mon Jan 28 16:26:07 CST 2019
cookie的名字JSESSIONID
cookie的值F432529EE1811DC43BEAF8F551D7A902
2019-01-28 16:26:07,390 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: 111
WHAT: [status=201-CREATED,location=https://mmoayyed.unicon.net:8433/cas/v1/tickets/login/TGT-2-*****lGyY-3GlcUADESKTOP-NEPM8G8]
ACTION: REST_API_TICKET_GRANTING_TICKET_CREATED
APPLICATION: CAS
WHEN: Mon Jan 28 16:26:07 CST 2019
CLIENT IP ADDRESS: 127.0.0.1
SERVER IP ADDRESS: 127.0.0.1
=============================================================
>
serviceAbstractWebApplicationService(id=http://app1.cas.com:9001/, originalUrl=http://app1.cas.com:9001/, artifactId=null, principal=null, source=service, loggedOutAlready=false, format=XML, attributes={})*****tgtId*******TGT-2-v8yUrMSxaHAr-YWVpuh48sDRniz-DPKpAtzFeXYHdRJS7cZsuSje6gmHlGyY-3GlcUADESKTOP-NEPM8G8*****authenticationResult*******DefaultAuthenticationResult(authentication=org.apereo.cas.authentication.DefaultAuthentication@cc89e1b4, service=AbstractWebApplicationService(id=http://app1.cas.com:9001/, originalUrl=http://app1.cas.com:9001/, artifactId=null, principal=null, source=service, loggedOutAlready=false, format=XML, attributes={}), credentialProvided=false)
2019-01-28 16:26:38,588 INFO [org.apereo.cas.ticket.registry.DefaultTicketRegistryCleaner] - <[0] expired tickets removed.>
2019-01-28 16:28:02,495 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: 111
WHAT: [result=Service Access Granted,service=http://app1.cas.com:9001/,requiredAttributes={}]
ACTION: SERVICE_ACCESS_ENFORCEMENT_TRIGGERED
APPLICATION: CAS
WHEN: Mon Jan 28 16:28:02 CST 2019
CLIENT IP ADDRESS: 127.0.0.1
SERVER IP ADDRESS: 127.0.0.1
=============================================================
>
2019-01-28 16:28:04,866 INFO [org.apereo.cas.DefaultCentralAuthenticationService] - <Granted ticket [ST-1-R4bNjOBlFeHz74g8XrmFlzFLPo0DESKTOP-NEPM8G8] for service [http://app1.cas.com:9001/] and principal [111]>
2019-01-28 16:28:04,867 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: 111
WHAT: ST-1-R4bNjOBlFeHz74g8XrmFlzFLPo0DESKTOP-NEPM8G8 for http://app1.cas.com:9001/
ACTION: SERVICE_TICKET_CREATED
APPLICATION: CAS
WHEN: Mon Jan 28 16:28:04 CST 2019
CLIENT IP ADDRESS: 127.0.0.1
SERVER IP ADDRESS: 127.0.0.1
=============================================================
>
2019-01-28 16:28:04,867 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: 111
WHAT: [status=200-OK,body=ST-1-R4bNjOBlFeHz74g8XrmFlzFLPo0DESKTOP-NEPM8G8]
ACTION: REST_API_SERVICE_TICKET_CREATED
APPLICATION: CAS
WHEN: Mon Jan 28 16:28:04 CST 2019
CLIENT IP ADDRESS: 127.0.0.1
SERVER IP ADDRESS: 127.0.0.1
=============================================================
>
2019-01-28 16:28:18,331 INFO [org.apereo.cas.web.flow.login.InitialFlowSetupAction] - <Setting path for cookies for warn cookie generator to: [/cas/] >
2019-01-28 16:28:18,345 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: audit:unknown
WHAT: [event=success,timestamp=Mon Jan 28 16:28:18 CST 2019,source=RankedMultifactorAuthenticationProviderWebflowEventResolver]
ACTION: AUTHENTICATION_EVENT_TRIGGERED
APPLICATION: CAS
WHEN: Mon Jan 28 16:28:18 CST 2019
CLIENT IP ADDRESS: 127.0.0.1
SERVER IP ADDRESS: 127.0.0.1
=============================================================
>
2019-01-28 16:28:20,126 WARN [org.apache.catalina.util.SessionIdGeneratorBase] - <Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [120] milliseconds.>
2019-01-28 16:28:29,333 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: audit:unknown
WHAT: [result=Service Access Granted,service=http://app1.cas.com:9001/,principal=SimplePrincipal(id=111, attributes={}),requiredAttributes={}]
ACTION: SERVICE_ACCESS_ENFORCEMENT_TRIGGERED
APPLICATION: CAS
WHEN: Mon Jan 28 16:28:29 CST 2019
CLIENT IP ADDRESS: 127.0.0.1
SERVER IP ADDRESS: 127.0.0.1
=============================================================
>
2019-01-28 16:28:29,334 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: 111
WHAT: ST-1-R4bNjOBlFeHz74g8XrmFlzFLPo0DESKTOP-NEPM8G8
ACTION: SERVICE_TICKET_VALIDATE_SUCCESS
APPLICATION: CAS
WHEN: Mon Jan 28 16:28:29 CST 2019
CLIENT IP ADDRESS: 127.0.0.1
SERVER IP ADDRESS: 127.0.0.1
=============================================================基于此restful认证已经完成。
请求中的cookie为:8074ACBDF7367A3EBDFF049730D741BF
这个cookie创建的位置为:
在对于验证码页面进行加载的时候,重置了sessionid
关于/login提交后,从数据库验证用户名,密码;通过后创建TGT,并创建jsessionid和TGC的创建;之后重定向到请求的url并传入st参数进行验证
cookie的详细内容
/login登陆页面的提交参数有:
重定向到url的请求:
Set-Cookie的值:A792112B087A9DB1E333E76868ED7B4C
至此,完成整个登陆界面
在cas client1已经登陆的情况下,client2在cas server中的认证流程是这样的:
private void configureWebflowContext(final RequestContext context) { val request = WebUtils.getHttpServletRequestFromExternalWebflowContext(context); WebUtils.putTicketGrantingTicketInScopes(context, this.ticketGrantingTicketCookieGenerator.retrieveCookieValue(request)); WebUtils.putWarningCookie(context, Boolean.valueOf(this.warnCookieGenerator.retrieveCookieValue(request))); WebUtils.putGoogleAnalyticsTrackingIdIntoFlowScope(context, casProperties.getGoogleAnalytics().getGoogleAnalyticsTrackingId()); WebUtils.putGeoLocationTrackingIntoFlowScope(context, casProperties.getEvents().isTrackGeolocation()); WebUtils.putPasswordManagementEnabled(context, casProperties.getAuthn().getPm().isEnabled()); WebUtils.putRememberMeAuthenticationEnabled(context, casProperties.getTicket().getTgt().getRememberMe().isEnabled()); WebUtils.putStaticAuthenticationIntoFlowScope(context, StringUtils.isNotBlank(casProperties.getAuthn().getAccept().getUsers()) || StringUtils.isNotBlank(casProperties.getAuthn().getReject().getUsers())); if (casProperties.getAuthn().getPolicy().isSourceSelectionEnabled()) { val availableHandlers = authenticationEventExecutionPlan.getAuthenticationHandlers() .stream() .filter(h -> h.supports(UsernamePasswordCredential.class)) .map(h -> StringUtils.capitalize(h.getName().trim())) .distinct() .sorted() .collect(Collectors.toList()); WebUtils.putAvailableAuthenticationHandleNames(context, availableHandlers); } }
public String retrieveCookieValue(final HttpServletRequest request) { try { var cookie = org.springframework.web.util.WebUtils.getCookie(request, getCookieName()); if (cookie == null) { val cookieValue = request.getHeader(getCookieName()); if (StringUtils.isNotBlank(cookieValue)) { LOGGER.trace("Found cookie [{}] under header name [{}]", cookieValue, getCookieName()); cookie = createCookie(cookieValue); } } return cookie == null ? null : this.casCookieValueManager.obtainCookieValue(cookie, request); } catch (final Exception e) { LOGGER.debug(e.getMessage(), e); } return null; }
protected String obtainValueFromCompoundCookie(final String cookieValue, final HttpServletRequest request) { val cookieParts = Splitter.on(String.valueOf(COOKIE_FIELD_SEPARATOR)).splitToList(cookieValue); if (cookieParts.isEmpty()) { throw new IllegalStateException("Invalid empty cookie"); } val value = cookieParts.get(0); if (!cookieProperties.isPinToSession()) { LOGGER.debug("Cookie session-pinning is disabled. Returning cookie value as it was provided"); return value; } if (cookieParts.size() != COOKIE_FIELDS_LENGTH) { throw new IllegalStateException("Invalid cookie. Required fields are missing"); } val remoteAddr = cookieParts.get(1); val userAgent = cookieParts.get(2); if (Stream.of(value, remoteAddr, userAgent).anyMatch(StringUtils::isBlank)) { throw new IllegalStateException("Invalid cookie. Required fields are empty"); } val clientInfo = ClientInfoHolder.getClientInfo(); if (!remoteAddr.equals(clientInfo.getClientIpAddress())) { throw new IllegalStateException("Invalid cookie. Required remote address " + remoteAddr + " does not match " + clientInfo.getClientIpAddress()); } val agent = HttpRequestUtils.getHttpServletRequestUserAgent(request); if (!userAgent.equals(agent)) { throw new IllegalStateException("Invalid cookie. Required user-agent " + userAgent + " does not match " + agent); } return value; }
代码说明:首先解密TGC后得到一个由@符号分隔的字符串,分隔后获取到TGT、客户端IP、客户端代理信息。并将从TGC中解密的客户端IP信息和客户端代理信息与当前请求的客户端IP信息和客户端代理信息进行比较,若不相等就抛出异常(Cas的安全策略)。