Extend to use accounts which follow OAuth2 protocol |
SuperMap iServer provides the OAuth2Client interface, which is used to follow the third-party login extension in OAuth2 protocol. The third party login: QQ, Sina Weibo and Renren. The QQ and Sina Weibo are the built-in login way of SuperMap iServer.
com.supermap.services.security.OAuth2Client interface has following methods:
This method is used to get the jumping URL of OAuth.
This method is used to access Token.
This method is used to get the user ID.
This method is used to get the user information.
Here we have an example to show the extension. Use the Renren login method.
Implement the RenRenLoginExtended class. Inherit from the OAuth2Client interface, as shown below:
package com.supermap.services.rest.resources.impl; import java.io.IOException; import java.net.URI; import java.net.URLEncoder; import com.supermap.services.security.OAuth2Client; import com.supermap.services.security.OAuthUserInfo; import org.apache.commons.io.IOUtils; import java.net.URISyntaxException; import org.json.JSONException; import org.json.JSONObject; public class RenRenLoginExtended implements OAuth2Client { // Renren OAuth2 authentication root address public static final String OAUTH_URL_RENREN = System.getProperty("OAUTH_RENREN", "https://graph.renren.com"); private static final String GET_CODE_URI_RENREN = OAUTH_URL_RENREN + "/oauth/authorize?client_id=%s&response_type=code&redirect_uri=%s&state=%s&display=page"; private static final String GET_TOKEN_BY_CODE_RENREN = OAUTH_URL_RENREN + "/oauth/token?client_id=%s&client_secret=%s&grant_type=authorization_code&code=%s&redirect_uri=%s"; private static final String useridUrl = "https://api.renren.com/v2/user/get?access_token=%s"; private static final String userInfoUrl = "https://api.renren.com/v2/user/get?access_token=%s&client_id=%s&userID=%s"; //Get the OAuth2 jumping URI public String getRedirectURI(String clientID, String state, String redirectUri) { return String.format(GET_CODE_URI_RENREN, clientID, redirectUri, state); } //Get the access Token public String getAccesstoken(String clientID, String clientSecret, String code, String redirectUri) throws IOException { String tokenurl = String.format(GET_TOKEN_BY_CODE_RENREN, clientID, clientSecret,code,redirectUri); try { String tokenResult = IOUtils.toString(new URI(tokenurl), "utf-8"); JSONObject tokenObj = new JSONObject(tokenResult); return tokenObj.getString("access_token"); } catch (JSONException e) { throw new IOException(e); }catch (URISyntaxException e) { throw new IOException(e); } } // Get the user ID public String getUserID(String accesstoken) throws IOException { String useridfourl = String.format(useridUrl, URLEncoder.encode(accesstoken, "utf-8")); try { String useridresult = IOUtils.toString(new URI(useridfourl), "utf-8"); JSONObject useridObj = new JSONObject(useridresult); return useridObj.getJSONObject("response").getString("id"); } catch (JSONException e) { throw new IOException(e); }catch (URISyntaxException e) { throw new IOException(e); } }
//Get the user information
public OAuthUserInfo getUserInfo(String token, String clientID, String userID) throws IOException {
String url = String.format(USERINFO_URL_PATTERN, token, clientID, userID);
OAuthUserInfo result = new OAuthUserInfo();
String content;
try {
content = IOUtils.toString(new URI(url), "utf-8");
JSONObject json = JSON.parseObject(content);
if (json != null) {
result.figureurl = json.getString("profile_image_url");
result.nickName = json.getString("nickname");
result.name = json.getString("name");
result.email = getEmail(token, clientID);
}
return result;
} catch (IOException | URISyntaxException e) {
throw new IOException(e);
}
}
private String getEmail(String token, String clientId) throws IOException {
try {
String url = String.format(EMAIL_URL_PATTERN, token, clientId);
String content = IOUtils.toString(new URI(url), "utf-8");
if (StringUtils.isBlank(content)) {
return StringUtils.EMPTY;
}
int startIndex = StringUtils.indexOf(content, '[');
int endIndex = StringUtils.indexOf(content, ']');
content = StringUtils.substring(content, startIndex + 1, endIndex);
JSONObject json = JSON.parseObject(content);
if (json != null) {
return json.getString("email");
}
} catch (IOException | URISyntaxException e) {
throw new IOException(e);
}
return StringUtils.EMPTY;
}
private String getContentByMethodPost(String url, List<BasicNameValuePair> nvps) {
HttpPost httpPost = new HttpPost(url);
try {
httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
} catch (UnsupportedEncodingException e) {
return null;
}
DefaultHttpClient httpClient = new DefaultHttpClient();
try {
HttpResponse httpResponse = httpClient.execute(httpPost);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = httpResponse.getEntity();
return EntityUtils.toString(entity, HTTP.UTF_8);
}
} catch (IOException ignore) {
} finally {
IOUtils.closeQuietly(httpClient);
}
return null;
}
Copy the com folder that contains the compiled RenRenLoginExtended.class file to the SuperMap iServer Web application, that is %SuperMap iServer_HOME%\webapps\iserver\WEB-INF\classes (first create a classes folder in this directory).
Create a new extendedOAuth.xml file in the root directory of %SuperMap iServer_HOME%webapps/iserver/WEB-INF, containing the followings:
<?xml version="1.0" encoding="UTF-8"?> <extendedOAuthSettings> <extendedOAuthSetting> <loginType>RENREN</loginType> <oAuth2ClientClass>com.supermap.services.rest.resources.impl.RenRenLoginExtended</oAuth2ClientClass> </extendedOAuthSetting> </extendedOAuthSettings>
The <extendedOAuthSettings> is the configuration set of third party login method extension. It can contains multiple <extendedOAuthSetting> labels. Each <extendedOAuthSetting> label corresponds to a third-party login extension configuration that follows the OAuth2 protocol. The contents in <extendedOAuthSetting> correspond to the configuration of ExtendedOAuthSetting:
Add the following contents to the root node of iserver-system.xml, which is located in iServer_HOME%webapps/iserver/WEB-INF:
<server> ... <oAuthConfigs> <oAuthConfig> <id>1</id> <enabled>true</enabled> <loginType>RENREN</loginType> <buttonText>Renren Login</buttonText> <clientSecret>b7544a9cc9524bac9641346f3720384b</clientSecret> <clientID>fc23a7eefde348cca487c3bab60861be</clientID> <redirectDomain>iserver.supermap.com</redirectDomain> <loginIcon>renren.png</loginIcon> </oAuthConfig> </oAuthConfigs> <!--<oAuthMetas> <oAuthMeta><meta property="qc:admins" content="4323423424235" /></oAuthMeta> </oAuthMetas>--> </server>
The <oAuthConfigs> is the configuration set of third party login method. It can contains multiple <oAuthConfig> labels. Each <oAuthConfig> label corresponds to a configuration of the login method. The contents in <oAuthConfig> correspond to the configuration of OAuthConfig :
<oAuthMetas> label represents the meta info (will be added to the HEAD label in the HTML codes in the first page ) used to verify website address. Extending the Renren account does not need to fill with in the meta data.
When you finish above steps, representing you have added the Renren login method. In the third party login configuration (http://iserver.supermap.com:8090/iserver/manager/security/oauthconfig), you can view the configuration. These information correspond to configuration in <oAuthConfig> label. Access the login page of iPortal, iServer or iEdge, you can see that the Renren account button is added. Please refer to Usage of Third-party Loogin for more information.