Browse Source

提交开源任务材料

10.0
LAPTOP-SB56SG4Q\86185 3 years ago
parent
commit
373b8c4a23
  1. BIN
      JSD-7492 -需求确认书V1.docx
  2. 5
      README.md
  3. 16
      plugin.xml
  4. 9
      readme.txt
  5. 204
      src/main/java/com/fr/plugin/ctfo/sso/Oauth2Filter.java
  6. 5
      src/main/resources/xplatform.properties
  7. 5
      xplatform.properties

BIN
JSD-7492 -需求确认书V1.docx

Binary file not shown.

5
README.md

@ -1,3 +1,6 @@
# open-JSD-7942
JSD-7942 开源任务材料
JSD-7942 开源任务材料\
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
仅作为开发者学习参考使用!禁止用于任何商业用途!\
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。

16
plugin.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plugin>
<id>com.fr.plugin.ctfo.sso</id>
<name><![CDATA[oauth2单点登录]]></name>
<active>yes</active>
<version>1.2</version>
<env-version>10.0</env-version>
<jartime>2018-07-31</jartime>
<vendor>fr.open</vendor>
<description><![CDATA[oauth2单点登录]]></description>
<change-notes><![CDATA[]]></change-notes>
<extra-decision>
<GlobalRequestFilterProvider class="com.fr.plugin.ctfo.sso.Oauth2Filter"/>
</extra-decision>
<function-recorder class="com.fr.plugin.ctfo.sso.Oauth2Filter"/>
</plugin>

9
readme.txt

@ -0,0 +1,9 @@
此次完成功能如下
a、单点登录
1、将压缩文件解压后的xplatform.properties配置文件拷贝至 %部署路径%/WEB-INF/resources, 并修改对应配置
2、安装本插件,插件安装见连接http://help.finereport.com/doc-view-2198.html
3、进入系统测试单点登录,访问地址为http://ip:port/webroot/decision

204
src/main/java/com/fr/plugin/ctfo/sso/Oauth2Filter.java

@ -0,0 +1,204 @@
package com.fr.plugin.ctfo.sso;
import com.fr.base.PropertiesUtils;
import com.fr.common.util.Assert;
import com.fr.data.NetworkHelper;
import com.fr.decision.authority.data.User;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.decision.mobile.terminal.TerminalHandler;
import com.fr.decision.webservice.utils.DecisionServiceConstants;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.decision.webservice.v10.login.TokenResource;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.general.http.HttpToolbox;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.stable.StringUtils;
import com.fr.stable.web.Device;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.Instant;
import java.util.Collections;
import java.util.Properties;
import java.util.stream.Stream;
/**
* @author fr.open
* @since 2021/5/25
*/
@FunctionRecorder
public class Oauth2Filter extends AbstractGlobalRequestFilterProvider {
private static final String[] NOT_FILTER = {
"/decision/file",
"/decision/resources",
"/system",
"/materials.min.js.map",
"/remote",
"/login",
"/login/config",
};
private final String apiAuthorize;
private final String apiAppKey;
private final String apiAppSecret;
private final String apiGetToken;
private final String apiGetUser;
public Oauth2Filter() {
Properties props = PropertiesUtils.getProperties("xplatform");
apiAuthorize = getValue(props, "api.authorize");
apiAppKey = getValue(props, "api.app-key");
apiAppSecret = getValue(props, "api.app-secret");
apiGetToken = getValue(props, "api.get-token");
apiGetUser = getValue(props, "api.get-user");
}
private String getValue(Properties props, String key) {
String value = props.getProperty(key);
Assert.hasText(value, "配置项[" + key + "]不能为空");
return value;
}
@Override
public String filterName() {
return "ctfoOauth2";
}
@Override
public String[] urlPatterns() {
return new String[]{"/*"};
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
final String url = request.getRequestURL().toString();
FineLoggerFactory.getLogger().info("sso >> URL of this request => {}", url);
try {
if (isLogin(request) || Stream.of(NOT_FILTER).anyMatch(url::contains)) {
FineLoggerFactory.getLogger().info("sso >> 已登录或默认可放行的请求地址");
chain.doFilter(request, response);
return;
}
String code = request.getParameter("code");
if (StringUtils.isBlank(code)) {
FineLoggerFactory.getLogger().info("sso >> Parameter['code'] 值为空, 跳转到登录页");
toAuthorize(request, response);
return;
}
FineLoggerFactory.getLogger().info("sso >> Parameter['code'] => [{}]", code);
String token;
try {
token = getAccessToken(request, code);
} catch (Exception e) {
FineLoggerFactory.getLogger().error("sso >> 获取access token失败", e);
chain.doFilter(request, response);
return;
}
FineLoggerFactory.getLogger().info("sso >> AccessToken => [{}]", token);
String username;
try {
username = getUsername(token);
} catch (Exception e) {
FineLoggerFactory.getLogger().error("sso >> 获取用户名失败", e);
chain.doFilter(request, response);
return;
}
FineLoggerFactory.getLogger().info("sso >> username => [{}]", token);
login(username, request, response);
chain.doFilter(request, response);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void toAuthorize(HttpServletRequest request, HttpServletResponse response) throws IOException {
String urlPattern = "%s?response_type=code&client_id=%s&redirect_uri=%s&oauth_timestamp=%s";
String rURI = request.getRequestURL().toString();
// if (request.getQueryString() != null) {
// rURI += "?" + request.getQueryString();
// }
rURI = URLEncoder.encode(rURI, "utf-8");
String url = String.format(urlPattern, apiAuthorize, apiAppKey, rURI, Instant.now().toEpochMilli());
FineLoggerFactory.getLogger().info("sso >> 登录认证地址 => [{}]", url);
response.sendRedirect(url);
}
private String getAccessToken(HttpServletRequest request, String code) throws IOException, IllegalAccessException {
String api = "%s?grant_type=authorization_code&oauth_timestamp=%s&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s";
String rURI = request.getRequestURL().toString();
rURI = URLEncoder.encode(rURI, "utf-8");
// if (request.getQueryString() != null) {
// rURI += "?" + request.getQueryString();
// }
api = String.format(api, apiGetToken, Instant.now().toEpochMilli(), apiAppKey, apiAppSecret, code, rURI);
FineLoggerFactory.getLogger().info("sso >> CODE换取AccessToken的接口地址 => [{}]", api);
String response = HttpToolbox.post(api, Collections.emptyMap());
FineLoggerFactory.getLogger().info("sso >> CODE换取AccessToken的接口返回内容 => [{}]", response);
JSONObject res = new JSONObject(response);
if (res.has("access_token") && StringUtils.isNotBlank(res.getString("access_token"))) {
return res.getString("access_token");
}
throw new IllegalAccessException();
}
private String getUsername(String token) throws IOException, IllegalAccessException {
String api = String.format("%s?access_token=%s", apiGetUser, token);
FineLoggerFactory.getLogger().info("sso >> 获取用户信息接口地址 => [{}]", api);
String response = HttpToolbox.get(api);
FineLoggerFactory.getLogger().info("sso >> 获取用户信息接口地址返回内容 => [{}]", response);
JSONObject res = new JSONObject(response);
if (res.has("attributes")) {
JSONObject attrs = res.getJSONObject("attributes");
if (attrs.has("account_no") && StringUtils.isNotBlank(attrs.getString("account_no"))) {
return attrs.getString("account_no");
}
}
throw new IllegalAccessException();
}
private void login(String username, HttpServletRequest request, HttpServletResponse response) {
try {
User user = UserService.getInstance().getUserByUserName(username);
if (user == null) {
FineLoggerFactory.getLogger().error("sso >> User \"{}\" does not exist", username);
return;
}
FineLoggerFactory.getLogger().info("sso >> Getted user: {}", user);
String token = LoginService.getInstance().login(request, response, username);
FineLoggerFactory.getLogger().info("sso >> Getted login token: {}", token);
request.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token);
FineLoggerFactory.getLogger().info("sso >> User[{}] login successfully", username);
} catch (Exception e) {
FineLoggerFactory.getLogger().error("sso >> Failed to login with[" + username + "]", e);
}
}
private boolean isLogin(HttpServletRequest request) {
String oldToken = TokenResource.COOKIE.getToken(request);
return oldToken != null && checkTokenValid(request, (String) oldToken);
}
private boolean checkTokenValid(HttpServletRequest req, String token) {
try {
Device device = NetworkHelper.getDevice(req);
LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device));
return true;
} catch (Exception ignore) {
}
return false;
}
}

5
src/main/resources/xplatform.properties

@ -0,0 +1,5 @@
api.app-key=1238912731982
api.app-secret=1293102832190380
api.authorize=http://114.242.227.113:10000/login/esc-sso/oauth2.0/authorize
api.get-token=http://114.242.227.113:10000/login/esc-sso/oauth2.0/accessToken
api.get-user=http://114.242.227.113:10000/login/esc-sso/oauth2.0/profile

5
xplatform.properties

@ -0,0 +1,5 @@
api.app-key=
api.app-secret=
api.authorize=xxx/oauth2.0/authorize
api.get-token=xxx/oauth2.0/accessToken
api.get-user=xxxo/oauth2.0/profile
Loading…
Cancel
Save