/* * Copyright (c) 2008-2016 Computer Network Information Center (CNIC), Chinese Academy of Sciences. * * This file is part of Duckling project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package cn.vlabs.umt.oauth; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import javax.servlet.ServletRequest; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import cn.vlabs.umt.oauth.client.HttpClient; import cn.vlabs.umt.oauth.client.HttpsConnectionClient; import cn.vlabs.umt.oauth.client.OAuthClient; import cn.vlabs.umt.oauth.client.URLConnectionClient; import cn.vlabs.umt.oauth.client.request.OAuthClientRequest; import cn.vlabs.umt.oauth.client.response.OAuthJSONAccessTokenResponse; import cn.vlabs.umt.oauth.common.exception.OAuthProblemException; import cn.vlabs.umt.oauth.common.exception.OAuthSystemException; import cn.vlabs.umt.oauth.common.message.types.GrantType; import cn.vlabs.umt.oauth.common.message.types.ResponseType; public class Oauth { private String clientId; private String clientSecret; private String redirectURI; private String authorizeURL; private String accessTokenURL; private String scope; private String theme; public Oauth(String name) throws IOException { InputStream in = Oauth.class.getResourceAsStream("/" + name); Properties p = new Properties(); p.load(in); loadProperties(p); in.close(); } public Oauth(String serverUrl,String redirectUri, String clientId, String clientSecret, String theme){ this.clientId=clientId; this.clientSecret=clientSecret; this.redirectURI = redirectUri; this.authorizeURL= serverUrl+"/oauth2/authorize"; this.accessTokenURL = serverUrl+"/oauth2/token"; this.theme = theme; } public Oauth(Properties p) { loadProperties(p); } private void loadProperties(Properties p) { this.clientId = p.getProperty("client_id"); this.clientSecret = p.getProperty("client_secret"); this.redirectURI = p.getProperty("redirect_uri"); this.authorizeURL = p.getProperty("authorize_URL"); this.accessTokenURL = p.getProperty("access_token_URL"); this.scope = p.getProperty("scope"); this.theme = p.getProperty("theme"); } public AccessToken refreshToken(String refreshToken) throws OAuthProblemException { try { OAuthClientRequest request = OAuthClientRequest .tokenLocation(this.accessTokenURL) .setClientId(this.clientId) .setClientSecret(this.clientSecret) .setParameter("grant_type", "refresh_token") .setParameter("refresh_token", refreshToken) .buildBodyMessage(); OAuthClient oAuthClient = new OAuthClient( getHttpClient(this.accessTokenURL)); OAuthJSONAccessTokenResponse oAuthResponse = oAuthClient .accessToken(request, OAuthJSONAccessTokenResponse.class); String error = oAuthResponse.getParam("error"); if (error != null && error.length() > 0) { OAuthProblemException ex = OAuthProblemException.error(error, oAuthResponse.getParam("error_description")); throw ex; } AccessToken token = new AccessToken(); token.setAccessToken(oAuthResponse.getAccessToken()); token.setRefreshToken(oAuthResponse.getRefreshToken()); token.setExpiresIn(oAuthResponse.getExpiresIn()); token.setScope(oAuthResponse.getScope()); token.setUserInfo(getUserInfo(oAuthResponse.getParam("userInfo"))); return token; } catch (OAuthSystemException e) { throw OAuthProblemException.error("systemError", e.getMessage()); } } public AccessToken validateAccessToken(String accessToken) throws OAuthProblemException { try { OAuthClientRequest request = OAuthClientRequest .tokenLocation(this.accessTokenURL) .setClientId(this.clientId) .setClientSecret(this.clientSecret) .setParameter("grant_type", "validate_access_token") .setParameter("access_token", accessToken) .buildBodyMessage(); OAuthClient oAuthClient = new OAuthClient( getHttpClient(this.accessTokenURL)); OAuthJSONAccessTokenResponse oAuthResponse = oAuthClient .accessToken(request, OAuthJSONAccessTokenResponse.class); String error = oAuthResponse.getParam("error"); if (error != null && error.length() > 0) { OAuthProblemException ex = OAuthProblemException.error(error, oAuthResponse.getParam("error_description")); throw ex; } AccessToken token = new AccessToken(); token.setAccessToken(oAuthResponse.getAccessToken()); token.setRefreshToken(oAuthResponse.getRefreshToken()); token.setExpiresIn(oAuthResponse.getExpiresIn()); token.setScope(oAuthResponse.getScope()); token.setUserInfo(getUserInfo(oAuthResponse.getParam("userInfo"))); return token; } catch (OAuthSystemException e) { throw OAuthProblemException.error("systemError", e.getMessage()); } } public String getAuthorizeURL(ServletRequest request) throws UMTOauthConnectException { try { OAuthClientRequest req = OAuthClientRequest .authorizationLocation(authorizeURL).setClientId(clientId) .setRedirectURI(redirectURI) .setResponseType(ResponseType.CODE.toString()) .setScope(scope).buildQueryMessage(); if (theme == null || theme.length() == 0) { return req.getLocationUri(); } else { return req.getLocationUri() + "&theme=" + theme; } } catch (OAuthSystemException e) { throw new UMTOauthConnectException("获取authorization code URL错误", e); } } public AccessToken getAccessTokenByRequest(ServletRequest req) throws UMTOauthConnectException, OAuthProblemException { OAuthClientRequest request; String url = ""; try { String code = req.getParameter("code"); if (code == null || code.length() == 0) { String error = req.getParameter("error"); OAuthProblemException ex = null; if (error != null && error.length() > 0) { ex = OAuthProblemException.error(error, req.getParameter("error_description")); } else { ex = OAuthProblemException.error("invalid_request", "code值为空"); } throw ex; } request = OAuthClientRequest.tokenLocation(accessTokenURL) .setGrantType(GrantType.AUTHORIZATION_CODE) .setClientId(clientId).setClientSecret(clientSecret) .setRedirectURI(redirectURI).setCode(code) .buildBodyMessage(); OAuthClient oAuthClient = new OAuthClient( getHttpClient(accessTokenURL)); url = request.getLocationUri(); OAuthJSONAccessTokenResponse oAuthResponse = oAuthClient .accessToken(request, OAuthJSONAccessTokenResponse.class); String error = oAuthResponse.getParam("error"); if (error != null && error.length() > 0) { OAuthProblemException ex = OAuthProblemException.error(error, oAuthResponse.getParam("error_description")); throw ex; } AccessToken token = new AccessToken(); token.setAccessToken(oAuthResponse.getAccessToken()); token.setRefreshToken(oAuthResponse.getRefreshToken()); token.setExpiresIn(oAuthResponse.getExpiresIn()); token.setScope(oAuthResponse.getScope()); token.setUserInfo(getUserInfo(oAuthResponse.getParam("userInfo"))); return token; } catch (OAuthSystemException e) { throw new UMTOauthConnectException("获取accessToken错误url" + url, e); } } private HttpClient getHttpClient(String accessTokenURL) { if (accessTokenURL.toLowerCase().startsWith("https")) { return new HttpsConnectionClient(); } else { return new URLConnectionClient(); } } private UserInfo getUserInfo(String param) { if (param == null || param.length() == 0) { return null; } JSONObject obj; try { UserInfo user = new UserInfo(); obj = new JSONObject(param); user.setType(getFromJSON(obj, "type")); user.setTrueName(getFromJSON(obj, "truename")); user.setCstnetId(getFromJSON(obj, "cstnetId")); user.setUmtId(getFromJSON(obj, "umtId")); user.setPasswordType(getFromJSON(obj, "passwordType")); user.setCstnetIdStatus(getFromJSON(obj, "cstnetIdStatus")); user.setSecurityEmail(getFromJSON(obj, "securityEmail")); user.setEncPassword(getFromJSON(obj, "encPassword")); user.setOrgInfo(getOrgInfoFromJSON(obj)); return user; } catch (JSONException e) { return null; } } public OrgInfo[] getOrgInfoFromJSON(JSONObject obj) { if (obj.has("orgInfo")) { try { JSONArray orgInfoJson = obj.getJSONArray("orgInfo"); if (orgInfoJson != null) { OrgInfo[] infos = new OrgInfo[orgInfoJson.length()]; for (int i = 0; i < orgInfoJson.length(); i++) { JSONObject orgInfo = orgInfoJson.getJSONObject(i); OrgInfo info = new OrgInfo(); info.setCas(orgInfo.getBoolean("isCas")); info.setCoreMail(orgInfo.getBoolean("isCoreMail")); info.setDomains(getStringArrayFromJSON(orgInfo, "domains")); info.setOrgId(orgInfo.getString("orgId")); info.setOrgName(orgInfo.getString("orgName")); infos[i] = info; } return infos; } } catch (JSONException e) { return new OrgInfo[] {}; } } return new OrgInfo[] {}; } public String[] getStringArrayFromJSON(JSONObject obj, String key) { try { JSONArray domains = obj.getJSONArray(key); if (domains != null && domains.length() > 0) { String[] r = new String[domains.length()]; for (int i = 0; i < domains.length(); i++) { r[i] = domains.getString(i); } return r; } } catch (JSONException e) { } return new String[] {}; } private String getFromJSON(JSONObject obj, String key) { try { return obj.getString(key); } catch (JSONException e) { return null; } } }