Commits

明点软件  committed 57b61c4

增加淘宝OAuth2.0授权协议

  • Participants
  • Parent commits 5ae3f91

Comments (0)

Files changed (28)

 *.iml
 .idea/*
 out/*
+*.jar
 syntax: regexp
 ^Grails-spring-security-taobao-grailsPlugins\.iml$
 syntax: regexp

File Grails-spring-security-taobao.iml

       <sourceFolder url="file://$MODULE_DIR$/src/java" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/grails-app/utils" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/groovy" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/grails-app/i18n" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/grails-app/controllers" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/grails-app/domain" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/grails-app/services" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/grails-app/taglib" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/test/unit" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/test/integration" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/grails-app/i18n" isTestSource="false" />
       <excludeFolder url="file://$MODULE_DIR$/target/classes" />
     </content>
     <orderEntry type="inheritedJdk" />
         <JAVADOC />
         <SOURCES>
           <root url="jar://$MODULE_DIR$/spring-security-core-3.0.7.RELEASE-sources.jar!/" />
+          <root url="jar://$MODULE_DIR$/spring-security-web-3.0.7.RELEASE-sources.jar!/" />
         </SOURCES>
         <jarDirectory url="file://$MODULE_DIR$/lib" recursive="false" />
       </library>

File SpringSecurityTaobaoGrailsPlugin.groovy

 import com.mingidea.security.alibaba.AlibabaAuthenticationFilter
 import com.mingidea.security.alibaba.AlibabaAuthenticationFilter
 import com.mingidea.security.alibaba.AlibabaAuthenticationProvider
+import com.mingidea.security.taobao.oauth.TaobaoOAuthAuthenticationFilter
+import com.mingidea.security.taobao.oauth.TaobaoOAuthAuthenticationProvider
 import com.mingidea.security.taobao.top.TaobaoTopAuthenticationFilter
 import com.mingidea.security.taobao.top.TaobaoTopAuthenticationProvider
 import org.codehaus.groovy.grails.plugins.springsecurity.SecurityFilterPosition
 */
 class SpringSecurityTaobaoGrailsPlugin {
     // the plugin version
-    def version = "1.1"
+    def version = "1.1-BETA-6"
     // the version or versions of Grails the plugin is designed for
     def grailsVersion = "2.1 > *"
     // the other plugins this plugin depends on
         // have to get again after overlaying DefaultTaobaoSecurityConfig
         conf = SpringSecurityUtils.securityConfig
 
-        // 淘宝
-        if (conf.taobao.active) {
-            println 'Configuring Spring Security Taobao ...'
+        //淘宝OAuth2.0授权
+        if (conf.taobao.oauth.active) {
+            println 'Configuring Spring Security Taobao OAuth2.0 ...'
 
-            // 注册淘宝拦截器
-            SpringSecurityUtils.registerProvider 'taobaoAuthenticationProvider'
-            SpringSecurityUtils.registerFilter 'taobaoAuthenticationFilter', conf.taobao.filter.position
+            SpringSecurityUtils.registerProvider 'taobaoOAuthAuthenticationProvider'
+            SpringSecurityUtils.registerFilter 'taobaoOAuthAuthenticationFilter', conf.taobao.oauth.filter.position
 
-            taobaoAuthenticationProvider(TaobaoTopAuthenticationProvider) {
-                appSecretMap = conf.taobao.appSecretMap
+            taobaoOAuthAuthenticationProvider(TaobaoOAuthAuthenticationProvider) {
+                appConfigs = conf.taobao.oauth.appConfigs
                 authenticationDao = ref('taobaoAuthenticationDao')
             }
 
-            taobaoAuthenticationFilter(TaobaoTopAuthenticationFilter, conf.taobao.filter.processUrl){
+            taobaoOAuthAuthenticationFilter(TaobaoOAuthAuthenticationFilter, conf.taobao.oauth.filter.processUrl){
                 authenticationManager = ref('authenticationManager')
                 sessionAuthenticationStrategy = ref('sessionAuthenticationStrategy')
 
             }
         }
 
+        // 淘宝TOP授权
+        if (conf.taobao.top.active) {
+            println 'Configuring Spring Security Taobao Top ...'
+
+            SpringSecurityUtils.registerProvider 'taobaoTopAuthenticationProvider'
+            SpringSecurityUtils.registerFilter 'taobaoTopAuthenticationFilter', conf.taobao.top.filter.position
+
+            taobaoTopAuthenticationProvider(TaobaoTopAuthenticationProvider) {
+                appSecretMap = conf.taobao.top.appSecretMap
+                authenticationDao = ref('taobaoAuthenticationDao')
+            }
+
+            taobaoTopAuthenticationFilter(TaobaoTopAuthenticationFilter, conf.taobao.top.filter.processUrl){
+                authenticationManager = ref('authenticationManager')
+                sessionAuthenticationStrategy = ref('sessionAuthenticationStrategy')
+
+                //ref to grails spring security core plugin
+                authenticationSuccessHandler = ref('authenticationSuccessHandler')
+                authenticationFailureHandler = ref('authenticationFailureHandler')
+                rememberMeServices = ref('rememberMeServices')
+                allowSessionCreation = conf.apf.allowSessionCreation
+            }
+        }
+
+        //阿里巴巴OAuth2.0授权
         if (conf.alibaba.active) {
-            println 'Configuring Spring Security Alibaba ...'
+            println 'Configuring Spring Security Alibaba OAuth2.0 ...'
 
             // 注册阿里巴巴拦截器
             SpringSecurityUtils.registerProvider 'alibabaAuthenticationProvider'
             SpringSecurityUtils.registerFilter 'alibabaAuthenticationFilter', conf.alibaba.filter.position
 
             alibabaAuthenticationProvider(AlibabaAuthenticationProvider) {
-                appSecretMap = conf.alibaba.appSecretMap
+                appConfigs = conf.alibaba.appConfigs
                 authenticationDao = ref('alibabaAuthenticationDao')
             }
 

File grails-app/conf/Config.groovy

     //
     
     root {
-        debug 'stdout'
+        info 'stdout'
     }
     appenders {
         console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
 grails.plugins.springsecurity.authority.className = 'test.Role'
 grails.plugins.springsecurity.taobao.accountDomainClassName = 'test.TaobaoAccount'
 
+grails.plugins.springsecurity.taobao.oauth.appConfigs = [
+    [appKey: '21320510', appSecret: '1cc57599a18e865d168a05cedca8e0b8', redirectUrl: 'http://dev.mingidea.com/spring-security-taobao/j_spring_taobao_oauth_security_check?appKey=21320510']
+]
+//test_app_1的appkey 和 appscert
+grails.plugins.springsecurity.taobao.top.appSecretMap = ['12264981' : '4aaaabc0a7057c3fd36b8de889d4aa65']
 
-//test_app_1的appkey 和 appscert
-grails.plugins.springsecurity.taobao.appSecretMap = ['12264981' : '4aaaabc0a7057c3fd36b8de889d4aa65']
-
-grails.plugins.springsecurity.alibaba.appSecretMap = ['1003921' : 'K=PQvl]lhhq']
+grails.plugins.springsecurity.alibaba.appConfigs = [
+        [ appKey: '1003955', appSecret: 'sFe1l9l-1J', redirectUrl: "http://dev.mingidea.com:8080/spring-security-taobao/j_spring_alibaba_security_check?appKey=1003955"]
+]
 
 grails.plugins.springsecurity.securityConfigType = "InterceptUrlMap"
 grails.plugins.springsecurity.interceptUrlMap = [

File grails-app/conf/DefaultTaobaoSecurityConfig.groovy

 security {
     maxConcurrentSessions = -1
     taobao {
-        //appKey -> appSecret
-        appSecretMap = [:]
-        active = true
-        filter {
-            processUrl = '/j_spring_taobao_security_check'
-            position = 900 // 和OPEN_ID位置一样
+        oauth {
+            appConfigs = []
+            active = true
+            filter {
+                processUrl = '/j_spring_taobao_oauth_security_check'
+                position = 901
+            }
+        }
+        top {
+            //appKey -> appSecret
+            appSecretMap = [:]
+            active = true
+            filter {
+                processUrl = '/j_spring_taobao_security_check'
+                position = 902
+            }
         }
     }
 
     alibaba {
-        appSecretMap = [:]
+        appConfigs = []
         active = true
         filter {
             processUrl = '/j_spring_alibaba_security_check'
-            position = 901
+            position = 903
         }
     }
 }
-<plugin name='spring-security-taobao' version='1.1-BATE-2' grailsVersion='2.1 &gt; *'>
+<plugin name='spring-security-taobao' version='1.1-BETA-6' grailsVersion='2.1 &gt; *'>
   <author>Simon Leung</author>
   <authorEmail>simon.r.leung@gmail.com</authorEmail>
   <title>Spring Security Taobao Plugin</title>

File src/groovy/test/TestAlibabaAuthenticationDao.groovy

 
 import com.mingidea.security.AuthenticationDao
 import com.mingidea.security.alibaba.AlibabaUser
+import com.mingidea.security.oauth.OAuthUser
 import org.springframework.security.core.userdetails.UserDetails
 
 /**

File src/java/com/mingidea/security/User.java

 
     @Override
     public String toString() {
-        return ToStringBuilder.reflectionToString(this, ToStringStyle.SIMPLE_STYLE);
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
     }
 }

File src/java/com/mingidea/security/alibaba/AlibabaAuthenticationFilter.java

 package com.mingidea.security.alibaba;
 
 import com.mingidea.security.AuthenticationToken;
+import com.mingidea.security.oauth.OAuthCredentials;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
     public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
         String appKey = request.getParameter("appKey");
         String code = request.getParameter("code");
-        AlibabaCredentials credentials = new AlibabaCredentials(appKey, code);
+        OAuthCredentials credentials = new OAuthCredentials(appKey, code);
         AlibabaAuthenticationToken token = new AlibabaAuthenticationToken(credentials);
 
         // delegate to the authentication provider

File src/java/com/mingidea/security/alibaba/AlibabaAuthenticationProvider.java

 package com.mingidea.security.alibaba;
 
-import com.google.gson.FieldNamingPolicy;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
+import com.google.gson.*;
 import com.mingidea.security.AbstractAuthenticationProvider;
+import com.mingidea.security.oauth.AbstractOAuthAuthenticationProvider;
+import com.mingidea.security.oauth.AppConfig;
+import com.mingidea.security.oauth.OAuthUser;
 import com.mingidea.security.util.HttpUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.util.Assert;
 
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
  * @author Liang Yong Rui
  */
-public class AlibabaAuthenticationProvider extends AbstractAuthenticationProvider<AlibabaUser> implements InitializingBean {
+public class AlibabaAuthenticationProvider extends AbstractOAuthAuthenticationProvider<AlibabaUser> implements InitializingBean {
     private static Logger log = LoggerFactory.getLogger(AlibabaAuthenticationProvider.class);
-    private static Gson gson = new GsonBuilder()
-                                    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
-                                    .create();
-
-
-    /**
-     * appKey to appSecret mapping
-     */
-    private Map<String, String> appSecretMap;
+    private static JsonParser jsonParser = new JsonParser();
 
     @Override
-    protected AlibabaUser validateCredentials(Object credentials) {
-        AlibabaCredentials alibabaCredentials = (AlibabaCredentials)credentials;
-        String appKey = alibabaCredentials.getAppKey();
-        String code = alibabaCredentials.getCode();
-        OAuthToken oAuthToken = getOAuthToken(appKey, code);
-
-        AlibabaUser user = new AlibabaUser(oAuthToken.resourceOwner, appKey);
-        user.setAccessToken(oAuthToken.getAccessToken());
-        user.setRefreshToken(oAuthToken.getRefreshToken());
-        user.setExpiresIn(oAuthToken.getExpiresIn());
-
-        return user;
+    protected String getTokenUrl(String appKey) {
+        return "https://gw.open.china.alibaba.com/openapi/http/1/system.oauth2/getToken/" + appKey;
     }
 
-    private OAuthToken getOAuthToken(String appKey, String code) {
-        String url = "https://gw.open.china.alibaba.com/openapi/http/1/system.oauth2/getToken/" + appKey;
-        String parameters = buildOAuthTokenParameters(appKey, code);
-        String json = null;
-        try {
-            json = HttpUtils.post(url, parameters);
-        } catch (IOException e) {
-            log.error("fail to get oauth token", e);
-            throw new BadCredentialsException("fail to get oauth token", e);
+    @Override
+    protected Map<String, String> getTokenParameters(String appKey, String code) {
+        AppConfig appConfig = getAppConfig(appKey);
+        if (appConfig == null) {
+            throw new BadCredentialsException("can't not find app config for appKey: " + appKey);
         }
-        return gson.fromJson(json, OAuthToken.class);
+
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("grant_type", "authorization_code");
+        parameters.put("need_refresh_token", "true");
+        parameters.put("client_id", appKey);
+        parameters.put("client_secret", appConfig.getAppSecret());
+        parameters.put("redirect_uri", appConfig.getAppKey());
+        parameters.put("code", code);
+
+        return parameters;
     }
 
-    private String buildOAuthTokenParameters(String appKey, String code) {
-        String appSecret = appSecretMap.get(appKey);
-        if (appSecret == null) {
-            throw new BadCredentialsException("can't not find appSecret for appKey: " + appKey);
-        }
+    @Override
+    protected AlibabaUser parseToken(String appKey, String jsonString) {
+        JsonObject json = jsonParser.parse(jsonString).getAsJsonObject();
+        String resourceOwner = json.get("resource_owner").getAsString();
+        String accessToken = json.get("access_token").getAsString();
+        String refreshToken = json.get("refresh_token").getAsString();
+        long expiresIn = json.get("expires_in").getAsLong();
 
-        return new StringBuilder()
-                .append("grant_type=authorization_code&need_refresh_token=true&client_id=")
-                .append(appKey)
-                .append("&client_secret=")
-                .append(HttpUtils.encodeUrl(appSecret))
-                .append("&redirect_uri=")
-                //TODO 动态配置
-                .append(HttpUtils.encodeUrl("http://dev.mingidea.com:8080/spring-security-taobao/j_spring_alibaba_security_check?appKey=1003921"))
-                .append("&code=")
-                .append(code)
-                .toString();
-    }
-
-    public void setAppSecretMap(Map<String, String> appSecretMap) {
-        this.appSecretMap = appSecretMap;
+        AlibabaUser user = new AlibabaUser(appKey, resourceOwner);
+        user.setAccessToken(accessToken);
+        user.setRefreshToken(refreshToken);
+        user.setExpiresIn(expiresIn);
+        return user;
     }
 
     @Override
 
     @Override
     public void afterPropertiesSet() throws Exception {
-        Assert.notNull(appSecretMap, "The appSecretMap property can't be null");
-    }
-
-    private class OAuthToken {
-        private String resourceOwner;
-        private Long expiresIn;
-        private String accessToken;
-        private String refreshToken;
-
-        public String getResourceOwner() {
-            return resourceOwner;
-        }
-
-        public void setResourceOwner(String resourceOwner) {
-            this.resourceOwner = resourceOwner;
-        }
-
-        public Long getExpiresIn() {
-            return expiresIn;
-        }
-
-        public void setExpiresIn(Long expiresIn) {
-            this.expiresIn = expiresIn;
-        }
-
-        public String getAccessToken() {
-            return accessToken;
-        }
-
-        public void setAccessToken(String accessToken) {
-            this.accessToken = accessToken;
-        }
-
-        public String getRefreshToken() {
-            return refreshToken;
-        }
-
-        public void setRefreshToken(String refreshToken) {
-            this.refreshToken = refreshToken;
-        }
+        Assert.isTrue(getAppConfigs().size() > 0, "The appConfigs must not be empty");
     }
 }

File src/java/com/mingidea/security/alibaba/AlibabaAuthenticationToken.java

 package com.mingidea.security.alibaba;
 
 import com.mingidea.security.AuthenticationToken;
+import com.mingidea.security.oauth.OAuthCredentials;
 import org.springframework.security.core.userdetails.UserDetails;
 
 import java.util.Collection;
 /**
  * @author Liang Yong Rui
  */
-public class AlibabaAuthenticationToken extends AuthenticationToken<AlibabaCredentials> {
+public class AlibabaAuthenticationToken extends AuthenticationToken<OAuthCredentials> {
 
-    public AlibabaAuthenticationToken(AlibabaCredentials credentials) {
+    public AlibabaAuthenticationToken(OAuthCredentials credentials) {
         super(credentials);
     }
 

File src/java/com/mingidea/security/alibaba/AlibabaCredentials.java

-package com.mingidea.security.alibaba;
-
-import java.io.Serializable;
-
-/**
- * 阿里巴巴OAuth登陆证书
- * @author Liang Yong Rui
- */
-public class AlibabaCredentials implements Serializable {
-    private static final long serialVersionUID = 1L;
-    private String appKey;
-    private String code;
-
-    public AlibabaCredentials(String appKey, String code) {
-        this.appKey = appKey;
-        this.code = code;
-    }
-
-    public String getAppKey() {
-        return appKey;
-    }
-
-    public String getCode() {
-        return code;
-    }
-}

File src/java/com/mingidea/security/alibaba/AlibabaUser.java

-package com.mingidea.security.alibaba;
-
-import com.mingidea.security.User;
-
-/**
- * @author Liang Yong Rui
- */
-public class AlibabaUser extends User {
-    private String accessToken;
-    private String refreshToken;
-    private Long expiresIn;
-
-    public AlibabaUser(String id, String appKey) {
-        super(id, appKey);
-    }
-
-    public String getAccessToken() {
-        return accessToken;
-    }
-
-    public void setAccessToken(String accessToken) {
-        this.accessToken = accessToken;
-    }
-
-    public String getRefreshToken() {
-        return refreshToken;
-    }
-
-    public void setRefreshToken(String refreshToken) {
-        this.refreshToken = refreshToken;
-    }
-
-    public Long getExpiresIn() {
-        return expiresIn;
-    }
-
-    public void setExpiresIn(Long expiresIn) {
-        this.expiresIn = expiresIn;
-    }
-}

File src/java/com/mingidea/security/oauth/AbstractOAuthAuthenticationProvider.java

+package com.mingidea.security.oauth;
+
+import com.google.gson.JsonParser;
+import com.mingidea.security.AbstractAuthenticationProvider;
+import com.mingidea.security.util.HttpUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.BadCredentialsException;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Liang Yong Rui
+ */
+public abstract class AbstractOAuthAuthenticationProvider<T extends OAuthUser> extends AbstractAuthenticationProvider<T> {
+    private static Logger log = LoggerFactory.getLogger(AbstractOAuthAuthenticationProvider.class);
+
+    /**
+     * appKey -> AppConfig的映射
+     * <p/>
+     * 在配置文件中的格式:
+     * [
+     * [appKey: "565656", appSecret: "3adf=333", redirectUri: "http://dev.mingidea.com"],
+     * [appKey: "565656", appSecret: "3adf=333", redirectUri: "http://dev.mingidea.com"]
+     * ]
+     */
+    private Map<String, AppConfig> appConfigs = new HashMap<String, AppConfig>();
+
+    @Override
+    protected T validateCredentials(Object credentials) {
+        OAuthCredentials oAuthCredentials = (OAuthCredentials) credentials;
+        String appKey = oAuthCredentials.getAppKey();
+        String code = oAuthCredentials.getCode();
+
+        String getTokenUrl = getTokenUrl(appKey);
+        Map<String, String> getTokenParameters = getTokenParameters(appKey, code);
+
+        try {
+            String tokenJson = HttpUtils.post(getTokenUrl, getTokenParameters);
+            return parseToken(appKey, tokenJson);
+        } catch (Exception e) {
+            log.error("fail to get oauth token, appKey:" + appKey, e);
+            throw new BadCredentialsException("fail to get oauth token", e);
+        }
+    }
+
+
+    public void setAppConfigs(List<Map<String, String>> appConfigMaps) {
+        // 将map格式的配置转换为AppConfig对象
+        for (Map<String, String> appConfigMap : appConfigMaps) {
+            String appKey = appConfigMap.get("appKey");
+            String appSecret = appConfigMap.get("appSecret");
+            String redirectUrl = appConfigMap.get("redirectUrl");
+
+            AppConfig appConfig = new AppConfig(appKey, appSecret, redirectUrl);
+            appConfigs.put(appKey, appConfig);
+        }
+    }
+
+    protected Map<String, AppConfig> getAppConfigs() {
+        return appConfigs;
+    }
+
+    protected AppConfig getAppConfig(String appKey) {
+        return appConfigs.get(appKey);
+    }
+
+    protected abstract String getTokenUrl(String appKey);
+
+    protected abstract Map<String, String> getTokenParameters(String appKey, String code);
+
+    /**
+     * 将token json解析成相应的User对象
+     */
+    protected abstract T parseToken(String appKey, String json);
+}

File src/java/com/mingidea/security/oauth/AppConfig.java

+package com.mingidea.security.oauth;
+
+/**
+ * @author Liang Yong Rui
+ */
+public class AppConfig {
+    private String appKey;
+    private String appSecret;
+    private String redirectUrl;
+
+    public AppConfig(String appKey, String appSecret, String redirectUrl) {
+        this.appKey = appKey;
+        this.appSecret = appSecret;
+        this.redirectUrl = redirectUrl;
+    }
+
+    public String getAppKey() {
+        return appKey;
+    }
+
+    public void setAppKey(String appKey) {
+        this.appKey = appKey;
+    }
+
+    public String getRedirectUrl() {
+        return redirectUrl;
+    }
+
+    public void setRedirectUrl(String redirectUrl) {
+        this.redirectUrl = redirectUrl;
+    }
+
+    public String getAppSecret() {
+        return appSecret;
+    }
+
+    public void setAppSecret(String appSecret) {
+        this.appSecret = appSecret;
+    }
+}

File src/java/com/mingidea/security/oauth/OAuthAuthenticationFilter.java

+package com.mingidea.security.oauth;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * @author Liang Yong Rui
+ */
+public class OAuthAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
+    protected OAuthAuthenticationFilter(String defaultFilterProcessesUrl) {
+        super(defaultFilterProcessesUrl);
+    }
+
+    @Override
+    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
+        return null;
+    }
+}

File src/java/com/mingidea/security/oauth/OAuthCredentials.java

+package com.mingidea.security.oauth;
+
+import java.io.Serializable;
+
+/**
+ * @author Liang Yong Rui
+ */
+public class OAuthCredentials implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private String appKey;
+    private String code;
+
+    public OAuthCredentials(String appKey, String code) {
+        this.appKey = appKey;
+        this.code = code;
+    }
+
+    public String getAppKey() {
+        return appKey;
+    }
+
+    public String getCode() {
+        return code;
+    }
+}

File src/java/com/mingidea/security/oauth/OAuthUser.java

+package com.mingidea.security.oauth;
+
+import com.mingidea.security.User;
+
+/**
+ * @author Liang Yong Rui
+ */
+public class OAuthUser extends User {
+    private String accessToken;
+    private String refreshToken;
+    private long expiresIn;
+
+    public OAuthUser(String userId, String appKey) {
+        super(userId, appKey);
+    }
+
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
+
+    public String getRefreshToken() {
+        return refreshToken;
+    }
+
+    public void setRefreshToken(String refreshToken) {
+        this.refreshToken = refreshToken;
+    }
+
+    public Long getExpiresIn() {
+        return expiresIn;
+    }
+
+    public void setExpiresIn(long expiresIn) {
+        this.expiresIn = expiresIn;
+    }
+}

File src/java/com/mingidea/security/taobao/TaobaoCredentials.java

-package com.mingidea.security.taobao;
-
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.Assert;
-
-/**
- * 表示淘宝登陆的回调参数。
- * 参考:
- * <a href="http://open.taobao.com/doc/category_list.htm?id=199">用户授权介绍</a>
- *
- * @author Simon Leung
- * @since 0.1
- */
-public class TaobaoCredentials implements Serializable {
-    private static final long serialVersionUID = 1L;
-    private static Logger log = LoggerFactory.getLogger(TaobaoCredentials.class);
-
-    private String appKey;
-    private String session;
-    private String parameters;
-    private String sign;
-
-    //上下文参数,从top_parameters中解析所得
-    private long timestamp;
-    private String iframe;
-    private String visitorId;
-    private String visitorNick;
-    private String visitorRole;
-
-    private long expiresIn;
-    private long r1ExpiresIn;
-    private long r2ExpiresIn;
-    private long w1ExpiresIn;
-    private long w2ExpiresIn;
-    private long reExpiresIn;
-
-    private String refreshToken;
-    private String subTaobaoUserId;
-    private String subTaobaoUserNick;
-
-    private TaobaoCredentials() {
-        //Can not be instantiated directly,use #build()
-    }
-
-    /**
-     * Build a TaobaoCredentials instance by HTTP request.
-     *
-     * @param request
-     * @return
-     */
-    public static TaobaoCredentials build(HttpServletRequest request) {
-        Assert.notNull(request, "The request can't be null");
-        TaobaoCredentials credentials = new TaobaoCredentials();
-        credentials.appKey = request.getParameter("top_appkey");
-        credentials.session = request.getParameter("top_session");
-        //base64 encoded
-        String parameters = request.getParameter("top_parameters");
-        credentials.parameters = parameters;
-        credentials.sign = request.getParameter("top_sign");
-
-        if (parameters != null) {
-            String charsetParameter = request.getParameter("encode");
-            String charset = charsetParameter == null ? "GBK" : charsetParameter;
-            String decodedParameters = null;
-            try {
-                decodedParameters = new String(Base64.decodeBase64(parameters), charset);
-            } catch (UnsupportedEncodingException e) {
-                //ignore
-            }
-            log.debug("top parameters: {}", decodedParameters);
-            Map<String, String> parameterMap = parseParameters(decodedParameters);
-            credentials.timestamp = Long.parseLong(parameterMap.get("ts"));
-            credentials.iframe = parameterMap.get("iframe");
-            credentials.visitorId = parameterMap.get("visitor_id");
-            credentials.visitorNick = parameterMap.get("visitor_nick");
-            credentials.visitorRole = parameterMap.get("visitor_role");
-
-            credentials.expiresIn = toLong(parameterMap.get("expires_in"));
-            credentials.r1ExpiresIn = toLong(parameterMap.get("r1_expires_in"));
-            credentials.r2ExpiresIn = toLong(parameterMap.get("r2_expires_in"));
-            credentials.w1ExpiresIn = toLong(parameterMap.get("w1_expires_in"));
-            credentials.w2ExpiresIn = toLong(parameterMap.get("w2_expires_in"));
-            credentials.reExpiresIn = toLong(parameterMap.get("re_expires_in"));
-
-            credentials.refreshToken = parameterMap.get("refresh_token");
-            credentials.subTaobaoUserId = parameterMap.get("sub_taobao_user_id");
-            credentials.subTaobaoUserNick = parameterMap.get("sub_taobao_user_nick");
-        }
-
-        return credentials;
-    }
-
-    private static long toLong(String str) {
-        if (str == null) {
-            return 0L;
-        }
-        try {
-            return Long.parseLong(str);
-        } catch (NumberFormatException nfe) {
-            return 0L;
-        }
-    }
-
-    /**
-     * 将URL参数解析成Map
-     *
-     * @param parameters like:key1=value1&key2=value2……
-     * @return key value map
-     */
-    private static Map<String, String> parseParameters(String parameters) {
-        Map<String, String> map = new HashMap<String, String>();
-        String[] pairs = StringUtils.split(parameters, "&");
-        for (String pair : pairs) {
-            String[] keyValue = StringUtils.split(pair, "=");
-            map.put(keyValue[0], keyValue[1]);
-        }
-        return map;
-    }
-
-    public String getParameters() {
-        return parameters;
-    }
-
-    public String getSession() {
-        return session;
-    }
-
-    public String getAppKey() {
-        return appKey;
-    }
-
-    public String getSign() {
-        return sign;
-    }
-
-    public long getTimestamp() {
-        return timestamp;
-    }
-
-    public String getIframe() {
-        return iframe;
-    }
-
-    public String getVisitorId() {
-        return visitorId;
-    }
-
-    public String getVisitorNick() {
-        return visitorNick;
-    }
-
-    public String getVisitorRole() {
-        return visitorRole;
-    }
-
-    public long getExpiresIn() {
-        return expiresIn;
-    }
-
-    public void setExpiresIn(long expiresIn) {
-        this.expiresIn = expiresIn;
-    }
-
-    public long getR1ExpiresIn() {
-        return r1ExpiresIn;
-    }
-
-    public void setR1ExpiresIn(long r1ExpiresIn) {
-        this.r1ExpiresIn = r1ExpiresIn;
-    }
-
-    public long getR2ExpiresIn() {
-        return r2ExpiresIn;
-    }
-
-    public void setR2ExpiresIn(long r2ExpiresIn) {
-        this.r2ExpiresIn = r2ExpiresIn;
-    }
-
-    public long getW1ExpiresIn() {
-        return w1ExpiresIn;
-    }
-
-    public void setW1ExpiresIn(long w1ExpiresIn) {
-        this.w1ExpiresIn = w1ExpiresIn;
-    }
-
-    public long getW2ExpiresIn() {
-        return w2ExpiresIn;
-    }
-
-    public void setW2ExpiresIn(long w2ExpiresIn) {
-        this.w2ExpiresIn = w2ExpiresIn;
-    }
-
-    public long getReExpiresIn() {
-        return reExpiresIn;
-    }
-
-    public void setReExpiresIn(long reExpiresIn) {
-        this.reExpiresIn = reExpiresIn;
-    }
-
-    public String getRefreshToken() {
-        return refreshToken;
-    }
-
-    public void setRefreshToken(String refreshToken) {
-        this.refreshToken = refreshToken;
-    }
-
-    public String getSubTaobaoUserId() {
-        return subTaobaoUserId;
-    }
-
-    public void setSubTaobaoUserId(String subTaobaoUserId) {
-        this.subTaobaoUserId = subTaobaoUserId;
-    }
-
-    public String getSubTaobaoUserNick() {
-        return subTaobaoUserNick;
-    }
-
-    public void setSubTaobaoUserNick(String subTaobaoUserNick) {
-        this.subTaobaoUserNick = subTaobaoUserNick;
-    }
-}

File src/java/com/mingidea/security/taobao/TaobaoUser.java

 package com.mingidea.security.taobao;
 
-import com.mingidea.security.User;
+import com.mingidea.security.oauth.OAuthUser;
 
-public class TaobaoUser extends User {
-    private String session;
-
+public class TaobaoUser extends OAuthUser {
+    /** 授权时的时间戳,单位毫秒 */
     private long timestamp;
 
-    /** sesion key 失效时间 */
-    private long expiresIn;
+    /** R1级别API授权时长, 单位秒*/
+    private long r1ExpiresIn;
 
-    private long r1ExpiresIn;
+    /** R2级别API授权时长, 单位秒*/
     private long r2ExpiresIn;
+
+    /** W1级别API授权时长, 单位秒*/
     private long w1ExpiresIn;
+
+    /** W2级别API授权时长, 单位秒*/
     private long w2ExpiresIn;
 
-    /** refresh token 失效时间 */
+    /** refresh token 失效时间, 单位秒 */
     private long reExpiresIn;
 
-    private String refreshToken;
 
     public TaobaoUser(String userId, String appKey) {
         super(userId, appKey);
     }
 
-    public String getSession() {
-        return session;
-    }
-
-    public void setSession(String session) {
-        this.session = session;
-    }
-
     public long getTimestamp() {
         return timestamp;
     }
         this.timestamp = timestamp;
     }
 
-    public long getExpiresIn() {
-        return expiresIn;
-    }
-
-    public void setExpiresIn(long expiresIn) {
-        this.expiresIn = expiresIn;
-    }
-
     public long getR1ExpiresIn() {
         return r1ExpiresIn;
     }
     public void setReExpiresIn(long reExpiresIn) {
         this.reExpiresIn = reExpiresIn;
     }
-
-    public String getRefreshToken() {
-        return refreshToken;
-    }
-
-    public void setRefreshToken(String refreshToken) {
-        this.refreshToken = refreshToken;
-    }
 }

File src/java/com/mingidea/security/taobao/oauth/TaobaoOAuthAuthenticationFilter.java

 package com.mingidea.security.taobao.oauth;
 
+import com.mingidea.security.oauth.OAuthCredentials;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
 /**
  * @author Liang Yong Rui
  */
-public class TaobaoOAuthAuthenticationFilter {
+public class TaobaoOAuthAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
+    public TaobaoOAuthAuthenticationFilter(String defaultFilterProcessesUrl) {
+        super(defaultFilterProcessesUrl);
+    }
+
+    @Override
+    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
+        String appKey = request.getParameter("appKey");
+        String code = request.getParameter("code");
+        OAuthCredentials credentials = new OAuthCredentials(appKey, code);
+        TaobaoOAuthAuthenticationToken token = new TaobaoOAuthAuthenticationToken(credentials);
+
+        // delegate to the authentication provider
+        Authentication authentication = this.getAuthenticationManager().authenticate(token);
+
+        return authentication;
+    }
 }

File src/java/com/mingidea/security/taobao/oauth/TaobaoOAuthAuthenticationProvider.java

+package com.mingidea.security.taobao.oauth;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.mingidea.security.oauth.AbstractOAuthAuthenticationProvider;
+import com.mingidea.security.oauth.AppConfig;
+import com.mingidea.security.taobao.TaobaoUser;
+import org.springframework.security.authentication.BadCredentialsException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Liang Yong Rui
+ */
+public class TaobaoOAuthAuthenticationProvider extends AbstractOAuthAuthenticationProvider<TaobaoUser> {
+    private static JsonParser jsonParser = new JsonParser();
+
+    @Override
+    protected String getTokenUrl(String appKey) {
+        return "https://oauth.taobao.com/token";
+    }
+
+    @Override
+    protected Map<String, String> getTokenParameters(String appKey, String code) {
+        AppConfig appConfig = getAppConfig(appKey);
+        if (appConfig == null) {
+            throw new BadCredentialsException("can't not find app config for appKey: " + appKey);
+        }
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("client_id", appKey);
+        parameters.put("client_secret", appConfig.getAppSecret());
+        parameters.put("grant_type", "authorization_code");
+        parameters.put("code", code);
+        parameters.put("redirect_uri", appConfig.getRedirectUrl());
+
+        return parameters;
+    }
+
+    @Override
+    protected TaobaoUser parseToken(String appKey, String jsonString) {
+        JsonObject json = jsonParser.parse(jsonString).getAsJsonObject();
+        JsonElement taobaoUserNick = json.get("taobao_user_nick");
+        JsonElement subTaobaoUserNick = json.get("sub_taobao_user_nick");
+        String userId = subTaobaoUserNick == null ? taobaoUserNick.getAsString() : subTaobaoUserNick.getAsString();
+
+        String accessToken = json.get("access_token").getAsString();
+        String refreshToken = json.get("refresh_token").getAsString();
+
+        long expiresIn = json.get("expires_in").getAsLong();
+        long reExpiresIn = json.get("re_expires_in").getAsLong();
+        long r1ExpiresIn = json.get("r1_expires_in").getAsLong();
+        long r2ExpiresIn = json.get("r2_expires_in").getAsLong();
+        long w1ExpiresIn = json.get("w1_expires_in").getAsLong();
+        long w2ExpiresIn = json.get("w2_expires_in").getAsLong();
+
+        TaobaoUser user = new TaobaoUser(userId, appKey);
+        user.setAccessToken(accessToken);
+        user.setRefreshToken(refreshToken);
+        user.setTimestamp(System.currentTimeMillis());
+        user.setExpiresIn(expiresIn);
+        user.setReExpiresIn(reExpiresIn);
+        user.setR1ExpiresIn(r1ExpiresIn);
+        user.setR2ExpiresIn(r2ExpiresIn);
+        user.setW1ExpiresIn(w1ExpiresIn);
+        user.setW2ExpiresIn(w2ExpiresIn);
+
+        return user;
+    }
+
+    @Override
+    public boolean supports(Class<? extends Object> authenticationClass) {
+        return TaobaoOAuthAuthenticationToken.class.isAssignableFrom(authenticationClass);
+    }
+}

File src/java/com/mingidea/security/taobao/oauth/TaobaoOAuthAuthenticationToken.java

+package com.mingidea.security.taobao.oauth;
+
+import com.mingidea.security.AuthenticationToken;
+import com.mingidea.security.oauth.OAuthCredentials;
+import org.springframework.security.core.userdetails.UserDetails;
+
+/**
+ * @author Liang Yong Rui
+ */
+public class TaobaoOAuthAuthenticationToken extends AuthenticationToken<OAuthCredentials> {
+    public TaobaoOAuthAuthenticationToken(OAuthCredentials credentials) {
+        super(credentials);
+    }
+
+    public TaobaoOAuthAuthenticationToken(UserDetails principal) {
+        super(principal);
+    }
+}

File src/java/com/mingidea/security/taobao/top/TaobaoTopAuthenticationFilter.java

 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import com.mingidea.security.taobao.TaobaoCredentials;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.core.Authentication;
     public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
         throws AuthenticationException, IOException, ServletException {
 
-        TaobaoCredentials credentials = TaobaoCredentials.build(request);
+        TaobaoTopCredentials credentials = TaobaoTopCredentials.build(request);
         TaobaoTopAuthenticationToken token = new TaobaoTopAuthenticationToken(credentials);
         // delegate to the authentication provider
         Authentication authentication = this.getAuthenticationManager().authenticate(token);

File src/java/com/mingidea/security/taobao/top/TaobaoTopAuthenticationProvider.java

 
 import com.mingidea.security.AbstractAuthenticationProvider;
 import com.mingidea.security.taobao.*;
-import com.mingidea.security.taobao.TaobaoCredentials;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.slf4j.Logger;
 
     @Override
     protected TaobaoUser validateCredentials(Object credentials) {
-        TaobaoCredentials taobaoCredentials = (TaobaoCredentials)credentials;
+        TaobaoTopCredentials taobaoCredentials = (TaobaoTopCredentials)credentials;
 
         String appKey = taobaoCredentials.getAppKey();
         String parameters = taobaoCredentials.getParameters();
     /**
      * copy properties from credentials to taobao user
      */
-    private void copyProperties(TaobaoCredentials credentials, TaobaoUser taobaoUser) {
+    private void copyProperties(TaobaoTopCredentials credentials, TaobaoUser taobaoUser) {
         taobaoUser.setSession(credentials.getSession());
+        taobaoUser.setAccessToken(credentials.getSession());
+        taobaoUser.setRefreshToken(credentials.getRefreshToken());
+        taobaoUser.setReExpiresIn(credentials.getReExpiresIn());
         taobaoUser.setTimestamp(credentials.getTimestamp());
         taobaoUser.setExpiresIn(credentials.getExpiresIn());
         taobaoUser.setR1ExpiresIn(credentials.getR1ExpiresIn());
         taobaoUser.setR2ExpiresIn(credentials.getR2ExpiresIn());
         taobaoUser.setW1ExpiresIn(credentials.getW1ExpiresIn());
         taobaoUser.setW2ExpiresIn(credentials.getW2ExpiresIn());
-        taobaoUser.setRefreshToken(credentials.getRefreshToken());
-        taobaoUser.setReExpiresIn(credentials.getReExpiresIn());
     }
 
 

File src/java/com/mingidea/security/taobao/top/TaobaoTopAuthenticationToken.java

 package com.mingidea.security.taobao.top;
 
 import com.mingidea.security.AuthenticationToken;
-import com.mingidea.security.taobao.TaobaoCredentials;
 import org.springframework.security.core.userdetails.UserDetails;
 
-public class TaobaoTopAuthenticationToken extends AuthenticationToken<TaobaoCredentials> {
-    public TaobaoTopAuthenticationToken(TaobaoCredentials credentials) {
+public class TaobaoTopAuthenticationToken extends AuthenticationToken<TaobaoTopCredentials> {
+    public TaobaoTopAuthenticationToken(TaobaoTopCredentials credentials) {
         super(credentials);
     }
 

File src/java/com/mingidea/security/taobao/top/TaobaoTopCredentials.java

+package com.mingidea.security.taobao.top;
+
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.Assert;
+
+/**
+ * 表示淘宝登陆的回调参数。
+ * 参考:
+ * <a href="http://open.taobao.com/doc/category_list.htm?id=199">用户授权介绍</a>
+ *
+ * @author Simon Leung
+ * @since 0.1
+ */
+public class TaobaoTopCredentials implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private static Logger log = LoggerFactory.getLogger(TaobaoTopCredentials.class);
+
+    private String appKey;
+    private String session;
+    private String parameters;
+    private String sign;
+
+    //上下文参数,从top_parameters中解析所得
+    private long timestamp;
+    private String iframe;
+    private String visitorId;
+    private String visitorNick;
+    private String visitorRole;
+
+    private long expiresIn;
+    private long r1ExpiresIn;
+    private long r2ExpiresIn;
+    private long w1ExpiresIn;
+    private long w2ExpiresIn;
+    private long reExpiresIn;
+
+    private String refreshToken;
+    private String subTaobaoUserId;
+    private String subTaobaoUserNick;
+
+    private TaobaoTopCredentials() {
+        //Can not be instantiated directly,use #build()
+    }
+
+    /**
+     * Build a TaobaoTopCredentials instance by HTTP request.
+     *
+     * @param request
+     * @return
+     */
+    public static TaobaoTopCredentials build(HttpServletRequest request) {
+        Assert.notNull(request, "The request can't be null");
+        TaobaoTopCredentials credentials = new TaobaoTopCredentials();
+        credentials.appKey = request.getParameter("top_appkey");
+        credentials.session = request.getParameter("top_session");
+        //base64 encoded
+        String parameters = request.getParameter("top_parameters");
+        credentials.parameters = parameters;
+        credentials.sign = request.getParameter("top_sign");
+
+        if (parameters != null) {
+            String charsetParameter = request.getParameter("encode");
+            String charset = charsetParameter == null ? "GBK" : charsetParameter;
+            String decodedParameters = null;
+            try {
+                decodedParameters = new String(Base64.decodeBase64(parameters), charset);
+            } catch (UnsupportedEncodingException e) {
+                //ignore
+            }
+            log.debug("top parameters: {}", decodedParameters);
+            Map<String, String> parameterMap = parseParameters(decodedParameters);
+            credentials.timestamp = Long.parseLong(parameterMap.get("ts"));
+            credentials.iframe = parameterMap.get("iframe");
+            credentials.visitorId = parameterMap.get("visitor_id");
+            credentials.visitorNick = parameterMap.get("visitor_nick");
+            credentials.visitorRole = parameterMap.get("visitor_role");
+
+            credentials.expiresIn = toLong(parameterMap.get("expires_in"));
+            credentials.r1ExpiresIn = toLong(parameterMap.get("r1_expires_in"));
+            credentials.r2ExpiresIn = toLong(parameterMap.get("r2_expires_in"));
+            credentials.w1ExpiresIn = toLong(parameterMap.get("w1_expires_in"));
+            credentials.w2ExpiresIn = toLong(parameterMap.get("w2_expires_in"));
+            credentials.reExpiresIn = toLong(parameterMap.get("re_expires_in"));
+
+            credentials.refreshToken = parameterMap.get("refresh_token");
+            credentials.subTaobaoUserId = parameterMap.get("sub_taobao_user_id");
+            credentials.subTaobaoUserNick = parameterMap.get("sub_taobao_user_nick");
+        }
+
+        return credentials;
+    }
+
+    private static long toLong(String str) {
+        if (str == null) {
+            return 0L;
+        }
+        try {
+            return Long.parseLong(str);
+        } catch (NumberFormatException nfe) {
+            return 0L;
+        }
+    }
+
+    /**
+     * 将URL参数解析成Map
+     *
+     * @param parameters like:key1=value1&key2=value2……
+     * @return key value map
+     */
+    private static Map<String, String> parseParameters(String parameters) {
+        Map<String, String> map = new HashMap<String, String>();
+        String[] pairs = StringUtils.split(parameters, "&");
+        for (String pair : pairs) {
+            String[] keyValue = StringUtils.split(pair, "=");
+            map.put(keyValue[0], keyValue[1]);
+        }
+        return map;
+    }
+
+    public String getParameters() {
+        return parameters;
+    }
+
+    public String getSession() {
+        return session;
+    }
+
+    public String getAppKey() {
+        return appKey;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+    public String getIframe() {
+        return iframe;
+    }
+
+    public String getVisitorId() {
+        return visitorId;
+    }
+
+    public String getVisitorNick() {
+        return visitorNick;
+    }
+
+    public String getVisitorRole() {
+        return visitorRole;
+    }
+
+    public long getExpiresIn() {
+        return expiresIn;
+    }
+
+    public void setExpiresIn(long expiresIn) {
+        this.expiresIn = expiresIn;
+    }
+
+    public long getR1ExpiresIn() {
+        return r1ExpiresIn;
+    }
+
+    public void setR1ExpiresIn(long r1ExpiresIn) {
+        this.r1ExpiresIn = r1ExpiresIn;
+    }
+
+    public long getR2ExpiresIn() {
+        return r2ExpiresIn;
+    }
+
+    public void setR2ExpiresIn(long r2ExpiresIn) {
+        this.r2ExpiresIn = r2ExpiresIn;
+    }
+
+    public long getW1ExpiresIn() {
+        return w1ExpiresIn;
+    }
+
+    public void setW1ExpiresIn(long w1ExpiresIn) {
+        this.w1ExpiresIn = w1ExpiresIn;
+    }
+
+    public long getW2ExpiresIn() {
+        return w2ExpiresIn;
+    }
+
+    public void setW2ExpiresIn(long w2ExpiresIn) {
+        this.w2ExpiresIn = w2ExpiresIn;
+    }
+
+    public long getReExpiresIn() {
+        return reExpiresIn;
+    }
+
+    public void setReExpiresIn(long reExpiresIn) {
+        this.reExpiresIn = reExpiresIn;
+    }
+
+    public String getRefreshToken() {
+        return refreshToken;
+    }
+
+    public void setRefreshToken(String refreshToken) {
+        this.refreshToken = refreshToken;
+    }
+
+    public String getSubTaobaoUserId() {
+        return subTaobaoUserId;
+    }
+
+    public void setSubTaobaoUserId(String subTaobaoUserId) {
+        this.subTaobaoUserId = subTaobaoUserId;
+    }
+
+    public String getSubTaobaoUserNick() {
+        return subTaobaoUserNick;
+    }
+
+    public void setSubTaobaoUserNick(String subTaobaoUserNick) {
+        this.subTaobaoUserNick = subTaobaoUserNick;
+    }
+}

File src/java/com/mingidea/security/util/HttpUtils.java

 
 import org.apache.commons.io.IOUtils;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLEncoder;
+import java.util.Map;
 
 /**
  * @author Liang Yong Rui
  */
 public class HttpUtils {
+    public static String post(String urlString, Map<String, String> parameters) throws IOException {
+        return post(urlString, buildParametersString(parameters));
+    }
+
+    private static String buildParametersString(Map<String, String> parameters) {
+        StringBuilder stringBuilder = new StringBuilder();
+        int i = 0;
+        int size = parameters.size();
+        for (Map.Entry<String, String> entry : parameters.entrySet()) {
+            i++;
+            stringBuilder.append(entry.getKey())
+                    .append("=")
+                    .append(encodeUrl(entry.getValue()));
+            if (i < size) {
+                stringBuilder.append("&");
+            }
+        }
+        return stringBuilder.toString();
+    }
+
     public static String post(String urlString, String parameters) throws IOException {
         URL url = new URL(urlString);
         HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();