当前所在位置:首页 > 平台指引 > 接入规范 > 用户集成 > 6 第三方应用集成技术规范

6 第三方应用集成技术规范

第三方应用通过实现OAuth方式接入云平台后,云平台用户在应用商店中通过点击应用图标(链接)访问业务系统,业务系统通过云平台提供的appid以及密钥,按照OAuth标准流程请求授权以及相关资源。

6.1   依赖包

 commons-codec-1.3.jar

 commons-httpclient-3.1.jar

 commons-logging-1.1.1.jar

 httpclient-4.1.3.jar

 jstl-1.2.jar

 log4j-1.2.17.jar

 openapi-sdk.jar

其中openapi-sdk.jar请参考源码实例。

      6.2 相关说明

API调用的必备参数,需在应用集成前通过平台运营方提前获取,除调用入口地址外,还包括AppKey、AppSecret、Access Token(或SessionKey)AppKey、Appsecret在从管理平台创建该应用时获得;Access Token则通过登录账号授权方式(详细请参考下一节用户授权介绍)取得;取得这些数据后可进行API 调用,获取相应的用户数据。

使用平台用户登录第三方应用系统,通过OAuth服务完成授权之后,需要获取用户隐私信息(如:用户账户信息、用户身份信息等),为保证用户数据的安全性与隐私性,第三方应用系统应取得用户的授权{即Access Token(授权令牌)}。在这种情况下,第三方应用系统应引导用户完成使用平台帐号“登录授权”的流程。

该流程采用国际通用的OAuth2.0标准协议作为用户身份验证与授权协议,支持网站、手机客户端、桌面客户端。

     6.2.1 授权码模式

     此授权方式要求第三方应用系统的独立软件开发商(ISV)有Web Server应用,能够保存应用本身的密钥以及状态,可以通过https直接访问平台的授权服务器。

     

     6.2.2 授权操作步骤

以获取acccess_token为例说明,如果是环境测试,应将请求入口地址等相关数据换成对应入口地址,授权操作流程则同正式环境一致。

实际进行授权操作时,授权参数client_id(应用ID)、client_secret(应用密钥)均需根据ISV在平台中创建应用时所分配的实际数据为准进行替换使用,不应使用示例中给出的值直接进行测试,以免影响实际测试效果。

1) 拼接授权URL

用户通过青岛教育e平台访问目标应用链接(集成应用的requestLogin的地址示例:http://www.example.com/OAuth_client/requestLogin),应用在相应的后台filter类生成“授权地址”发起访问,来引导用户授权,并获得authorization_code

授权地址:http://www.example.com/auth/OAuth/authorize?client_id=54273&redirect_uri=http://www.example.com:8083/OAuth_client/callback&response_type=code&state=2075440927&forcelogin=false

参数列表:

参数名称

参数说明

client_id

必选参数,应用的唯一标识,对应于应用ID

redirect_uri

必选参数,用户授权完成后的回调地址,应用需要通过此回调地址获得用户的授权结果。此地址必须与在应用注册时填写的回调地址一致。

response_type

必选参数,此值可以为 code 或者 token 。在本流程中,此值为 code

scope

可选参数,申请权限的范围,如果不填,则使用缺省的应用默认申请的服务列表。

state

可选参数,用来维护请求和回调状态的附加字符串,在授权完成回调时会附加此参数,应用可以根据此字符串来判断上下文关系。

(2)  授权服务会判断当前会话信息,如果已登录,则会跳转到授权页面引导用户授权;未登录系统会跳转到云平台用户登录页面,输入管理公共服务平台账号密码,点击登录进行账号验证。

(3) 验证通过之后,获取autorization_code,再跳转到用户授权页面,当用户拒绝授权时,浏览器会重定向到redirect_uri,并附加错误信息,示例如下:

http://www.example.com/back?error=access_denied

在引导登录用户授权页面,当用户同意授权时,浏览器会重定向到redirect_uri,并附加autorization_code,示例如下:

http://www.example.com/back?code=45aEq

(4) 换取AccessToken

换取AccessToken地址示例如下:

http://www.example.com/auth/OAuth/token

上述地址传入参数列表:

参数名称

参数说明

client_id

必选参数,应用的唯一标识,对应于应用ID

client_secret

必选参数,应用的唯一标识,对应于应用密钥 

redirect_uri

必选参数,用户授权完成后的回调地址,应用需要通过此回调地址获得用户的授权结果。此地址必须与在应用注册时填写的回调地址一致

grant_type

必选参数,此值可以为 authorization_code 或者 refresh_token 。在本流程中,此值为 authorization_code

code

必选参数,上一步中获得的authorization_code

注意:此请求必须是HTTP POST方式,例如:

http://www.example.com/auth/token? client_id=2356&client_secret=edfc4e395ef93375&  redirect_uri=https://www.example.com/back&grant_type=authorization_code&code=45aEq

返回结果:

{

  "access_token":"a14afef0f66fcffce3e0fcd2e34f6ff4",

  "expires_in":3920,

  "refresh_token":"5d633d136b6d56a41829b73a424803ec",

  "scope":["/a/b/2.0","/weather/bj/1.1"]

}

返回结果参数说明:

参数名称

参数说明

access_token

应用授权码

expires_in

表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。

refresh_token

表示更新令牌,用来获取下一次的访问令牌,可选项

scope

表示权限范围,如果与客户端申请的范围一致,此项可省略

      6.3  开发示例

以第三方应用中采用青岛教育e平台账号登陆为例,通过验证青岛教育e平台中实名制账户信息,获取青岛教育e平台中用户的相关资料。

首先,需要向开发者中心进行注册,登陆到 http:// 27.221.57.93:8081/oam。

配置参数说明(此配置环境为测试环境):

##应用id

client_ID = 5427

##应用密钥

client_SERCRET = 67ad2626894b237fdcc2dc89ccbe1fa5

##回调地址,sdk读取

redirect_URI =http://www.example.com:8080/OAuth_client/callback

##应用首页,应用自己读取

app_URL = index.jsp

##widget首页(地址可为空)

widget_URL =

######以下内容不需要修改##############

#获取用户信息

baseURL = http://www.example.com/auth/api

#获取令牌

accessTokenURL = http://www.example.com/auth/OAuth/token

#请求授权

authorizeURL =http://www.example.com/auth/OAuth/authorize

(1) 直接请求授权url(requestLogin),自动跳转到云平台登录页面,并且url请求中会附带回调服务url路径

OAuth OAuth = new OAuth();

java.util.Random r = new java.util.Random();

String state = Integer.toString(r.nextInt());

hrequest.getSession().setAttribute(Config.getValue("client_ID")   "_state", state);

boolean forcelogin = false;

String auth_url;

try {

auth_url = OAuth.authorize("code", state, forcelogin);//拼接授权url由sdk完成

hresponse.sendRedirect(auth_url);

} catch (OpenAPIException e) {

throw new ServletException(e);

}

(2) 授权验证,第三方获取返回值code

输入用户名密码之后点击登陆,管理平台会进行验证;验证通过之后,获取Code,获取用户信息进行处理,然后自动跳转到回调url 

String code = hrequest.getParameter("code");

if (code == null || code.isEmpty()) {

throw new ServletException("获取code出错");

}

HttpSession session = hrequest.getSession();

// 增加state参数防止跨站攻击,不支持session的需去掉

Object sstate = session.getAttribute(client_ID   "_state");

String state = request.getParameter("state");

if (state == null || !state.equals(sstate)) {

throw new ServletException("跨站攻击!");

}

OAuth OAuth = new OAuth();

// 获取accesstoken

AccessToken tokenObj;

try {

tokenObj = OAuth.getAccessTokenByCode(code, state);

String token = tokenObj.getAccessTokenString();

session.setAttribute(this.client_ID   "_access_token", token);

// client_ID为应用ID, client_SERCRET为应用密钥

//openapi为浪潮封装jar包

// 下面开始获取用户信息

OpenApi api = new OpenApi(this.client_ID, this.client_SERCRET);

api.client.setToken(token);

JSONObject userJsonObj = api.sendCommand("/user/get_user_Info_phone", "1.0", "get", null);

String status = userJsonObj.getString("status");

JSONObject result = userJsonObj.getJSONObject("result");

String error = result.getString("error");

if (error != null && !error.isEmpty()) {

throw new ServletException("获取信息出错");

}

Iterator it = result.keys();

Map u = new HashMap();

while (it.hasNext()) {

String key = (String) it.next();

u.put(key, result.get(key));

}

// 模拟登陆往session里放登陆信息

session.setAttribute("user", u);

// 调到第三方应用系统界面,视应用情况而定

hresponse.sendRedirect(hrequest.getContextPath()   "/jsp/callindex.jsp");

} catch (OpenAPIException e) {

throw new ServletException(e);

} catch (JSONException e) {

throw new ServletException(e);

}


(3) 第三方应用获取青岛教育e平台的用户信息之后,进行相应的第三方资源访问;或者按照需求记录用户,以便下次访问能够直接访问第三方系统。