前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

项目中遇到和一些其他的部门进行联合办案,有时候,只是用下他们的接口,不需要大飞周章去登录,所以这里就派上了用场,需要注意的是,提供给等的用户名和密码。在登录后的权限一定是要被控制的,因为万一代码泄漏了,那是很麻烦的。



#cas config
cas.server.url.prefix=https://cas.healerjean.com
cas.server.url.login=${cas.server.url.prefix}/login
cas.server.url.ticket=${cas.server.url.prefix}/v1/tickets
cas.client.name=http://localhost:${server.port}
#客户端



package com.duodian.youhui.admin.moudle;

import com.duodian.youhui.admin.Exceptions.AppException;
import com.duodian.youhui.admin.bean.ResponseBean;
import com.duodian.youhui.admin.utils.HttpHelper;
import com.duodian.youhui.admin.utils.SdkHttpHelper;
import com.duodian.youhui.admin.utils.Xml2Json;
import com.duodian.youhui.data.admin.SysAdminUser;
import com.duodian.youhui.data.http.HttpBackBean;
import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.authentication.AttributePrincipalImpl;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.AssertionHolder;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.AssertionImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Desc:
 * @Author HealerJean
 * @Date 2018/7/18  下午4:58.
 */
@Api(description = "利用代码登录")
@Controller
@Slf4j
@ApiResponses(value = {
        @ApiResponse(code = 200, message = "访问正常"),
        @ApiResponse(code = 301, message = "逻辑错误"),
        @ApiResponse(code = 500, message = "系统错误"),
        @ApiResponse(code = 401, message = "未认证"),
        @ApiResponse(code = 403, message = "禁止访问"),
        @ApiResponse(code = 404, message = "url错误")
})
@RequestMapping("duodian/youhui")
public class CodeLoginController {


    @Value("${cas.server.url.ticket}")
    private String ticketUrl;

    @Value("${cas.server.url.prefix}")
    private String casUrl;

    @Value("${cas.client.name}")
    private String clientName;




@PostMapping("loginByCode")
@ResponseBody
public ResponseBean loginByCode(String code, HttpServletRequest request){
    try {
        if(StringUtils.equals("k1UT716udbyBapd9",code )){
            log.info("[代码登录 code =:"+code);
            SysAdminUser sysAdminUser = new SysAdminUser();
            sysAdminUser.setEmail("healerjean@gmail.com");
            sysAdminUser.setPassword("password");
            return this.casLogin(request, sysAdminUser);
        }
    } catch (Exception e) {
        log.error("[代码登录报错信息]"+e.getMessage(),e);
    }
    return ResponseBean.buildFailure();
}



    private ResponseBean casLogin(HttpServletRequest request, SysAdminUser adminUser) throws IOException {

        //开始远程请求登录服务器获取ticket
        LinkedHashMap<String,String> paramMap = new LinkedHashMap<>();
        paramMap.put("username",adminUser.getEmail());
        paramMap.put("password",adminUser.getPassword());
        HttpBackBean ticketContent = SdkHttpHelper.handlePostFormData(ticketUrl, null, paramMap, SdkHttpHelper.OVERTIME);

        String regex = "(?<=tickets/).+?(?=\\\")";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(ticketContent.getResult());



        if (matcher.find()) {
            // 我是不想这么写一堆的if else一层套一层的,强烈批判,不过为了兼容李世伟之前的代码写法,也只能写的这么丑了。
            // 我不对这种风格的代码负责。
            String ticket = matcher.group(0);
            log.info("[CodeLoginController]ticket:" + ticket);
            String service = "service="+ URLEncoder.encode(clientName,"UTF-8");
            String infoTicket = HttpHelper.handlePost(ticketUrl+"/"+ticket,service);
            log.info("[CodeLoginController]infoTicket:" + infoTicket);
            String infoContent = HttpHelper.handleGet(casUrl + "/p3/serviceValidate?service="+URLEncoder.encode(clientName,"UTF-8")+"&ticket="+infoTicket);
            log.info("[CodeLoginController]infoContent:" + infoContent);

            JSONObject jsonObject = JSONObject.fromObject(Xml2Json.xml2Json(infoContent));


            if (jsonObject.getString("authenticationSuccess") == null){
                throw new AppException("jsonNode-authenticationSuccess为空!");
            }
            if (jsonObject.getJSONObject("authenticationSuccess").getString("user") == null){
                throw new AppException("jsonNode-authenticationSuccess-user为空!");
            }
            String username = jsonObject.getJSONObject("authenticationSuccess").getString("user");
            log.info("[登录的用户名邮箱为]username:" + username);

            Map<String,Object> attributes = new HashMap<>();
            JSONObject resultMessage = jsonObject.getJSONObject("authenticationSuccess");


            for (Object key : resultMessage.keySet()) {
                    Object res = resultMessage.get(key);
                    attributes.put(key.toString(),res.toString());
                    log.info(key.toString()+":"+res.toString());
            }

            AttributePrincipal principal = new AttributePrincipalImpl(username,attributes);
            Assertion assertion = new AssertionImpl(principal,attributes);

            request.getSession().setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION,assertion);
            AssertionHolder.setAssertion(assertion);
            return ResponseBean.buildSuccess();
        } else {
        }
        return ResponseBean.buildSuccess(ticketContent);
    }

}


2、打印结果

 [CodeLoginController]ticket:TGT-2592-Oc1CTEtTcQVvfbgQbmeMEiVWYXTASI0LNvMRODrg-4cb0f809dc7d-casadmin-casadmin-1
 
 
 [CodeLoginController]infoTicket:ST-2574-2w5LWRCtt-4cb0f809dc7d-casadmin-casadmin-1
 
 
  [CodeLoginController]infoContent:
  
  <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
    <cas:authenticationSuccess>
        <cas:user>healerjean@gmail.com</cas:user>
        <cas:attributes>
            <cas:isFromNewLogin>true</cas:isFromNewLogin>
            <cas:authenticationDate>2018-07-20T11:19:05.882+08:00[Asia/Shanghai]</cas:authenticationDate>
            <cas:phone>15555555555</cas:phone>
            <cas:authenticationMethod>QueryDatabaseAuthenticationHandler</cas:authenticationMethod>
            <cas:successfulAuthenticationHandlers>QueryDatabaseAuthenticationHandler</cas:successfulAuthenticationHandlers>
            <cas:name>HealerJean</cas:name>
            <cas:longTermAuthenticationRequestTokenUsed>false</cas:longTermAuthenticationRequestTokenUsed>
            <cas:id>66</cas:id>
            </cas:attributes>
    </cas:authenticationSuccess>
</cas:serviceResponse>

ContactAuthor