近期项目上需要将我司系统集成至合作方云平台,双方都有登录,于是改造我司登录模式(我司项目最终会部署至合作方服务器),通过oauth2接入合作方云平台实现获取授权码及token登录本身的项目,下面就实践过程进行记录整理
整体分为以下几个步骤
下面就三个步骤进行解释:
1.调用接口授权码,oauth2的通用格式 xxx.com/oauth/authorize?client_id=client_id&response_type=code&redirect_uri=http://localhost:xxx/xxx
其中redirect_uri为回调接口,此次过程中为项目中接口,接收授权码回调并进行解析
2.通过接口获取授权码 xxx.com/oauth/token?grant_type=authorization_code&client_id=client_id&client_secret=be4ba6c9-c6f9-bb81-f2df-88381208b8d6&code=8N6TIo&redirect_uri=http://localhost:8081/getloginIDaasCode
{
"access_token": "436423b4-fc22-4f41-8186-d8706ae9396f",
"token_type": "bearer",
"refresh_token": "ce3dd10e-ec60-4399-9076-ee2140b04a61",
"expires_in": 1999,
"scope": "read write trust"
}
此时会获取到accessToken,此时已经完成调用,需要将合作方token改造换取成我方token
public OutputMessage loadAccessToken(HttpServletRequest request,HttpServletResponse response,
@RequestParam(name = "code")String authCode,
@RequestParam(name = "reqUrl",required=false)String reqUrl,
@RequestParam(required=false) String state) throws IOException, OAuthProblemException, OAuthSystemException {
// code为授权码 如8N6TIo
String homeUrl = publicService.genHomeUrl( authCode,reqUrl );
WebUtils.issueRedirect(request, response, homeUrl);
OutputMessage output = new OutputMessage();
return output;
}
/**
*
* 1、换取token
* 2、获取用户数据
* 3、创建ui参数
* 4、将ui参数跟token数据进行绑定
* 5、构建首页地址
*/
@Override
public String genHomeUrl(String authCode, String reqUrl) throws OAuthSystemException, OAuthProblemException {
// 转发地址,clientId,秘钥等从数据库获取
Oauth2Bean oauth2Bean = cuSysConfService.getOauth2Bean();
//1、该代码块 从token中获取用户信息
OAuthClientRequest req = OAuthClientRequest
.tokenLocation(oauth2Bean.getTokenUrl())
.setClientId(oauth2Bean.getClientId())
.setClientSecret(oauth2Bean.getClientSecret())
.setGrantType(GrantType.AUTHORIZATION_CODE).setCode(authCode)
.setRedirectURI(StringUtils.isEmpty(reqUrl) ? oauth2Bean.getRedirectUrl() : reqUrl)
.buildBodyMessage();
req.addHeader("Accept", "application/json");
req.addHeader("Content-Type", "application/json");
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
// 获取token
OAuthAccessTokenResponse oauthResponse = oAuthClient.accessToken(req);
String accessToken = oauthResponse.getAccessToken();
//2、通过access_token获取userInfo
OAuthClientRequest bearerClientRequest = new OAuthBearerClientRequest(oauth2Bean.getUserInfo()+"?client_id="+oauth2Bean.getClientId())
.setAccessToken(accessToken)
.buildQueryMessage();
OAuthResourceResponse resourceResponse = oAuthClient.resource(bearerClientRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
String userName = resourceResponse.getBody();
//3、构建UI参数 //"admin:#{"ct":"2022-05-06 11:05:10","reqUrl":"xxx"}#:code_admin";
String uiTempl = "{}:#{\"ct\":\"{}\",\"reqUrl\":\"{}\"}#:{}"+CommonConstants.authCodeLink+"{}";
String uiParam = StrUtil.format(uiTempl, userName, DateUtil.getNowDateTimeStr(),reqUrl, authCode,userName);
CuSysConf UISecretKeyCuSysConf = cuSysConfService.findValidCuSysConfByConfKey(QuVars.sysLoginUIEncryptPubKey);
if( UISecretKeyCuSysConf == null && UISecretKeyCuSysConf.getConfigValue()!=null ){
throw new BusinessException("未找到秘钥信息,请联系管理员");
}
try {
uiParam = RSAUtil.encrypt(uiParam, UISecretKeyCuSysConf.getConfigValue().trim() );
} catch (Exception e) {
LOG.error(e.getMessage(),e);
throw new BusinessException( e.getMessage() );
}
//4、绑定ui参数
// cacheDataService.saveAccessToken( authCode+ CommonConstants.authCodeLink+userName ,accessToken );
// cacheDataService.saveAccessTokenInfo( authCode+CommonConstants.authCodeLink+userName, oauthResponse.getBody() );
cuUsLoginSService.buildUserPermissionMenu(userName);
String homeUrl = curesSService.findHomeUrl(userName);
//5、构建首页地址,拼接首页地址进行转发,如前端参与可不做
String url = "";
//如果 reqUrl 不是空就使用此地址作为域名
if( StrUtil.isNotBlank( reqUrl ) ){
if (homeUrl.toLowerCase().startsWith("http")){
homeUrl = homeUrl.toLowerCase()
.replaceFirst("http://", "")
.replaceFirst("https://", "");
}
String suffixUrl = "";
if( homeUrl.contains("/") ){
suffixUrl = homeUrl.substring(homeUrl.indexOf("/"));
}
if (reqUrl.toLowerCase().startsWith("http")) {
url = reqUrl+suffixUrl;
}else{
url = "http://"+reqUrl+suffixUrl;
}
url = URLUtil.normalize(url);
url = url+"?UI="+ URLEncoder.encode(uiParam);
}else{
url = homeUrl+"?UI="+ URLEncoder.encode(uiParam);
}
return url;
}
最终将构建的地址进行访问即可直接通过token登录我司后台系统,达到接入oauth2系统无感登录。