OAuth单点登录
- 文档创建者:doreen0813
- 编辑次数:11次
- 最近更新:Roxy 于 2020-04-09
1. 概述
1.1 版本
FineBI 版本 |
---|
5.1 |
1.2 问题描述
使用 OAuth 服务器作为统一登录,集成 FineBI 系统,需要实现登录了 OAuth 后就可以直接访问平台, 不再需要平台登录。
1.3 解决思路
以 OAuth 授权码模式为例,流程如下:
1.3.1 获取 code
1)OAuth 服务器端注册了单点客户端的信息,包括 client_id, client_secret, redirect_uri(可选), logout_uri(可选)
2)问 OAuth 认证地址请求(简称 oauthAuthorizeUrl ),得到一个 code 。
请求参数( queryString 型参数):
参数名 | 解释 |
---|---|
client_id | 注册的客户端 ID |
redirect_uri | 回调地址 |
response_type | 固定值 code |
最后重定向到 redirect_uri,并带上参数 code
1.3.2 获取 access_token
1)带上参数 code 访问 OAuth 获取accessToken的请求(简称 oauthTokenUrl),获取 access_token 。
请求类型:POST
请求参数( queryString 型参数):
参数名 | 解释 |
---|---|
client_id | 注册的客户端 ID |
redirect_uri | 回调地址 |
grant_type | authorization_code |
client_secret | 可选 |
code | 上步骤的 code |
返回值:{access_token: ""}
2)(可选)access_token可能有效期较短,可以使用刷新 token 接口进行刷新。
1.3.3 获取登录用户信息
1)使用 access_token 获取登录的用户信息
请求类型:GET
请求参数(queryString 型参数):
参数名 | 解释 |
---|---|
client_id | 注册的客户端 ID |
access_token |
1.3.4 登录
根据此用户名去调用平台的后台登录方法进行登录。
2. 示例
2.1 操作步骤
2.1.1 文件准备
点击下载所需文件:OAuth.zip
2.1.2 放置 class 文件
将编译好的两个 class 文件:FrOauthFilter 和 FrOauthFilter$OauthLoginInfo 置于%FineBI%/webapps/webroot/WEB_INF/classes/com/fr目录下,如下图所示:
FrOauthFilter 文件源码如下所示:
package com.fr;
import com.fr.base.TemplateUtils;
import com.fr.data.NetworkHelper;
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.general.http.HttpToolbox;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.stable.web.Device;
import com.fr.store.StateHubManager;
import com.fr.store.StateHubService;
import com.fr.third.springframework.web.util.WebUtils;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: Elijah
* @Create: 2019-07-10
* @Desciption:
*/
public class FrOauthFilter implements Filter {
private static final StateHubService OAUTH_SERVICE = StateHubManager.applyForService("oauth");
private static final String COOKIE_AUTH = "oauth_access_token";
private static final int TIME = 3600000 * 24;
private String oauthTokenUrl; /** oauth获取accessToken地址,无需包括请求参数*/
private String oauthUserInfoUrl; /** oauth获取用户信息地址*/
private String oauthUserName = "username"; /**oauth获取用户信息接口返回值中的用户名字段*/
private String redirectUrl; /** 需要重定向回来的地址,一般就是工程地址*/
private String oauthClientId; /** oauth注册的客户端id*/
private String oauthClientSecret; /** oauth注册的客户端秘钥*/
private String oauthAuthorizeUrl; /** oauth认证地址,无需包括请求参数*/
private List<String> oauthExcludeUrl = new ArrayList<String>();
private String decisionRoot;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.oauthTokenUrl= filterConfig.getInitParameter("oauthTokenUrl");
this.oauthUserInfoUrl = filterConfig.getInitParameter("oauthUserInfoUrl");
this.redirectUrl = filterConfig.getInitParameter("redirectUrl");
this.oauthClientId = filterConfig.getInitParameter("oauthClientId");
this.oauthClientSecret = filterConfig.getInitParameter("oauthClientSecret");
this.oauthAuthorizeUrl = filterConfig.getInitParameter("oauthAuthorizeUrl");
this.oauthUserName = filterConfig.getInitParameter("oauthUserName") != null ? filterConfig.getInitParameter("oauthUserName") : oauthUserName;
String excludeUrls = filterConfig.getInitParameter("oauthExcludeUrl");
String[] array = excludeUrls.split(",");
for (String s: array) {
oauthExcludeUrl.add(filterConfig.getServletContext().getContextPath() + s.trim());
}
try {
this.decisionRoot = TemplateUtils.render(DecisionServiceConstants.MAIN_PAGE_URL);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
OauthLoginInfo loginInfo = getCurrentUser(request);
if (excludeUrl(request)) {
filterChain.doFilter(request, response);
return;
}
if (loginInfo != null ) {
/**如果oauth已经登录, 即已经存在本地会话,则刷新平台token*/
refreshDecisionToken(request, response, loginInfo);
filterChain.doFilter(request, response);
} else {
/**如果oauth没有登录,则判断是否携带oauth的code*/
String code = getCode(request);
if ( code != null) {
doOauth(request, response, filterChain, code);
}else {
/**直接重定向到oauth认证地址*/
response.sendRedirect(oauthAuthorizeUrl + "?client_id=" + oauthClientId + "&response_type=code" + "&redirect_uri=" + redirectUrl);
}
}
}
@Override
public void destroy() {
}
private void storeLoginUser(HttpServletRequest request, HttpServletResponse response, String userName, String accessToken) {
try {
String decisionToken = LoginService.getInstance().login(request, response, userName);
request.setAttribute("fine_auth_token", decisionToken);
Cookie cookie = new Cookie(COOKIE_AUTH, accessToken);
cookie.setPath("/");
cookie.setHttpOnly(true);
response.addCookie(cookie);
OAUTH_SERVICE.put(accessToken, new OauthLoginInfo(userName, accessToken, decisionToken), TIME);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
}
private void refreshDecisionToken(HttpServletRequest request, HttpServletResponse response, OauthLoginInfo loginInfo) {
try {
String oldToken = TokenResource.COOKIE.getToken(request);
Device device = NetworkHelper.getDevice(request);
LoginService.getInstance().loginStatusValid(oldToken, TerminalHandler.getTerminal(request, device));
} catch (Exception e) {
try {
String decisionToken = LoginService.getInstance().login(request, response, loginInfo.userName);
request.setAttribute("fine_auth_token", decisionToken);
OAUTH_SERVICE.put(loginInfo.accessToken, new OauthLoginInfo(loginInfo.userName, loginInfo.accessToken, decisionToken), TIME);
} catch (Exception ex) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
private static OauthLoginInfo getCurrentUser(HttpServletRequest request) {
Cookie cookie = WebUtils.getCookie(request, COOKIE_AUTH);
if (cookie == null) {
return null;
}
try {
return OAUTH_SERVICE.get(cookie.getValue());
} catch (Exception e) {
return null;
}
}
private boolean isLoginPage(HttpServletRequest request) {
if (request.getRequestURI().endsWith("/login")) {
return true;
}
String refer = request.getHeader("refer");
return refer != null && refer.contains(decisionRoot + "/login");
}
private void doOauth(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain, String code) throws IOException, ServletException {
String accessToken = null;
try {
/** (1) 获取access_token*/
JSONObject result = new JSONObject(HttpToolbox.post(oauthTokenUrl + "?client_id=" + oauthClientId + "&client_secret=" + oauthClientSecret + "&grant_type=authorization_code" + "&code=" + code + "&redirect_uri=" + redirectUrl, null));
accessToken = result.getString("access_token");
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
response.sendRedirect(oauthAuthorizeUrl + "?client_id=" + oauthClientId + "&response_type=code" + "&redirect_uri=" + redirectUrl);
}
if (StringUtils.isNotEmpty(accessToken)) {
/** (2) 再根据accessToken去请求oauthUserInfoUrl得到用户名*/
JSONObject userInfo = new JSONObject(HttpToolbox.get(oauthUserInfoUrl + "?client_id=" + oauthClientId + "&access_token=" + accessToken, null));
String userName = userInfo.getString(oauthUserName);
/** (3) 建立本地会话*/
storeLoginUser(request, response, userName, accessToken);
filterChain.doFilter(request, response);
}else {
/** 如果获取不到, 说明code失效则重定向到oauth认证地址*/
FineLoggerFactory.getLogger().error("oauth code is invalid");
response.sendRedirect(oauthAuthorizeUrl + "?client_id=" + oauthClientId + "&response_type=code" + "&redirect_uri=" + redirectUrl);
}
}
private boolean excludeUrl(HttpServletRequest request) {
String url = request.getRequestURI();
for (String exclude: oauthExcludeUrl) {
if (exclude.equals(url) || (exclude.endsWith("/*") && url.startsWith(exclude.substring(0, exclude.indexOf("/*"))))) {
return true;
}
}
return false;
}
public static void deleteTicket(HttpServletRequest request, HttpServletResponse response){
OauthLoginInfo loginInfo = getCurrentUser(request);
if (loginInfo != null) {
try {
OAUTH_SERVICE.delete(loginInfo.accessToken);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
Cookie cookie = new Cookie(COOKIE_AUTH, "");
cookie.setPath("/");
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
private String getCode(HttpServletRequest request) {
return request.getParameter("code");
}
public class OauthLoginInfo implements Serializable {
private static final long serialVersionUID = -5100721982500534486L;
String userName;
String accessToken;
String decisionToken;
String code;
boolean decisionLogout;
public OauthLoginInfo() {
}
public OauthLoginInfo(String userName, String accessToken, String decisionToken) {
this.userName = userName;
this.accessToken = accessToken;
this.decisionToken = decisionToken;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getDecisionToken() {
return decisionToken;
}
public void setDecisionToken(String decisionToken) {
this.decisionToken = decisionToken;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public boolean isDecisionLogout() {
return decisionLogout;
}
public void setDecisionLogout(boolean decisionLogout) {
this.decisionLogout = decisionLogout;
}
public OauthLoginInfo decisionLogout(boolean decisionLogout) {
this.decisionLogout = decisionLogout;
return this;
}
}
}
FrOauthFilter$OauthLoginInfo 文件源码如下所示:
package com.fr;
import com.fr.base.TemplateUtils;
import com.fr.data.NetworkHelper;
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.general.http.HttpToolbox;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.stable.web.Device;
import com.fr.store.StateHubManager;
import com.fr.store.StateHubService;
import com.fr.third.springframework.web.util.WebUtils;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: Elijah
* @Create: 2019-07-10
* @Desciption:
*/
public class FrOauthFilter implements Filter {
private static final StateHubService OAUTH_SERVICE = StateHubManager.applyForService("oauth");
private static final String COOKIE_AUTH = "oauth_access_token";
private static final int TIME = 3600000 * 24;
private String oauthTokenUrl; //oauth获取accessToken地址,无需包括请求参数
private String oauthUserInfoUrl; //oauth获取用户信息地址
private String oauthUserName = "username"; //oauth获取用户信息接口返回值中的用户名字段
private String redirectUrl; //需要重定向回来的地址,一般就是工程地址
private String oauthClientId; //oauth注册的客户端id
private String oauthClientSecret; //oauth注册的客户端秘钥
private String oauthAuthorizeUrl; //oauth认证地址,无需包括请求参数
private String oauthLogoutUrl;//oauth登出地址,无需包括请求参数
private List<String> oauthExcludeUrl = new ArrayList<String>();
private String decisionRoot;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.oauthTokenUrl= filterConfig.getInitParameter("oauthTokenUrl");
this.oauthUserInfoUrl = filterConfig.getInitParameter("oauthUserInfoUrl");
this.redirectUrl = filterConfig.getInitParameter("redirectUrl");
this.oauthClientId = filterConfig.getInitParameter("oauthClientId");
this.oauthClientSecret = filterConfig.getInitParameter("oauthClientSecret");
this.oauthAuthorizeUrl = filterConfig.getInitParameter("oauthAuthorizeUrl");
this.oauthLogoutUrl = filterConfig.getInitParameter("oauthLogoutUrl");
this.oauthUserName = filterConfig.getInitParameter("oauthUserName") != null ? filterConfig.getInitParameter("oauthUserName") : oauthUserName;
String excludeUrls = filterConfig.getInitParameter("oauthExcludeUrl");
String[] array = excludeUrls.split(",");
for (String s: array) {
oauthExcludeUrl.add(filterConfig.getServletContext().getContextPath() + s.trim());
}
try {
this.decisionRoot = TemplateUtils.render(DecisionServiceConstants.MAIN_PAGE_URL);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
OauthLoginInfo loginInfo = getCurrentUser(request);
if (excludeUrl(request)) {
filterChain.doFilter(request, response);
return;
}
if (loginInfo != null ) {
//如果oauth已经登录, 即已经存在本地会话,则刷新平台token
refreshDecisionToken(request, response, loginInfo);
filterChain.doFilter(request, response);
} else {
//如果oauth没有登录,则判断是否携带oauth的code
String code = getCode(request);
if ( code != null) {
doOauth(request, response, filterChain, code);
}else {
//直接重定向到oauth认证地址
response.sendRedirect(oauthAuthorizeUrl + "?client_id=" + oauthClientId + "&response_type=code" + "&redirect_uri=" + redirectUrl);
}
}
}
@Override
public void destroy() {
}
private void storeLoginUser(HttpServletRequest request, HttpServletResponse response, String userName, String accessToken) {
try {
String decisionToken = LoginService.getInstance().login(request, response, userName);
request.setAttribute("fine_auth_token", decisionToken);
Cookie cookie = new Cookie(COOKIE_AUTH, accessToken);
cookie.setPath("/");
cookie.setHttpOnly(true);
response.addCookie(cookie);
OAUTH_SERVICE.put(accessToken, new OauthLoginInfo(userName, accessToken, decisionToken), TIME);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
}
private void refreshDecisionToken(HttpServletRequest request, HttpServletResponse response, OauthLoginInfo loginInfo) {
try {
String oldToken = TokenResource.COOKIE.getToken(request);
Device device = NetworkHelper.getDevice(request);
LoginService.getInstance().loginStatusValid(oldToken, TerminalHandler.getTerminal(request, device));
} catch (Exception e) {
try {
String decisionToken = LoginService.getInstance().login(request, response, loginInfo.userName);
request.setAttribute("fine_auth_token", decisionToken);
OAUTH_SERVICE.put(loginInfo.accessToken, new OauthLoginInfo(loginInfo.userName, loginInfo.accessToken, decisionToken), TIME);
} catch (Exception ex) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
private static OauthLoginInfo getCurrentUser(HttpServletRequest request) {
Cookie cookie = WebUtils.getCookie(request, COOKIE_AUTH);
if (cookie == null) {
return null;
}
try {
return OAUTH_SERVICE.get(cookie.getValue());
} catch (Exception e) {
return null;
}
}
private boolean isLoginPage(HttpServletRequest request) {
if (request.getRequestURI().endsWith("/login")) {
return true;
}
String refer = request.getHeader("refer");
return refer != null && refer.contains(decisionRoot + "/login");
}
private void doOauth(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain, String code) throws IOException, ServletException {
String accessToken = null;
try {
// (1) 获取access_token
JSONObject result = new JSONObject(HttpToolbox.post(oauthTokenUrl + "?client_id=" + oauthClientId + "&client_secret=" + oauthClientSecret + "&grant_type=authorization_code" + "&code=" + code + "&redirect_uri=" + redirectUrl, null));
accessToken = result.getString("access_token");
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
response.sendRedirect(oauthAuthorizeUrl + "?client_id=" + oauthClientId + "&response_type=code" + "&redirect_uri=" + redirectUrl);
}
if (StringUtils.isNotEmpty(accessToken)) {
// (2) 再根据accessToken去请求oauthUserInfoUrl得到用户名
JSONObject userInfo = new JSONObject(HttpToolbox.get(oauthUserInfoUrl + "?client_id=" + oauthClientId + "&access_token=" + accessToken, null));
String userName = userInfo.getString(oauthUserName);
// (3) 建立本地会话
storeLoginUser(request, response, userName, accessToken);
filterChain.doFilter(request, response);
}else {
// 如果获取不到, 说明code失效则重定向到oauth认证地址
FineLoggerFactory.getLogger().error("oauth code is invalid");
response.sendRedirect(oauthAuthorizeUrl + "?client_id=" + oauthClientId + "&response_type=code" + "&redirect_uri=" + redirectUrl);
}
}
private boolean excludeUrl(HttpServletRequest request) {
String url = request.getRequestURI();
for (String exclude: oauthExcludeUrl) {
if (exclude.equals(url) || (exclude.endsWith("/*") && url.startsWith(exclude.substring(0, exclude.indexOf("/*"))))) {
return true;
}
}
return false;
}
public static void deleteTicket(HttpServletRequest request, HttpServletResponse response){
OauthLoginInfo loginInfo = getCurrentUser(request);
if (loginInfo != null) {
try {
OAUTH_SERVICE.delete(loginInfo.accessToken);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
Cookie cookie = new Cookie(COOKIE_AUTH, "");
cookie.setPath("/");
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
private String getCode(HttpServletRequest request) {
return request.getParameter("code");
}
public class OauthLoginInfo implements Serializable {
private static final long serialVersionUID = -5100721982500534486L;
String userName;
String accessToken;
String decisionToken;
String code;
boolean decisionLogout;
public OauthLoginInfo() {
}
public OauthLoginInfo(String userName, String accessToken, String decisionToken) {
this.userName = userName;
this.accessToken = accessToken;
this.decisionToken = decisionToken;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getDecisionToken() {
return decisionToken;
}
public void setDecisionToken(String decisionToken) {
this.decisionToken = decisionToken;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public boolean isDecisionLogout() {
return decisionLogout;
}
public void setDecisionLogout(boolean decisionLogout) {
this.decisionLogout = decisionLogout;
}
public OauthLoginInfo decisionLogout(boolean decisionLogout) {
this.decisionLogout = decisionLogout;
return this;
}
}
}
2.1.3 新建 web.xml
根据注释配置 OAuth 登出地址、认证地址、 获取 token 地址、重定向回来地址、注册的 client_id、注册的 client_secret 、获取用户信息接口地址、获取用户信息接口返回值中的平台用户名字段等 web.xml 中的参数,然后将其放在%FineBI%/webapps/webroot/WEB_INF目录下,web.xml 文件代码如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Template WebApp</display-name>
<mime-mapping>
<extension>msi</extension>
<mime-type>application/x-msi</mime-type>
</mime-mapping>
<!--设置oauth登出地址,非必须-->
<context-param>
<param-name>oauthLogoutUrl</param-name>
<param-value>https://www.example.com/oauth/authorize/logout</param-value>
</context-param>
<filter>
<filter-name>FrOauthFilter</filter-name>
<filter-class>com.fr.FrOauthFilter</filter-class>
<init-param>
<!--oauth认证地址-->
<param-name>oauthAuthorizeUrl</param-name>
<param-value>https://www.example.com/oauth/authorize</param-value>
</init-param>
<init-param>
<!--oauth获取token地址-->
<param-name>oauthTokenUrl</param-name>
<param-value>https://www.example.com/oauth/token</param-value>
</init-param>
<init-param>
<!--从oauth重定向回来地址,一般就是fr工程地址, 集群下则为nginx转发地址-->
<param-name>redirectUrl</param-name>
<param-value>http://www.aaa.com/webroot/decision</param-value>
</init-param>
<init-param>
<!--在oauth注册的client_id-->
<param-name>oauthClientId</param-name>
<param-value>xxxxx</param-value>
</init-param>
<init-param>
<!--在oauth注册的client_secret,非必须,没有就删除-->
<param-name>oauthClientSecret</param-name>
<param-value></param-value>
</init-param>
<init-param>
<!--oauth获取用户信息接口地址-->
<param-name>oauthUserInfoUrl</param-name>
<param-value>https://www.example.com/oauth/userinfo</param-value>
</init-param>
<init-param>
<!--oauth获取用户信息接口返回值中的平台用户名字段-->
<param-name>oauthUserName</param-name>
<param-value>username</param-value>
</init-param>
<!--排除远程设计和其他 -->
<init-param>
<param-name>oauthExcludeUrl</param-name>
<param-value>/decision/remote/design/*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FrOauthFilter</filter-name>
<url-pattern>/decision/*</url-pattern>
</filter-mapping>
</web-app>
注:其中 oauthUserName 参数有些特别,标记了用户信息接口的返回值中,哪个字段对应平台用户名,比如 oauthUserInfoUrl 接口返回了{ username: "张三", phone: "xxx", email:"ssss"}这样 JSON 接口的数据,则填写 username 。
2.1.4 单点登出
如果需要退出平台后,也同时退出 OAuth 系统,还需要进行下列配置。
1)web.xml 中配置登出地址,如下图所示:
2)添加 logout.jsp ,将 loggout.jsp 文件放到%FineBI%/webapps/webroot目录下,代码如下所示:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page import="com.fr.FrOauthFilter" %>
<html>
<body>
<%
FrOauthFilter.deleteTicket(request, response);
response.sendRedirect(application.getInitParameter("oauthLogoutUrl"));
%>
</body>
</html>
3)配置平台登录页
在管理系统>外观配置>登录页处选择设置登录网页,设置网页 URL 为第 2 步中放置的 jsp 地址,点击保存,如下图所示:
2.2 效果查看
重启工程后进行登录,如下图所示:
3. 注意事项
1)由于 OAuth 规范不严格,此仅作为 OAuth 登录的示例 ,可能需要根据客户的 OAuth 服务器要求修改,主要集中在 doOauth 方法中修改相关内容。
2)本例中用户信息接口返回值为 JSON 格式数据,比如为{username : "aaa", id: "123"},此时 web.xml 中的须配置成如下图所示:
如果返回值为{ user: {username : "aaa", id: "aaa"}},那么 param-value 则应为 user.username 。
3)若OAuth 系统使用了 https,则需要导入证书到报表服务器的 JAVA 环境中,否则会报错。
附件列表
-
有帮助
-
没帮助
-
只是浏览
-
评价文档,奖励 1 ~ 100 随机 F 豆!