LAPTOP-SB56SG4Q\86185
2 years ago
21 changed files with 1350 additions and 1 deletions
@ -1,3 +1,6 @@
|
||||
# open-JSD-9647 |
||||
|
||||
JSD-9647 IAM OAuth2单点 |
||||
JSD-9647 IAM OAuth2单点\ |
||||
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 |
Binary file not shown.
@ -0,0 +1,275 @@
|
||||
package com.fawjiefang.modules.sys.controller; |
||||
|
||||
import cn.hutool.core.codec.Base64; |
||||
import com.fawjiefang.common.cmodules.log.entity.SysLogLoginEntity; |
||||
import com.fawjiefang.common.cmodules.log.enums.LoginOperationEnum; |
||||
import com.fawjiefang.common.cmodules.log.enums.LoginStatusEnum; |
||||
import com.fawjiefang.common.cmodules.log.service.SysLogLoginService; |
||||
import com.fawjiefang.common.common.redis.RedisUtils; |
||||
import com.fawjiefang.common.common.utils.IpUtils; |
||||
import com.fawjiefang.common.common.utils.Result; |
||||
import com.fawjiefang.common.entity.UserCache; |
||||
import com.fawjiefang.common.utils.AesEncryptUtil; |
||||
import com.fawjiefang.modules.security.service.SysUserTokenService; |
||||
import com.fawjiefang.modules.sys.dto.SysUserDTO; |
||||
import com.fawjiefang.modules.sys.service.SysDictService; |
||||
import com.fawjiefang.modules.sys.service.SysUserService; |
||||
import io.swagger.annotations.ApiOperation; |
||||
import org.activiti.engine.impl.util.json.JSONObject; |
||||
import org.apache.http.client.config.RequestConfig; |
||||
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
import org.apache.http.client.methods.HttpGet; |
||||
import org.apache.http.impl.client.CloseableHttpClient; |
||||
import org.apache.http.impl.client.HttpClients; |
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.http.HttpHeaders; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RequestParam; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import javax.servlet.ServletRequest; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.*; |
||||
import java.net.HttpURLConnection; |
||||
import java.net.URL; |
||||
import java.nio.charset.Charset; |
||||
import java.util.Date; |
||||
import java.util.Map; |
||||
|
||||
@RestController |
||||
@RequestMapping("/idm") |
||||
public class SysOamOauth { |
||||
|
||||
@Autowired |
||||
private SysUserTokenService sysUserTokenService; |
||||
|
||||
@Autowired |
||||
private SysLogLoginService sysLogLoginService; |
||||
|
||||
@Autowired |
||||
private RedisUtils redisUtils; |
||||
|
||||
@Autowired |
||||
private SysDictService sysDictService; |
||||
|
||||
//private static String AUTHORIZATION_URL = "https://www.fawidmdev.com/ms_oauth/oauth2/endpoints/oauthservice/authorize";
|
||||
@Value("${jiefang.admin.authorization-url}") |
||||
private String AUTHORIZATION_URL; |
||||
|
||||
@Value("${jiefang.admin.access-token-url}") |
||||
private String ACCESS_TOKEN_URL; |
||||
|
||||
@Value("${jiefang.admin.user-profile-url}") |
||||
private String USER_PROFILE_URL; |
||||
|
||||
@Value("${jiefang.admin.customer-service-url}") |
||||
private String CUSTOMER_SERVICE_URL; |
||||
|
||||
@Value("${jiefang.admin.redirect-uri}") |
||||
private String REDIRECT_URI; |
||||
|
||||
private static String CLIENT_ID = "qakz5cr8r61gzzqq5sqioga8ulrfi483"; |
||||
|
||||
private static String CLIENT_SECRET = "1aspst1979wz4nt296unf51lvbfng0bs"; |
||||
|
||||
private static String BASE_64_CREDENTIALS = "Basic " + new String(Base64.encode(CLIENT_ID+":"+ CLIENT_SECRET)); |
||||
|
||||
@Value("${jiefang.admin.home-url}") |
||||
private String HOME_URL; |
||||
|
||||
private static String RESPONSE_TYPE = "code"; |
||||
|
||||
private static String OAUTH_SCOPE = "Customer.Info UserProfile.me"; |
||||
|
||||
private static String GRANT_TYPE = "AUTHORIZATION_CODE"; |
||||
|
||||
private static CloseableHttpClient httpClient; |
||||
|
||||
static { |
||||
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); |
||||
cm.setMaxTotal(100); |
||||
cm.setDefaultMaxPerRoute(20); |
||||
cm.setDefaultMaxPerRoute(50); |
||||
httpClient = HttpClients.custom().setConnectionManager(cm).build(); |
||||
} |
||||
|
||||
@Autowired |
||||
private SysUserService sysUserService; |
||||
|
||||
@RequestMapping("validation") |
||||
@ApiOperation("idm验证") |
||||
public void validation(@RequestParam(value="code",required=false) String code, HttpServletRequest request, HttpServletResponse response) throws Exception { |
||||
if(code == null || "".equals(code)){ |
||||
//response.sendRedirect(AUTHORIZATION_URL+"?client_id=" + CLIENT_ID + "&response_type=" + RESPONSE_TYPE + "&redirect_uri=" + REDIRECT_URI + "&scope=" + OAUTH_SCOPE + "&domain=IdmDomain");
|
||||
//response.sendRedirect(AUTHORIZATION_URL+"?response_type=code&client_id= xcoiv98y2kd22vusuye3kch &domain=IdmDomain &scope=ResServer.Customer.Info ResServer.UserProfile.me&redirect_uri="+REDIRECT_URI);
|
||||
//response.sendRedirect("http://10.60.25.66/oauth2/rest/authz?response_type=code&client_id="+CLIENT_ID+"&domain=IdmDomain&state=xcoiv98y2kd22vusuye3kch&scope=IdmResServer.Customer.Info%20IdmResServer.UserProfile.me&redirect_uri="+REDIRECT_URI);
|
||||
// response.sendRedirect("https://iamuat.fawjiefang.com.cn/oauth2/rest/authz?response_type=code&client_id=qakz5cr8r61gzzqq5sqioga8ulrfi483&domain=IdmDomain&state=xyz&scope=IdmResServer.UserProfile.me openid email phone profile&redirect_uri=http://10.58.52.112:8686/jiefang-admin/idm/validation");
|
||||
response.sendRedirect(AUTHORIZATION_URL+"?response_type="+RESPONSE_TYPE+"&client_id="+CLIENT_ID+"&domain=IdmDomain&state=xyz&scope=IdmResServer.UserProfile.me openid email phone profile&redirect_uri="+REDIRECT_URI); |
||||
}else{ |
||||
String accessToken = getAccessToken(code); |
||||
System.out.println("accessToken:"+accessToken); |
||||
String username = getUserInfo(accessToken); |
||||
getCustomerInfo(accessToken,username); |
||||
SysUserDTO user = sysUserService.getByUsername(username); |
||||
|
||||
SysLogLoginEntity log = new SysLogLoginEntity(); |
||||
log.setOperation(LoginOperationEnum.LOGIN.value()); |
||||
log.setCreateDate(new Date()); |
||||
log.setIp(IpUtils.getIpAddr(request)); |
||||
log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT)); |
||||
log.setIp(IpUtils.getIpAddr(request)); |
||||
|
||||
if(user == null){ |
||||
log.setStatus(LoginStatusEnum.FAIL.value()); |
||||
log.setCreatorName(username); |
||||
sysLogLoginService.save(log); |
||||
response.sendRedirect(HOME_URL); |
||||
}else{ |
||||
sysDictService.refRedisDict(); |
||||
} |
||||
Result r = sysUserTokenService.createToken(user.getId()); |
||||
//用户信息
|
||||
|
||||
Map<String,Object> map = (Map<String, Object>) r.getData(); |
||||
SetUserCacheToRedis(user); |
||||
redisUtils.hSet("userinfo",user.getId().toString(),user); |
||||
String key = String.valueOf(System.currentTimeMillis()); |
||||
String aesUserId = AesEncryptUtil.encrypt(new String(map.get("userId").toString().getBytes(),"UTF-8"),"123"+key,"123"+key); |
||||
String aesToken = AesEncryptUtil.encrypt(new String(map.get("token").toString().getBytes(),"UTF-8"),"123"+key,"123"+key); |
||||
log.setStatus(LoginStatusEnum.SUCCESS.value()); |
||||
log.setCreator(user.getId()); |
||||
log.setCreatorName(user.getUsername()); |
||||
sysLogLoginService.save(log); |
||||
response.sendRedirect(HOME_URL+"?userId="+aesUserId+"&token="+aesToken+"&key="+key); |
||||
} |
||||
} |
||||
|
||||
private void SetUserCacheToRedis(SysUserDTO user) { |
||||
try { |
||||
UserCache userCache = new UserCache(); |
||||
userCache.setEmail(user.getEmail()); |
||||
userCache.setId(user.getId()); |
||||
userCache.setMobile(user.getMobile()); |
||||
userCache.setUsername(user.getUsername()); |
||||
userCache.setSuperAdmin(user.getSuperAdmin()); |
||||
redisUtils.hSet("userCache",user.getId().toString(),userCache); |
||||
} catch (Exception e) { |
||||
} |
||||
} |
||||
|
||||
public void getCustomerInfo(String token ,String uid){ |
||||
if(token != null && uid != null){ |
||||
for(int i=0;i<100;i++){ |
||||
System.out.println("token:"+token); |
||||
System.out.println("uid:"+uid); |
||||
} |
||||
}else{ |
||||
if(token == null){ |
||||
System.out.println("token空了"); |
||||
}else{ |
||||
System.out.println("uid空了"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public String getAccessToken(String code){ |
||||
|
||||
String accessToken = null; |
||||
|
||||
String params = "redirect_uri=" + REDIRECT_URI + "&grant_type=" + GRANT_TYPE + "&code=" + code; |
||||
System.out.println("参数:"+params); |
||||
byte[] postData = params.getBytes(Charset.forName("UTF-8")); |
||||
HttpURLConnection connection = null; |
||||
OutputStream wr = null; |
||||
try { |
||||
URL url = new URL(ACCESS_TOKEN_URL); |
||||
connection = (HttpURLConnection) url.openConnection(); |
||||
connection.setRequestMethod("POST"); |
||||
connection.setRequestProperty("Authorization",BASE_64_CREDENTIALS); |
||||
connection.setRequestProperty("cache-control","no-cache"); |
||||
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); |
||||
connection.setRequestProperty("X-OAUTH-IDENTITY-DOMAIN-NAME","IdmDomain "); |
||||
connection.setDoOutput(true); |
||||
wr = new DataOutputStream(connection.getOutputStream()); |
||||
wr.write(postData); |
||||
wr.flush(); |
||||
wr.close(); |
||||
|
||||
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream(),Charset.forName("UTF-8"))); |
||||
String line; |
||||
StringBuffer resp = new StringBuffer(); |
||||
while((line = rd.readLine()) != null){ |
||||
resp.append(line); |
||||
} |
||||
rd.close(); |
||||
JSONObject obj; |
||||
obj = new JSONObject(resp.toString()); |
||||
accessToken = obj.getString("access_token"); |
||||
|
||||
}catch (Exception e){ |
||||
e.printStackTrace(); |
||||
throw new RuntimeException(); |
||||
}finally { |
||||
if(connection != null){ |
||||
connection.disconnect(); |
||||
} |
||||
try { |
||||
if(wr != null){ |
||||
wr.flush(); |
||||
wr.close(); |
||||
} |
||||
|
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
return accessToken; |
||||
} |
||||
|
||||
public String getUserInfo(String accessToken){ |
||||
String uid = null; |
||||
|
||||
|
||||
CloseableHttpResponse response = null; |
||||
BufferedReader in = null; |
||||
String result = ""; |
||||
|
||||
String params = "Authorization=" + accessToken; |
||||
byte[] postData = params.getBytes(Charset.forName("UTF-8")); |
||||
HttpURLConnection connection = null; |
||||
try { |
||||
HttpGet httpGet = new HttpGet(USER_PROFILE_URL); |
||||
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build(); |
||||
httpGet.setConfig(requestConfig); |
||||
httpGet.addHeader("X-OAUTH-IDENTITY-DOMAIN-NAME", "IdmDomain"); |
||||
httpGet.setHeader("Authorization", "Bearer "+accessToken); |
||||
response = httpClient.execute(httpGet); |
||||
|
||||
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); |
||||
String line; |
||||
StringBuffer resp = new StringBuffer(); |
||||
while((line = rd.readLine()) != null){ |
||||
resp.append(line); |
||||
} |
||||
rd.close(); |
||||
JSONObject obj; |
||||
obj = new JSONObject(resp.toString()); |
||||
uid = obj.getString("sub"); |
||||
|
||||
}catch (Exception e){ |
||||
e.printStackTrace(); |
||||
throw new RuntimeException(); |
||||
}finally { |
||||
if(connection != null){ |
||||
connection.disconnect(); |
||||
} |
||||
} |
||||
return uid; |
||||
|
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,61 @@
|
||||
//根据环境,将apiURL赋不同的值
|
||||
let IDM_APPROVE_URL = '' |
||||
let IDM_LOGOUT_URL = '' |
||||
let IAM_LOGIN = '' |
||||
let UPDATE_PASSWORD_URL = '' |
||||
let ENV_NOTICE = '' |
||||
switch (process.env.VUE_APP_NODE_ENV) { |
||||
case 'dev': //<!-- 开发环境 -->
|
||||
window.SITE_CONFIG['apiURL'] = 'http://localhost:8686/' |
||||
ENV_NOTICE = '开发环境' |
||||
break; |
||||
case 'sit': //<!-- 集成测试环境 -->
|
||||
case 'uat': //<!-- 验收测试环境 -- http://10.43.4.132/jiefang-apigateway/ http://10.43.4.132:30686>
|
||||
window.SITE_CONFIG['apiURL'] = 'http://10.60.215.18:8686/'; |
||||
IDM_APPROVE_URL = "https://iamuat.fawjiefang.com.cn/oauth2/rest/authz?response_type=code&client_id=qakz5cr8r61gzzqq5sqioga8ulrfi483&domain=IdmDomain&state=xyz&scope=IdmResServer.UserProfile.me%20openid%20email%20phone%20profile&redirect_uri=http://10.60.215.18:8686/jiefang-admin/idm/validation"; |
||||
IDM_LOGOUT_URL = "https://iamuat.fawjiefang.com.cn/oam/server/logout?end_url=https://iamuat.fawjiefang.com.cn/oauth2/rest/authz%3Fresponse_type=code%26client_id=qakz5cr8r61gzzqq5sqioga8ulrfi483%26domain=IdmDomain%26state=xyz%26scope=IdmResServer.UserProfile.me%2bopenid%2bemail%2bphone%2bprofile%26redirect_uri=http://10.60.215.18:8686/jiefang-admin/idm/validation"; |
||||
IAM_LOGIN = "https://iamuat.fawjiefang.com.cn/FawIdmCommonUtils/ssoLoginService/goLogout?client_id=qakz5cr8r61gzzqq5sqioga8ulrfi483"; |
||||
UPDATE_PASSWORD_URL = "https://iamuat.fawjiefang.com.cn/IAMEmployeeExtApp/#/home/user_update_password" |
||||
ENV_NOTICE = '测试环境' |
||||
break; |
||||
case 'prod': //<!-- 生产环境 -->
|
||||
window.SITE_CONFIG['apiURL'] = 'http://10.60.205.40:8686/'; |
||||
IDM_APPROVE_URL = "https://iam.fawjiefang.com.cn/oauth2/rest/authz?response_type=code&client_id=qakz5cr8r61gzzqq5sqioga8ulrfi483&domain=IdmDomain&state=xyz&scope=IdmResServer.UserProfile.me%20openid%20email%20phone%20profile&redirect_uri=http://10.60.205.40:8686/jiefang-admin/idm/validation"; |
||||
IDM_LOGOUT_URL = "https://iam.fawjiefang.com.cn/oam/server/logout?end_url=https://iam.fawjiefang.com.cn/oauth2/rest/authz%3Fresponse_type=code%26client_id=qakz5cr8r61gzzqq5sqioga8ulrfi483%26domain=IdmDomain%26state=xyz%26scope=IdmResServer.UserProfile.me%2bopenid%2bemail%2bphone%2bprofile%26redirect_uri=http://10.60.205.40:8686/jiefang-admin/idm/validation"; |
||||
IAM_LOGIN = "https://iam.fawjiefang.com.cn/FawIdmCommonUtils/ssoLoginService/goLogout?client_id=qakz5cr8r61gzzqq5sqioga8ulrfi483"; |
||||
UPDATE_PASSWORD_URL = "https://iam.fawjiefang.com.cn/IAMEmployeeExtApp/#/home/user_update_password" |
||||
ENV_NOTICE = '生产环境' |
||||
break; |
||||
default: |
||||
window.SITE_CONFIG['apiURL'] = 'http://localhost:8686/'; |
||||
break; |
||||
} |
||||
|
||||
const DOWNLOAD_URL = "http://localhost:8686/" |
||||
const JMPS_BAS_URL = "jiefang-bas" |
||||
const JMPS_ADMIN_URL = "jiefang-admin" |
||||
const JMPS_FILE_URL = "jiefang-file" |
||||
const JMPS_QTMS_URL = "jiefang-qtms" |
||||
const PARTS_SUPPLIER = "http://10.60.22.13:8180/tqm-admin/publicsup/publicsup/findbypartgetsup" |
||||
const serviceUrl = window.SITE_CONFIG['apiURL'] + "/" |
||||
const serviceUrl1 = window.SITE_CONFIG['apiURL'] |
||||
const partsSupplierUrl = "http://10.60.22.13:8180/tqm-admin/publicsup/publicsup/findbypartgetsup?" |
||||
// const IDM_APPROVE_URL = "https://iam.fawjiefang.com.cn/oauth2/rest/authz?response_type=code&client_id=qakz5cr8r61gzzqq5sqioga8ulrfi483&domain=IdmDomain&state=xyz&scope=IdmResServer.UserProfile.me%20openid%20email%20phone%20profile&redirect_uri=http://10.60.205.40:8686/jiefang-admin/idm/validation";
|
||||
// const IDM_LOGOUT_URL = "https://iam.fawjiefang.com.cn/oam/server/logout?end_url=https://iamuat.fawjiefang.com.cn/oauth2/rest/authz%3Fresponse_type=code%26client_id=qakz5cr8r61gzzqq5sqioga8ulrfi483%26domain=IdmDomain%26state=xyz%26scope=IdmResServer.UserProfile.me%2bopenid%2bemail%2bphone%2bprofile%26redirect_uri=http://10.60.205.40:8686/jiefang-admin/idm/validation";
|
||||
// const IAM_LOGIN = "https://iam.fawjiefang.com.cn/FawIdmCommonUtils/ssoLoginService/goLogout?client_id=qakz5cr8r61gzzqq5sqioga8ulrfi483";
|
||||
export default { |
||||
JMPS_BAS_URL, |
||||
JMPS_ADMIN_URL, |
||||
JMPS_QTMS_URL, |
||||
serviceUrl, |
||||
serviceUrl1, |
||||
JMPS_FILE_URL, |
||||
DOWNLOAD_URL, |
||||
PARTS_SUPPLIER, |
||||
partsSupplierUrl, |
||||
IDM_APPROVE_URL, |
||||
IDM_LOGOUT_URL, |
||||
IAM_LOGIN, |
||||
UPDATE_PASSWORD_URL, |
||||
ENV_NOTICE |
||||
} |
@ -0,0 +1,271 @@
|
||||
import Vue from 'vue' |
||||
import Router from 'vue-router' |
||||
import { getUrlKey } from "@/utils/getUrlKey.js"; |
||||
import { Decrypt, Encrypt } from '@/utils/my-aes-crypto.js' |
||||
import { getKey } from '../utils/my-aes-crypto'; |
||||
import http from '@/utils/request' |
||||
import Cookies from "js-cookie"; |
||||
import { pageRoutes, childrenRoutes, moduleRoutes } from '@/router/config' |
||||
import { |
||||
isURL |
||||
} from '@/utils/validate' |
||||
import baseUrl from '@/config' |
||||
Vue.use(Router) |
||||
|
||||
const router = new Router({ |
||||
mode: 'hash', |
||||
scrollBehavior: () => ({ |
||||
y: 0 |
||||
}), |
||||
routes: pageRoutes.concat(moduleRoutes) |
||||
}) |
||||
export function addDynamicRoute(routeParams, router) { |
||||
// 组装路由名称, 并判断是否已添加, 如是: 则直接跳转
|
||||
var routeName = routeParams.routeName |
||||
var dynamicRoute = window.SITE_CONFIG['dynamicRoutes'].filter(item => item.name === routeName)[0] |
||||
if (dynamicRoute) { |
||||
return router.push({ |
||||
name: routeName, |
||||
params: routeParams.params |
||||
}) |
||||
} |
||||
// 否则: 添加并全局变量保存, 再跳转
|
||||
dynamicRoute = { |
||||
path: routeName, |
||||
component: () => |
||||
import(`@/views/modules/${routeParams.path}`), |
||||
name: routeName, |
||||
meta: { |
||||
...window.SITE_CONFIG['contentTabDefault'], |
||||
menuId: routeParams.menuId, |
||||
title: `${routeParams.title}` |
||||
} |
||||
} |
||||
router.addRoutes([{ |
||||
...moduleRoutes, |
||||
name: `main-dynamic__${dynamicRoute.name}`, |
||||
children: [dynamicRoute] |
||||
}]) |
||||
window.SITE_CONFIG['dynamicRoutes'].push(dynamicRoute) |
||||
router.push({ |
||||
name: dynamicRoute.name, |
||||
params: routeParams.params |
||||
}) |
||||
} |
||||
|
||||
let appendRoutes = (dataList) => { |
||||
for (let i = 0; i < childrenRoutes.length; i++) { |
||||
concatRoutes(dataList, childrenRoutes[i]); |
||||
} |
||||
|
||||
return dataList; |
||||
} |
||||
|
||||
let concatRoutes = (parentList, appendNode) => { |
||||
for (let i = 0; i < parentList.length; i++) { |
||||
let value = parentList[i]; |
||||
|
||||
//向路由的每个结点追加isLastLevel属性,标识是否为最后一级导航结点,按配置到数据库中的算,页面上后append的,默认都是页面内部路由,不算
|
||||
if (value.children == null) { |
||||
value.children = []; |
||||
} |
||||
|
||||
if (value.isLastLevel == null || value.isLastLevel == false) { |
||||
value.isLastLevel = value.children.length == 0; |
||||
} |
||||
|
||||
//依据rootUrl寻找父级结点
|
||||
if (value.url && appendNode.rootUrl == value.url) { //找到了,为children赋值,结束循环
|
||||
value.children = value.children.concat(appendNode.children); |
||||
return; |
||||
} else { //没找到,递归
|
||||
concatRoutes(value.children, appendNode); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
router.beforeEach((to, from, next) => { |
||||
|
||||
var userId = getUrlKey("userId"); |
||||
var token = getUrlKey("token"); |
||||
var key = getUrlKey("key"); |
||||
if (userId && token) { |
||||
userId = userId.replace(/\ +/g, "+");//去掉空格
|
||||
userId = userId.replace(/[ ]/g, "+"); //去掉空格
|
||||
userId = userId.replace(/[\r\n]/g, "+");//去掉回车换行
|
||||
token = token.replace(/\ +/g, "+");//去掉空格
|
||||
token = token.replace(/[ ]/g, "+"); //去掉空格
|
||||
token = token.replace(/[\r\n]/g, "+");//去掉回车换行
|
||||
} |
||||
var deUserId = ""; |
||||
var deToken = ""; |
||||
console.log("userId", userId); |
||||
console.log("token", token); |
||||
console.log("key", key); |
||||
|
||||
if( Cookies.get('cookieFlag') != '1'){ |
||||
if (userId && token && key && Number("123" + getKey()) - Number("123" + key) < 600000) { |
||||
deUserId = Decrypt(userId, "123" + key, "123" + key); |
||||
deToken = Decrypt(token, "123" + key, "123" + key); |
||||
console.log("deUserId", deUserId); |
||||
console.log("deToken", deToken); |
||||
Cookies.set("token", deToken); |
||||
Cookies.set("userId", deUserId); |
||||
} else { |
||||
console.log("已经超时了"); |
||||
} |
||||
}else{ |
||||
Cookies.remove('cookieFlag'); |
||||
} |
||||
|
||||
if (to.name != "logout") { |
||||
// if (!Cookies.get("token") || !Cookies.get("userId")) {
|
||||
// window.location.replace(baseUrl.IDM_APPROVE_URL)
|
||||
// }
|
||||
} |
||||
// 添加动态(菜单)路由
|
||||
// 已添加或者当前路由为页面路由, 可直接访问
|
||||
if (window.SITE_CONFIG['dynamicMenuRoutesHasAdded'] || fnCurrentRouteIsPageRoute(to, pageRoutes)) { |
||||
return next() |
||||
} |
||||
// 获取菜单列表, 添加并全局变量保存
|
||||
http.get(baseUrl.JMPS_ADMIN_URL + '/sys/menu/nav').then(({ |
||||
data: res |
||||
}) => { |
||||
console.log("beforeEachbeforeEachbeforeEach"); |
||||
|
||||
if (res.code !== 0) { |
||||
Vue.prototype.$message({ |
||||
message: res.msg, |
||||
type: "error", |
||||
duration: 2000 |
||||
}); |
||||
return next({ |
||||
name: 'login' |
||||
}) |
||||
// window.location.replace(baseUrl.IDM_APPROVE_URL)
|
||||
} |
||||
window.SITE_CONFIG['menuList'] = appendRoutes(res.data); |
||||
fnAddDynamicMenuRoutes(window.SITE_CONFIG['menuList']) |
||||
next({ |
||||
...to, |
||||
replace: true |
||||
}) |
||||
}).catch(() => { |
||||
next({ |
||||
name: 'login' |
||||
}) |
||||
// window.location.replace(baseUrl.IDM_APPROVE_URL)
|
||||
}) |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}) |
||||
|
||||
/** |
||||
* 判断当前路由是否为页面路由 |
||||
* @param {*} route 当前路由 |
||||
* @param {*} pageRoutes 页面路由 |
||||
*/ |
||||
function fnCurrentRouteIsPageRoute(route, pageRoutes = []) { |
||||
var temp = [] |
||||
for (var i = 0; i < pageRoutes.length; i++) { |
||||
if (route.path === pageRoutes[i].path) { |
||||
return true |
||||
} |
||||
if (pageRoutes[i].children && pageRoutes[i].children.length >= 1) { |
||||
temp = temp.concat(pageRoutes[i].children) |
||||
} |
||||
} |
||||
return temp.length >= 1 ? fnCurrentRouteIsPageRoute(route, temp) : false |
||||
} |
||||
|
||||
const createRouteConfig = (menu) => { |
||||
// 组装路由
|
||||
var route = { |
||||
url: menu.url, |
||||
path: '', |
||||
component: null, |
||||
name: '', |
||||
meta: { |
||||
...window.SITE_CONFIG['contentTabDefault'], |
||||
menuId: menu.id, |
||||
title: menu.name |
||||
} |
||||
} |
||||
|
||||
if (menu.meta && menu.meta.isBreadcrumb) { |
||||
route.meta = { |
||||
...route.meta, |
||||
...menu.meta |
||||
} |
||||
} |
||||
|
||||
// eslint-disable-next-line
|
||||
let URL = (menu.url || '').replace(/{{([^}}]+)?}}/g, (s1, s2) => eval(s2)) // URL支持{{ window.xxx }}占位符变量
|
||||
if (isURL(URL)) { |
||||
route['path'] = route['name'] = `i-${menu.id}` |
||||
route['meta']['iframeURL'] = URL |
||||
} else { |
||||
URL = URL.replace(/^\//, '').replace(/_/g, '-') |
||||
route['path'] = route['name'] = URL.replace(/\//g, '-') |
||||
route['component'] = () => |
||||
import(`@/views/modules/${URL}`) |
||||
} |
||||
|
||||
if (menu.routeName && menu.routeName != "") { |
||||
route['name'] = menu.routeName; |
||||
} |
||||
|
||||
return route; |
||||
} |
||||
|
||||
/** |
||||
* 添加动态(菜单)路由 |
||||
* @param {*} menuList 菜单列表 |
||||
* @param {*} routes 递归创建的动态(菜单)路由 |
||||
*/ |
||||
function fnAddDynamicMenuRoutes(menuList = [], routes = []) { |
||||
var temp = [] |
||||
for (var i = 0; i < menuList.length; i++) { |
||||
|
||||
//逻辑需要,对于其下配置了children的结点,本身也要能够跳转
|
||||
if (menuList[i].url && menuList[i].children && menuList[i].children.length >= 1) { |
||||
routes.push(createRouteConfig(menuList[i])); |
||||
} |
||||
|
||||
if (menuList[i].children && menuList[i].children.length >= 1) { |
||||
temp = temp.concat(menuList[i].children) |
||||
continue |
||||
} |
||||
|
||||
routes.push(createRouteConfig(menuList[i])) |
||||
} |
||||
if (temp.length >= 1) { |
||||
return fnAddDynamicMenuRoutes(temp, routes) |
||||
} |
||||
// 添加路由
|
||||
router.addRoutes([{ |
||||
...moduleRoutes, |
||||
name: 'main-dynamic-menu', |
||||
children: routes |
||||
}, |
||||
{ |
||||
path: '*', |
||||
redirect: { |
||||
name: '404' |
||||
} |
||||
} |
||||
]) |
||||
window.SITE_CONFIG['dynamicMenuRoutes'] = routes |
||||
window.SITE_CONFIG['dynamicMenuRoutesHasAdded'] = true |
||||
|
||||
} |
||||
|
||||
|
||||
export default router |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,62 @@
|
||||
{ |
||||
"info": { |
||||
"_postman_id": "1c37d4fa-6ce7-4829-8a1e-9bc5151032ac", |
||||
"name": "jsd9880", |
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" |
||||
}, |
||||
"item": [ |
||||
{ |
||||
"name": "getToken", |
||||
"protocolProfileBehavior": { |
||||
"disabledSystemHeaders": { |
||||
"user-agent": true, |
||||
"accept": true |
||||
} |
||||
}, |
||||
"request": { |
||||
"method": "POST", |
||||
"header": [ |
||||
{ |
||||
"key": "Cookie", |
||||
"value": "cf_chl_2=8530a6541dd5d4a; cf_chl_prog=x20; cf_clearance=LAn7K16arymRPPFI9SJPfBGWpbln5vCCIZzBrTf_Ibc-1647589093-0-150", |
||||
"type": "text" |
||||
}, |
||||
{ |
||||
"key": "User-Agent", |
||||
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.39", |
||||
"type": "text" |
||||
}, |
||||
{ |
||||
"key": "accept", |
||||
"value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", |
||||
"type": "text" |
||||
} |
||||
], |
||||
"body": { |
||||
"mode": "urlencoded", |
||||
"urlencoded": [ |
||||
{ |
||||
"key": "accessToken", |
||||
"value": "eyJraWQiOiJJZG1Eb21haW4iLCJ4NXQiOiJ6dy1iN0phQlVPQjBrUEtzTlhyOWdHdi0tX3ciLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2lhbXVhdC5mYXdqaWVmYW5nLmNvbS5jbjo0NDMvb2F1dGgyIiwiYXVkIjpbIklkbVJlc1NlcnZlciIsIjE0NzI4MTlhMGNmOTQwYzI5NWY0Yjg0YjFjMDIzMWY1Il0sImV4cCI6MTY0ODEwNTMyMiwianRpIjoiVHFoWTJEcFBQQzdVMWRXbkdqQTBvUSIsImlhdCI6MTY0ODEwMTcyMiwic3ViIjoiMTAwMDQyNjIiLCJzZXNzaW9uSWQiOiIyYmYzYmM1Ny1hN2E5LTQyNjctOWZiZS0xZDU4YTEzYzAzNDN8c2V3dkE4U3F5b3pzNXpuTS9uV2x2a2R6YkNISFNveFpHREpyd3ZSVWhnZz0iLCJjdXN0b21lQXR0ciI6IkN1c3RvbVZhbHVlIiwicmVzU3J2QXR0ciI6IlJFU09VUkNFQ09OU1QiLCJjbGllbnQiOiIxNDcyODE5YTBjZjk0MGMyOTVmNGI4NGIxYzAyMzFmNSIsInNjb3BlIjpbIklkbVJlc1NlcnZlci5Vc2VyUHJvZmlsZS5tZSIsIm9wZW5pZCIsImVtYWlsIiwicGhvbmUiLCJwcm9maWxlIl0sImRvbWFpbiI6IklkbURvbWFpbiJ9.fvcih44HOKTCXEfCOVyxugUHJQDN_d8LqW4TDZX4E3tOaks5skh-JVVci8hOjppPAn6ue1-LWplb6WNxu3qQWsQQdQu6WyRsXsY-2TAqAkDoUs_eLr6FRZkzbjZPSLCq6fpcxTaBCpuWYrHyKCZnpSYw2sjrfcBKY22o4jus4FMxxUOrJowMdzY3CVzy9jqVeX0A0TWwWwgqdMaL6cCNuwnLnmUubs1aGHP-mUdlpNxKJnJlE9YAaRtdBsLaOMpHDgqUsl3EQcBy4R1pbMIiox0_61v433AjhuGIPbjsI-OGTxPJmesIuPi9IXvaB7vxxf0raeT73vBoJGF8kxB6Gw", |
||||
"type": "text" |
||||
} |
||||
] |
||||
}, |
||||
"url": { |
||||
"raw": "localhost:8075/webroot/decision/url/getToken", |
||||
"host": [ |
||||
"localhost" |
||||
], |
||||
"port": "8075", |
||||
"path": [ |
||||
"webroot", |
||||
"decision", |
||||
"url", |
||||
"getToken" |
||||
] |
||||
} |
||||
}, |
||||
"response": [] |
||||
} |
||||
] |
||||
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin> |
||||
<id>com.eco.plugin.xxxx.ijf.iam</id> |
||||
<name><![CDATA[IAM单点登录]]></name> |
||||
<active>yes</active> |
||||
<version>1.0.4</version> |
||||
<env-version>10.0</env-version> |
||||
<jartime>2020-07-31</jartime> |
||||
<vendor>fr.open</vendor> |
||||
<description><![CDATA[oauth2]]></description> |
||||
<change-notes><![CDATA[ |
||||
add 9880 |
||||
]]></change-notes> |
||||
<extra-decision> |
||||
<GlobalRequestFilterProvider class="com.fr.plugin.IAMloginFilter"/> |
||||
<!-- 长连接 --> |
||||
<HttpHandlerProvider class="com.fr.plugin.TCauth2HandlerProvider"/> |
||||
<!-- 短连接 --> |
||||
<URLAliasProvider class="com.fr.plugin.TCauth2URLAliasBridge"/> |
||||
</extra-decision> |
||||
<function-recorder class="com.fr.plugin.TCauth2HandlerProvider"/> |
||||
</plugin> |
@ -0,0 +1,120 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fanruan.api.net.http.HttpKit; |
||||
import com.fr.decision.authority.data.User; |
||||
import com.fr.decision.fun.impl.BaseHttpHandler; |
||||
import com.fr.decision.webservice.v10.login.LoginService; |
||||
import com.fr.decision.webservice.v10.user.UserService; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.plugin.context.PluginContexts; |
||||
import com.fr.third.org.apache.commons.codec.digest.DigestUtils; |
||||
import com.fr.third.org.apache.commons.lang3.StringUtils; |
||||
import com.fr.third.springframework.web.bind.annotation.RequestMethod; |
||||
import com.fr.web.utils.WebUtils; |
||||
import org.dom4j.DocumentException; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
import java.net.URLEncoder; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.Base64; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
public class GetTicket extends BaseHttpHandler { |
||||
@Override |
||||
public RequestMethod getMethod() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public String getPath() { |
||||
return "/getToken"; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isPublic() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { |
||||
JSONObject entries = new JSONObject(); |
||||
if (!PluginContexts.currentContext().isAvailable()) { |
||||
entries.put("code", "1"); |
||||
entries.put("msg", "授权过期请联系销售人员"); |
||||
WebUtils.printAsJSON(httpServletResponse, entries); |
||||
return; |
||||
} |
||||
String accessToken = WebUtils.getHTTPRequestParameter(httpServletRequest, "accessToken"); |
||||
if (StringUtils.isBlank(accessToken)) { |
||||
entries.put("code", "1"); |
||||
entries.put("msg", "accessToken码不存在"); |
||||
WebUtils.printAsJSON(httpServletResponse, entries); |
||||
return; |
||||
} |
||||
//第一步获取token
|
||||
// String accessToken = getAccessToken(code);
|
||||
// if (StringUtils.isBlank(accessToken)) {
|
||||
// entries.put("code", "1");
|
||||
// entries.put("msg", "授权码无效,请重新授权");
|
||||
// WebUtils.printAsJSON(httpServletResponse, entries);
|
||||
// return;
|
||||
// }
|
||||
String uid = getUserInfo(accessToken); |
||||
User user = UserService.getInstance().getUserByUserName(uid); |
||||
if (user == null) { |
||||
entries.put("code", "1"); |
||||
entries.put("msg", "登录失败:" + uid + " 在帆软用户体系不存在,请联系管理员添加"); |
||||
WebUtils.printAsJSON(httpServletResponse, entries); |
||||
return; |
||||
} |
||||
String token = login(httpServletRequest, httpServletResponse, uid); |
||||
entries.put("code", "0"); |
||||
entries.put("data", token); |
||||
WebUtils.printAsJSON(httpServletResponse, entries); |
||||
} |
||||
|
||||
private String getAccessToken(String code) throws IOException { |
||||
Oauth2Config config = Oauth2Config.getInstance(); |
||||
String valAddr = config.getValAddr(); |
||||
String appId = config.getAppId(); |
||||
String clientSecret = config.getClientSecret(); |
||||
String frUrl = Oauth2Config.getInstance().getFrUrl(); |
||||
String redirectUrl = String.format("%s/url/iam/authCallBack", frUrl); |
||||
Map<String, String> params = new HashMap<>(); |
||||
String tokenUrl = String.format("%s/oauth2/rest/token", valAddr); |
||||
params.put("redirect_uri", redirectUrl); |
||||
params.put("grant_type", "AUTHORIZATION_CODE"); |
||||
params.put("code", code); |
||||
Map<String, String> header = new HashMap<>(); |
||||
header.put("X-OAUTH-IDENTITY-DOMAIN-NAME", "IdmDomain"); |
||||
header.put("Authorization", "Basic " + Base64.getEncoder().encodeToString(String.format("%s:%s", appId, clientSecret).getBytes(StandardCharsets.UTF_8))); |
||||
String json = HttpKit.post(tokenUrl, params, "utf-8", "utf-8", header); |
||||
FineLoggerFactory.getLogger().info("获取AccessToken 请求返回:{}", json); |
||||
JSONObject obj = new JSONObject(json); |
||||
return obj.getString("access_token"); |
||||
} |
||||
|
||||
public static String getUserInfo(String accessToken) throws DocumentException, IOException { |
||||
Map<String, String> header = new HashMap<>(); |
||||
Oauth2Config config = Oauth2Config.getInstance(); |
||||
String valAddr = config.getValAddr(); |
||||
String url = String.format("%s/oauth2/rest/userinfo?access_token=%s", valAddr, accessToken); |
||||
header.put("Authorization", "Bearer " + accessToken); |
||||
String json = HttpKit.get(url, new HashMap<>(), header); |
||||
FineLoggerFactory.getLogger().info("获取userinfo 请求返回:{}", json); |
||||
JSONObject obj = new JSONObject(json); |
||||
return obj.getString("sub"); |
||||
} |
||||
|
||||
private String login(HttpServletRequest req, HttpServletResponse res, String username) throws Exception { |
||||
String token = LoginService.getInstance().login(req, res, username); |
||||
req.setAttribute("fine_auth_token", token); |
||||
FineLoggerFactory.getLogger().info("fr FrFilter is over with username is ###" + username); |
||||
return token; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,63 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.decision.fun.impl.BaseHttpHandler; |
||||
import com.fr.decision.webservice.v10.login.LoginService; |
||||
import com.fr.third.org.apache.commons.codec.digest.DigestUtils; |
||||
import com.fr.third.org.apache.commons.lang3.StringUtils; |
||||
import com.fr.third.springframework.web.bind.annotation.RequestMethod; |
||||
import com.fr.web.utils.WebUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
import java.net.URLEncoder; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
public class GoAuthApi extends BaseHttpHandler { |
||||
@Override |
||||
public RequestMethod getMethod() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public String getPath() { |
||||
return "/goAuth"; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isPublic() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { |
||||
if (isLogin(httpServletRequest)) { |
||||
sendRedirect(httpServletResponse, HttpUtils.getDefaultUrl(httpServletRequest)); |
||||
return; |
||||
} else { |
||||
String valAddr = Oauth2Config.getInstance().getValAddr(); |
||||
String appId = Oauth2Config.getInstance().getAppId(); |
||||
String frUrl = Oauth2Config.getInstance().getFrUrl(); |
||||
String redirectUrl = String.format("%s/url/iam/authCallBack", frUrl); |
||||
redirectUrl = URLEncoder.encode(redirectUrl, "utf-8"); |
||||
String goUrl = String.format("%s/oauth2/rest/authz?response_type=code&client_id=%s&domain=IdmDomain&state=xyz&scope=IdmResServer.UserProfile.me openid email phone profile&redirect_uri=%s", valAddr, appId, redirectUrl); |
||||
sendRedirect(httpServletResponse, goUrl); |
||||
} |
||||
} |
||||
|
||||
|
||||
private void sendRedirect(HttpServletResponse res, String url) throws IOException { |
||||
Map<String, String> params = new HashMap<>(); |
||||
params.put("callBack", url); |
||||
WebUtils.writeOutTemplate("com/fr/plugin/redirect.html", res, params); |
||||
} |
||||
|
||||
private boolean isLogin(HttpServletRequest req) { |
||||
return LoginService.getInstance().isLogged(req); |
||||
} |
||||
|
||||
private String md5(String str) { |
||||
return DigestUtils.md5Hex(str); |
||||
} |
||||
} |
@ -0,0 +1,52 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.base.FRContext; |
||||
import com.fr.base.ServerConfig; |
||||
import com.fr.base.TemplateUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.third.org.apache.commons.io.IOUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import java.io.*; |
||||
import java.net.HttpURLConnection; |
||||
import java.net.URL; |
||||
import java.net.URLEncoder; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.Base64; |
||||
import java.util.Iterator; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* http请求工具类 |
||||
* |
||||
* @author 0246 |
||||
*/ |
||||
public class HttpUtils { |
||||
|
||||
|
||||
|
||||
/** |
||||
* 返回当前系统的根路径 |
||||
* |
||||
* @return |
||||
*/ |
||||
public static String getDefaultUrl(HttpServletRequest req) { |
||||
StringBuilder url = new StringBuilder(); |
||||
try { |
||||
url.append(req.getScheme()); |
||||
url.append("://"); |
||||
url.append(req.getServerName()); |
||||
if (req.getServerPort() != 80) { |
||||
url.append(":"); |
||||
url.append(req.getServerPort()); |
||||
} |
||||
url.append(TemplateUtils.render("${fineServletURL}")); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
return url.toString(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,166 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.base.ServerConfig; |
||||
import com.fr.base.TemplateUtils; |
||||
import com.fr.data.NetworkHelper; |
||||
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; |
||||
import com.fr.decision.webservice.utils.DecisionStatusService; |
||||
import com.fr.decision.webservice.v10.login.LoginService; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.plugin.transform.ExecuteFunctionRecord; |
||||
import com.fr.plugin.transform.FunctionRecorder; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.store.StateHubService; |
||||
import com.fr.web.utils.WebUtils; |
||||
|
||||
import javax.servlet.FilterChain; |
||||
import javax.servlet.FilterConfig; |
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
import java.io.PrintWriter; |
||||
import java.io.StringWriter; |
||||
import java.net.URLEncoder; |
||||
import java.util.Iterator; |
||||
import java.util.Map; |
||||
|
||||
@FunctionRecorder(localeKey = "fds") |
||||
public class IAMloginFilter extends AbstractGlobalRequestFilterProvider { |
||||
@Override |
||||
public String filterName() { |
||||
return "oauth2"; |
||||
} |
||||
|
||||
@Override |
||||
public String[] urlPatterns() { |
||||
return new String[]{ |
||||
"/*" |
||||
}; |
||||
} |
||||
|
||||
@Override |
||||
public void init(FilterConfig filterConfig) { |
||||
Oauth2Config.getInstance(); |
||||
super.init(filterConfig); |
||||
} |
||||
|
||||
@Override |
||||
@ExecuteFunctionRecord |
||||
public void doFilter(HttpServletRequest request, HttpServletResponse httpServletResponse, FilterChain filterChain) { |
||||
try { |
||||
if (isLogOut(request)) { |
||||
delLoginOut(request, httpServletResponse); |
||||
return; |
||||
} |
||||
if (needFilter(request) && !isLogin(request)) { |
||||
//跳转到登录界面
|
||||
String originalURL =getOriginalUrlIgnoreCode(request); |
||||
String frUrl = Oauth2Config.getInstance().getFrUrl(); |
||||
String valAddr = Oauth2Config.getInstance().getValAddr(); |
||||
String appId = Oauth2Config.getInstance().getAppId(); |
||||
StateHubService stateHubService = DecisionStatusService.originUrlStatusService(); |
||||
stateHubService.put("loginCallBack", originalURL); |
||||
String redirectUrl = String.format("%s/url/iam/authCallBack", frUrl); |
||||
redirectUrl = URLEncoder.encode(redirectUrl, "utf-8"); |
||||
String goUrl = String.format("%s/oauth2/rest/authz?response_type=code&client_id=%s&domain=IdmDomain&state=xyz&scope=IdmResServer.UserProfile.me openid email phone profile&redirect_uri=%s", valAddr, appId, redirectUrl); |
||||
sendRedirect(httpServletResponse, goUrl); |
||||
return; |
||||
} |
||||
filterChain.doFilter(request, httpServletResponse); |
||||
} catch (IOException | ServletException e) { |
||||
printException2FrLog(e); |
||||
} catch (Exception e) { |
||||
printException2FrLog(e); |
||||
} |
||||
} |
||||
|
||||
public String getOriginalUrlIgnoreCode(HttpServletRequest request) throws Exception { |
||||
StringBuffer url = new StringBuffer(request.getRequestURI()); |
||||
Map parameterMap = request.getParameterMap(); |
||||
Iterator iterator = parameterMap.entrySet().iterator(); |
||||
boolean notFirst = url.toString().indexOf("?") == -1; |
||||
while (iterator.hasNext()) { |
||||
Map.Entry entry = (Map.Entry) iterator.next(); |
||||
if (StringUtils.equals("code", entry.getKey().toString())) { |
||||
continue; |
||||
} |
||||
if (notFirst) { |
||||
url.append('?'); |
||||
notFirst = false; |
||||
} else { |
||||
url.append('&'); |
||||
} |
||||
|
||||
url.append(entry.getKey().toString()); |
||||
url.append('='); |
||||
url.append( URLEncoder.encode(request.getParameter(entry.getKey().toString()),"utf-8")); |
||||
} |
||||
FineLoggerFactory.getLogger().info("重定向到:" + url.toString()); |
||||
return url.toString(); |
||||
} |
||||
|
||||
private void delLoginOut(HttpServletRequest req, HttpServletResponse res) { |
||||
try { |
||||
//执行帆软内部的退出
|
||||
LoginService.getInstance().logout(req, res); |
||||
Oauth2Config oauth2Config = Oauth2Config.getInstance(); |
||||
JSONObject jsonObject = new JSONObject(); |
||||
String url = String.format("%s/xxxx/ssoLoginService/goLogout", oauth2Config.getValAddr()); |
||||
jsonObject.put("data", url); |
||||
//调用外部接口注销accessToken
|
||||
FineLoggerFactory.getLogger().error("登出成功: ----------------"); |
||||
//指定退出之后到他们登录页面
|
||||
WebUtils.printAsJSON(res, jsonObject); |
||||
} catch (Exception var4) { |
||||
} |
||||
} |
||||
|
||||
private boolean isLogOut(HttpServletRequest req) { |
||||
String url = WebUtils.getOriginalURL(req); |
||||
String servletNamePrefix = "/" + ServerConfig.getInstance().getServletName() + "/logout"; |
||||
return url.contains(servletNamePrefix) && req.getMethod().equals("POST"); |
||||
} |
||||
|
||||
private void sendRedirect(HttpServletResponse res, String url) { |
||||
res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); |
||||
res.setHeader("Location", url); |
||||
} |
||||
|
||||
private boolean needFilter(HttpServletRequest request) { |
||||
String requestURI = request.getRequestURI(); |
||||
String isAdmin = request.getParameter("isAdmin"); |
||||
if (StringUtils.equals(isAdmin, "1")) { |
||||
return false; |
||||
} |
||||
if (StringUtils.isNotBlank(requestURI) && request.getMethod().equals("GET")) { |
||||
if (requestURI.endsWith("decision")) { |
||||
return true; |
||||
} |
||||
if (requestURI.endsWith("/view/form") || requestURI.endsWith("/view/report")) { |
||||
if (StringUtils.isNotBlank(request.getParameter("viewlet"))) { |
||||
return true; |
||||
} |
||||
} |
||||
if (requestURI.contains("/v10/entry/access/") && request.getMethod().equals("GET")) { |
||||
return true; |
||||
} |
||||
if (requestURI.contains("/v5/design/report") && (requestURI.endsWith("/edit") || requestURI.endsWith("/view"))) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public static void printException2FrLog(Throwable e) { |
||||
StringWriter writer = new StringWriter(); |
||||
e.printStackTrace(new PrintWriter(writer)); |
||||
String s = writer.toString(); |
||||
FineLoggerFactory.getLogger().error("错误:{}", s); |
||||
} |
||||
|
||||
private boolean isLogin(HttpServletRequest req) { |
||||
return LoginService.getInstance().isLogged(req); |
||||
} |
||||
} |
@ -0,0 +1,70 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.config.*; |
||||
import com.fr.config.holder.Conf; |
||||
import com.fr.config.holder.factory.Holders; |
||||
|
||||
@Visualization(category = "IAM单点登录配置") |
||||
public class Oauth2Config extends DefaultConfiguration { |
||||
|
||||
private static volatile Oauth2Config config = null; |
||||
|
||||
public static Oauth2Config getInstance() { |
||||
if (config == null) { |
||||
config = ConfigContext.getConfigInstance(Oauth2Config.class); |
||||
} |
||||
return config; |
||||
} |
||||
|
||||
@Identifier(value = "valAddr", name = "接口地址", description = "接口地址", status = Status.SHOW) |
||||
private Conf<String> valAddr = Holders.simple(""); |
||||
@Identifier(value = "frUrl", name = "报表地址", description = "报表地址", status = Status.SHOW) |
||||
private Conf<String> frUrl = Holders.simple("http://localhost:8075/webroot/decision"); |
||||
@Identifier(value = "appId", name = "clientId", description = "clientId", status = Status.SHOW) |
||||
private Conf<String> appId = Holders.simple(""); |
||||
@Identifier(value = "clientSecret", name = "clientSecret", description = "clientSecret", status = Status.SHOW) |
||||
private Conf<String> clientSecret = Holders.simple(""); |
||||
|
||||
public String getFrUrl() { |
||||
return frUrl.get(); |
||||
} |
||||
|
||||
public void setFrUrl(String frUrl) { |
||||
this.frUrl.set(frUrl); |
||||
} |
||||
|
||||
public String getAppId() { |
||||
return appId.get(); |
||||
} |
||||
|
||||
public void setAppId(String appId) { |
||||
this.appId.set(appId); |
||||
} |
||||
|
||||
public String getClientSecret() { |
||||
return clientSecret.get(); |
||||
} |
||||
|
||||
public void setClientSecret(String clientSecret) { |
||||
this.clientSecret.set(clientSecret); |
||||
} |
||||
|
||||
public String getValAddr() { |
||||
return valAddr.get(); |
||||
} |
||||
|
||||
public void setValAddr(String valAddr) { |
||||
this.valAddr.set(valAddr); |
||||
} |
||||
|
||||
@Override |
||||
public Object clone() throws CloneNotSupportedException { |
||||
Oauth2Config cloned = (Oauth2Config) super.clone(); |
||||
cloned.valAddr = (Conf<String>) valAddr.clone(); |
||||
cloned.appId = (Conf<String>) appId.clone(); |
||||
cloned.clientSecret = (Conf<String>) clientSecret.clone(); |
||||
cloned.frUrl = (Conf<String>) frUrl.clone(); |
||||
return cloned; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,122 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fanruan.api.net.http.HttpKit; |
||||
import com.fr.decision.authority.data.User; |
||||
import com.fr.decision.fun.impl.BaseHttpHandler; |
||||
import com.fr.decision.webservice.utils.DecisionStatusService; |
||||
import com.fr.decision.webservice.v10.login.LoginService; |
||||
import com.fr.decision.webservice.v10.user.UserService; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.store.StateHubService; |
||||
import com.fr.third.jodd.util.StringUtil; |
||||
import com.fr.third.org.apache.commons.lang3.StringUtils; |
||||
import com.fr.third.springframework.web.bind.annotation.RequestMethod; |
||||
import com.fr.web.utils.WebUtils; |
||||
import org.dom4j.Document; |
||||
import org.dom4j.DocumentException; |
||||
import org.dom4j.DocumentHelper; |
||||
import org.dom4j.Element; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.Base64; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
public class TCAuthCallbackApi extends BaseHttpHandler { |
||||
@Override |
||||
public RequestMethod getMethod() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public String getPath() { |
||||
return "/authCallBack"; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isPublic() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { |
||||
String code = WebUtils.getHTTPRequestParameter(httpServletRequest, "code"); |
||||
if (StringUtils.isBlank(code)) { |
||||
WebUtils.printAsString(httpServletResponse, "code授权码不存在"); |
||||
return; |
||||
} |
||||
//第一步获取token
|
||||
|
||||
String accessToken = getAccessToken(code); |
||||
if (StringUtils.isBlank(accessToken)) { |
||||
WebUtils.printAsString(httpServletResponse, "授权码无效,请重新授权"); |
||||
return; |
||||
} |
||||
String uid = getUserInfo(accessToken); |
||||
User user = UserService.getInstance().getUserByUserName(uid); |
||||
if (user == null) { |
||||
WebUtils.printAsString(httpServletResponse, "登录失败:" + uid + " 在帆软用户体系不存在,请联系管理员添加"); |
||||
return; |
||||
} |
||||
login(httpServletRequest, httpServletResponse, uid); |
||||
StateHubService stateHubService = DecisionStatusService.originUrlStatusService(); |
||||
Object callback = stateHubService.get("loginCallBack"); |
||||
if (callback != null) { |
||||
sendRedirect(httpServletResponse, callback.toString()); |
||||
return; |
||||
} |
||||
sendRedirect(httpServletResponse, HttpUtils.getDefaultUrl(httpServletRequest)); |
||||
} |
||||
|
||||
private String getAccessToken(String code) throws IOException { |
||||
Oauth2Config config = Oauth2Config.getInstance(); |
||||
String valAddr = config.getValAddr(); |
||||
String appId = config.getAppId(); |
||||
String clientSecret = config.getClientSecret(); |
||||
String frUrl = Oauth2Config.getInstance().getFrUrl(); |
||||
String redirectUrl = String.format("%s/url/iam/authCallBack", frUrl); |
||||
Map<String, String> params = new HashMap<>(); |
||||
String tokenUrl = String.format("%s/oauth2/rest/token", valAddr); |
||||
params.put("redirect_uri", redirectUrl); |
||||
params.put("grant_type", "AUTHORIZATION_CODE"); |
||||
params.put("code", code); |
||||
Map<String, String> header = new HashMap<>(); |
||||
header.put("X-OAUTH-IDENTITY-DOMAIN-NAME", "IdmDomain"); |
||||
header.put("Authorization", "Basic " + Base64.getEncoder().encodeToString(String.format("%s:%s", appId, clientSecret).getBytes(StandardCharsets.UTF_8))); |
||||
String json = HttpKit.post(tokenUrl, params, "utf-8", "utf-8", header); |
||||
FineLoggerFactory.getLogger().info("获取AccessToken 请求返回:{}", json); |
||||
JSONObject obj = new JSONObject(json); |
||||
return obj.getString("access_token"); |
||||
} |
||||
|
||||
public static String getUserInfo(String accessToken) throws DocumentException, IOException { |
||||
Map<String, String> header = new HashMap<>(); |
||||
Oauth2Config config = Oauth2Config.getInstance(); |
||||
String valAddr = config.getValAddr(); |
||||
String url = String.format("%s/oauth2/rest/userinfo?access_token=%s", valAddr, accessToken); |
||||
header.put("Authorization", "Bearer " + accessToken); |
||||
String json = HttpKit.get(url, new HashMap<>(), header); |
||||
FineLoggerFactory.getLogger().info("获取userinfo 请求返回:{}", json); |
||||
JSONObject obj = new JSONObject(json); |
||||
return obj.getString("sub"); |
||||
} |
||||
|
||||
|
||||
private String login(HttpServletRequest req, HttpServletResponse res, String username) throws Exception { |
||||
String token = LoginService.getInstance().login(req, res, username); |
||||
req.setAttribute("fine_auth_token", token); |
||||
FineLoggerFactory.getLogger().info("fr FrFilter is over with username is ###" + username); |
||||
return token; |
||||
} |
||||
|
||||
private void sendRedirect(HttpServletResponse res, String url) throws IOException { |
||||
Map<String, String> params = new HashMap<>(); |
||||
params.put("callBack", url); |
||||
WebUtils.writeOutTemplate("com/fr/plugin/redirect.html", res, params); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,25 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.decision.fun.HttpHandler; |
||||
import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; |
||||
import com.fr.plugin.transform.ExecuteFunctionRecord; |
||||
import com.fr.plugin.transform.FunctionRecorder; |
||||
import com.fr.stable.fun.Authorize; |
||||
|
||||
@FunctionRecorder |
||||
/** |
||||
* url处理器需要在这里注册 |
||||
*/ |
||||
@Authorize |
||||
public class TCauth2HandlerProvider extends AbstractHttpHandlerProvider { |
||||
@Override |
||||
@ExecuteFunctionRecord |
||||
public HttpHandler[] registerHandlers() { |
||||
return new HttpHandler[]{ |
||||
new GoAuthApi(), |
||||
new GetTicket(), |
||||
new TCAuthCallbackApi() |
||||
}; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,27 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.decision.fun.impl.AbstractURLAliasProvider; |
||||
import com.fr.decision.webservice.url.alias.URLAlias; |
||||
import com.fr.decision.webservice.url.alias.URLAliasFactory; |
||||
|
||||
/** |
||||
* 将长连接转换为短连接 |
||||
* 参考文档: |
||||
* https://wiki.fanruan.com/display/PD/com.fr.decision.fun.URLAliasProvider
|
||||
*/ |
||||
public class TCauth2URLAliasBridge extends AbstractURLAliasProvider |
||||
{ |
||||
public TCauth2URLAliasBridge() { |
||||
Oauth2Config.getInstance(); |
||||
} |
||||
|
||||
@Override |
||||
public URLAlias[] registerAlias() { |
||||
//像这样配置之后再访问/api就可以通过http(s)://ip:port/webroot/decision/url/api。 进行访问
|
||||
return new URLAlias[]{ |
||||
URLAliasFactory.createPluginAlias("/goAuth", "/goAuth", true), |
||||
URLAliasFactory.createPluginAlias("/getToken", "/getToken", true), |
||||
URLAliasFactory.createPluginAlias("/iam/authCallBack", "/authCallBack", true), |
||||
}; |
||||
} |
||||
} |
Loading…
Reference in new issue