Java tutorial
package com.supermap.desktop.icloud.online; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.http.*; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; /** * Created by xie on 2016/12/24. * Online */ public class AuthenticatorImpl implements Authenticator { private HttpClientBuilder ssoHttpClientBuilder = null; public void setSsoHttpClientBuilder(HttpClientBuilder ssoHttpClientBuilder) { this.ssoHttpClientBuilder = ssoHttpClientBuilder.disableCookieManagement().disableRedirectHandling(); } /** * ??HttpClientLicenseServece???HttpClient * * @param token ? * @param clientBuilder HttpClient * @param service * @return * @throws AuthenticationException */ public CloseableHttpClient authenticate(UsernamePassword token, HttpClientBuilder clientBuilder, URL service) throws AuthenticationException { CloseableHttpClient client = this.ssoHttpClientBuilder.build(); try { String jSessionId = login(client, token, service); if (null == jSessionId) { return null; } clientBuilder.addInterceptorLast(new SessionIdCookie(jSessionId)); return clientBuilder.build(); } catch (IOException e) { throw new AuthenticationException(e); } finally { IOUtils.closeQuietly(client); } } /** * ?Onlinejsessionid * * @param client * @param token ??? * @param service ? * @return * @throws IOException * @throws AuthenticationException */ public String login(CloseableHttpClient client, UsernamePassword token, URL service) throws IOException, AuthenticationException { String ssoLoginUrl = getURI(service.toString()); RequestContent content = getSSOLoginParameter(client, ssoLoginUrl); String location = sendUsernamePassword(client, token, ssoLoginUrl, content); if (null == location) { return null; } return getJSessionId(client, location); } /** * ?SSOURL * * @param service * @return */ private String getURI(String service) { String uri = "https://sso.supermap.com/login?format=json"; if (StringUtils.isNotBlank(service)) { try { uri = uri + "&service=" + URLEncoder.encode(service, StandardCharsets.UTF_8.name()); } catch (UnsupportedEncodingException e) { throw new IllegalStateException( StandardCharsets.UTF_8.name() + " Unsupported. That's unacceptable!!", e); } } return uri; } /** * ?SSOjsessionid * get * * @param client * @param uri * @return * @throws IOException * @throws AuthenticationException */ private RequestContent getSSOLoginParameter(CloseableHttpClient client, String uri) throws IOException, AuthenticationException { HttpGet get = new HttpGet(uri); CloseableHttpResponse response = client.execute(get); try { return buildRequestContent(response); } finally { IOUtils.closeQuietly(response); } } /** * ?location:location?jsessionid,execution,_eventId,lt? * post * * @param client * @param token * @param uri * @param content * @return * @throws IOException * @throws AuthenticationException */ private String sendUsernamePassword(CloseableHttpClient client, UsernamePassword token, String uri, RequestContent content) throws IOException, AuthenticationException { HttpPost post = new HttpPost(uri); List<NameValuePair> formparams = new ArrayList(); formparams.add(new BasicNameValuePair("username", token.username)); formparams.add(new BasicNameValuePair("password", token.password)); formparams.add(new BasicNameValuePair("lt", content.lt)); formparams.add(new BasicNameValuePair("execution", content.execution)); formparams.add(new BasicNameValuePair("_eventId", content._eventId)); UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, StandardCharsets.UTF_8); post.setHeader("Cookie", content.jsessionid); post.setEntity(uefEntity); CloseableHttpResponse response = client.execute(post); try { int code = response.getStatusLine().getStatusCode(); if (code == 200) { return null; } if (code == 302) { Header header = response.getFirstHeader("Location"); if (header == null) { throw new AuthenticationException( "unexpected response:code 302 without Location response header"); } return header.getValue(); } String entity = getEntityText(response); throw new AuthenticationException("login failed. code:" + code + ";entity:" + entity); } finally { IOUtils.closeQuietly(response); } } /** * Entity?? * * @param response * @return * @throws ParseException * @throws IOException */ private String getEntityText(CloseableHttpResponse response) throws ParseException, IOException { HttpEntity entity = response.getEntity(); return entity == null ? null : EntityUtils.toString(entity, StandardCharsets.UTF_8); } /** * ?onlinejsessionid(id) * * @param client * @param location * @return ?jsessionid * @throws IOException * @throws AuthenticationException */ private String getJSessionId(CloseableHttpClient client, String location) throws IOException, AuthenticationException { HttpClientContext context = HttpClientContext.create(); HttpGet httpGetToCheckTicket = new HttpGet(location); CloseableHttpResponse response = client.execute(httpGetToCheckTicket, context); try { int code = response.getStatusLine().getStatusCode(); String result = getJSessionIdFromResponse(response); String entity; if ((code >= 400) || (StringUtils.isEmpty(result))) { entity = getEntityText(response); throw new AuthenticationException( "invalid response. url:" + location + ".code:" + code + "." + entity); } return result; } finally { response.close(); } } private RequestContent buildRequestContent(CloseableHttpResponse response) throws AuthenticationException, ParseException, IOException { RequestContent content = new RequestContent(); HttpEntity httpEntity = response.getEntity(); int code = response.getStatusLine().getStatusCode(); if (httpEntity == null) { throw new AuthenticationException("login failed.code:" + code); } String responseInfo = EntityUtils.toString(httpEntity, StandardCharsets.UTF_8); if (200 == response.getStatusLine().getStatusCode()) { try { content = JSON.parseObject(responseInfo, RequestContent.class); content.jsessionid = getJSessionIdFromResponse(response); } catch (JSONException e) { throw new AuthenticationException("invalid response:" + responseInfo); } finally { EntityUtils.consumeQuietly(httpEntity); } } else { throw new AuthenticationException("login failed.code:" + response.getStatusLine().getStatusCode() + ".response:" + getEntityText(response)); } return content; } /** * HttpRespose?jsessionid * * @param response * @return */ private String getJSessionIdFromResponse(HttpResponse response) { Header header = response.getFirstHeader("Set-Cookie"); if (header == null) { return ""; } String[] kvps = StringUtils.split(header.getValue(), ';'); for (String kvp : kvps) { int index = kvp.indexOf('='); if (StringUtils.equalsIgnoreCase(kvp.substring(0, index), "JSESSIONID")) { return kvp; } } return ""; } private static class SessionIdCookie implements HttpRequestInterceptor { private String jSessionId; SessionIdCookie(String paramSessionId) { this.jSessionId = paramSessionId; } public void process(HttpRequest request, HttpContext context) throws HttpException, IOException { request.setHeader("Cookie", this.jSessionId); } } /** * */ private static class RequestContent { public String lt; public String execution; public String _eventId; public String jsessionid; } }