Browse Source

--第三方登陆相关(未完成)

jiapeng 8 years ago
parent
commit
c138a4b5d8

+ 34 - 0
src/main/java/com/ekexiu/portal/dao/UserOpenIdDao.java

@ -0,0 +1,34 @@
1
package com.ekexiu.portal.dao;
2

3
import com.ekexiu.portal.po.UserOpenId;
4
import java.sql.Connection;
5
import java.sql.SQLException;
6
import java.util.List;
7

8
import org.jfw.apt.annotation.Nullable;
9
import org.jfw.apt.orm.annotation.dao.DAO;
10
import org.jfw.apt.orm.annotation.dao.method.From;
11
import org.jfw.apt.orm.annotation.dao.method.operator.DeleteWith;
12
import org.jfw.apt.orm.annotation.dao.method.operator.Insert;
13
import org.jfw.apt.orm.annotation.dao.method.operator.SelectList;
14
import org.jfw.apt.orm.annotation.dao.method.operator.SelectOne;
15

16
@DAO
17
public interface UserOpenIdDao {
18
    @Insert
19
    int insert(Connection con, UserOpenId user) throws SQLException;
20

21
    @DeleteWith
22
    @From(UserOpenId.class)
23
    int delete(Connection con, String userid) throws SQLException;
24
    @DeleteWith
25
    @From(UserOpenId.class)
26
    int delete(Connection con, String oauthType, String openid) throws SQLException;
27

28
    @SelectList
29
    List<UserOpenId> query(Connection con, String userid) throws SQLException;
30

31
    @SelectOne
32
    @Nullable
33
    UserOpenId query(Connection con, String oauthType, String userid) throws SQLException;
34
}

+ 9 - 0
src/main/java/com/ekexiu/portal/oauth/OAuthHandler.java

@ -0,0 +1,9 @@
1
package com.ekexiu.portal.oauth;
2

3
import org.jfw.util.exception.JfwBaseException;
4

5
public interface OAuthHandler {
6
	String getType();
7
	String getLoginUrl();
8
	OAuthUser login(String code) throws JfwBaseException;
9
}

+ 195 - 0
src/main/java/com/ekexiu/portal/oauth/OAuthService.java

@ -0,0 +1,195 @@
1
package com.ekexiu.portal.oauth;
2

3
import java.sql.Connection;
4
import java.sql.SQLException;
5
import java.util.HashMap;
6
import java.util.Map;
7
import java.util.concurrent.TimeUnit;
8

9
import org.jfw.apt.annotation.Autowrie;
10
import org.jfw.apt.web.annotation.Path;
11
import org.jfw.apt.web.annotation.method.SetCookie;
12
import org.jfw.apt.web.annotation.operate.Get;
13
import org.jfw.apt.web.annotation.operate.Post;
14
import org.jfw.apt.web.annotation.param.JdbcConn;
15
import org.jfw.util.context.JfwAppContext;
16
import org.jfw.util.exception.JfwBaseException;
17
import org.jfw.util.state.StateCode;
18

19
import com.ekexiu.portal.dao.ProfessorDao;
20
import com.ekexiu.portal.dao.UserDao;
21
import com.ekexiu.portal.dao.UserOpenIdDao;
22
import com.ekexiu.portal.po.User;
23
import com.ekexiu.portal.po.UserOpenId;
24
import com.ekexiu.portal.pojo.SessionUser;
25
import com.ekexiu.portal.service.SysService;
26

27
@Path("/oauth")
28
public class OAuthService {
29

30
    private long expriesWithOpenId = 1000 * 60 * 10;
31

32
    @Autowrie
33
    private UserOpenIdDao userOpenIdDao;
34
    @Autowrie
35
    private UserDao userDao;
36
    @Autowrie
37
    private ProfessorDao professorDao;
38

39
    private Map<String, OAuthHandler> handlers;
40

41
    public Map<String, OAuthHandler> getHandlers() {
42
        return handlers;
43
    }
44

45
    public void setHandlers(Map<String, OAuthHandler> handlers) {
46
        this.handlers = handlers;
47
    }
48

49
    public UserOpenIdDao getUserOpenIdDao() {
50
        return userOpenIdDao;
51
    }
52

53
    public void setUserOpenIdDao(UserOpenIdDao userOpenIdDao) {
54
        this.userOpenIdDao = userOpenIdDao;
55
    }
56

57
    public UserDao getUserDao() {
58
        return userDao;
59
    }
60

61
    public void setUserDao(UserDao userDao) {
62
        this.userDao = userDao;
63
    }
64

65
    public long getExpriesWithOpenId() {
66
        return expriesWithOpenId;
67
    }
68

69
    public void setExpriesWithOpenId(long expriesWithOpenId) {
70
        this.expriesWithOpenId = expriesWithOpenId;
71
    }
72

73
    public ProfessorDao getProfessorDao() {
74
        return professorDao;
75
    }
76

77
    public void setProfessorDao(ProfessorDao professorDao) {
78
        this.professorDao = professorDao;
79
    }
80

81
    @Get
82
    @Path("/validCode")
83
    public AuthLoginResponse validCode(@JdbcConn Connection con, String code, String state) throws SQLException, JfwBaseException {
84
        OAuthHandler oah = this.handlers.get(state);
85
        if (oah == null)
86
            throw new IllegalArgumentException("非法的参数{state=" + state);
87
        OAuthUser ou = oah.login(code);
88
        UserOpenId uoi = this.userOpenIdDao.query(con, oah.getType(), ou.getOpenId());
89

90
        StateCode<OAuthUser, UserOpenId> sc = new StateCode<OAuthUser, UserOpenId>();
91
        final String key = JfwAppContext.cacheObjectAndGenKey(sc);
92
        sc.setKey(ou);
93
        sc.setValue(uoi);
94
        sc.setBuildTime(System.currentTimeMillis());
95
        sc.setExpiredTime(sc.getBuildTime() + this.expriesWithOpenId);
96
        JfwAppContext.getScheduledExecutorService().schedule(new Runnable() {
97
            @Override
98
            public void run() {
99
                JfwAppContext.removeCachedObject(key);
100
            }
101
        }, this.expriesWithOpenId, TimeUnit.MILLISECONDS);
102
        AuthLoginResponse alr = new AuthLoginResponse();
103
        alr.setAssociated(null != uoi);
104
        alr.setAuthCode(key);
105
        return alr;
106
    }
107

108
    @SetCookie(checkResultNull = true, path = "/", value = { "userid=result.getId()", "userMobilePhone=result.getMobilePhone()", "userType=result.getType()",
109
            "userAuth=String.valueOf(result.isAuth())", "userEmail=result.getEmail()==null?\"\":result.getEmail()",
110
            "userName=result.getName()==null?\"\":java.net.URLEncoder.encode(result.getName(),\"utf-8\")" })
111
    @Post
112
    @Path("/login")
113
    public SessionUser login(@JdbcConn Connection con, String authCode) throws SQLException, JfwBaseException {
114
        @SuppressWarnings("unchecked")
115
        StateCode<OAuthUser, UserOpenId> sc = (StateCode<OAuthUser, UserOpenId>) JfwAppContext.getCachedObject(authCode);
116
        JfwAppContext.removeCachedObject(authCode);
117
        if (sc == null || sc.getExpiredTime() < System.currentTimeMillis())
118
            throw new JfwBaseException(-1, "authCode is expired");
119
        if (null == sc.getValue())
120
            throw new JfwBaseException(-2, "authCode is invalid openid not associate local user");
121

122
        User user = this.userDao.query(con, sc.getValue().getUserid());
123
        if (null == user)
124
            return null;
125
        SessionUser ret = new SessionUser();
126
        ret.setId(user.getId());
127
        if (null != this.professorDao.query(con, user.getId())) {
128
            ret.setName(this.professorDao.query(con, user.getId()).getName());
129
        }
130
        ret.setMobilePhone(user.getMobilePhone());
131
        ret.setType(user.getUserType());
132
        ret.setEmail(user.getEmail());
133
        ret.setAuth(!SysService.DEFAULT_PASS_WORD.equals(user.getPasswd()));
134
        return ret;
135
    }
136

137
    @Post
138
    @Path("/validOpenid")
139
    public AuthLoginResponse validOpenid(@JdbcConn Connection con, String authType, String openid) throws SQLException, JfwBaseException {
140
        OAuthUser ou = new OAuthUser();
141
        ou.setType(authType);
142
        ou.setOpenId(openid);
143
        UserOpenId uoi = this.userOpenIdDao.query(con, authType, openid);
144
        AuthLoginResponse alr = new AuthLoginResponse();
145
        StateCode<OAuthUser, UserOpenId> sc = new StateCode<OAuthUser, UserOpenId>();
146
        final String key = JfwAppContext.cacheObjectAndGenKey(sc);
147
        sc.setKey(ou);
148
        sc.setValue(uoi);
149
        sc.setBuildTime(System.currentTimeMillis());
150
        sc.setExpiredTime(sc.getBuildTime() + this.expriesWithOpenId);
151
        JfwAppContext.getScheduledExecutorService().schedule(new Runnable() {
152
            @Override
153
            public void run() {
154
                JfwAppContext.removeCachedObject(key);
155
            }
156
        }, this.expriesWithOpenId, TimeUnit.MILLISECONDS);
157
        alr.setAssociated(null != uoi);
158
        alr.setAuthCode(key);
159
        return alr;
160
    }
161

162
    
163

164
    @Get
165
    @Path("/redirectUris")
166
    public Map<String, String> getRedirectUris() {
167
        Map<String, String> ret = new HashMap<String, String>();
168
        for (Map.Entry<String, OAuthHandler> h : this.handlers.entrySet()) {
169
            ret.put(h.getKey(), h.getValue().getLoginUrl());
170
        }
171
        return ret;
172
    }
173

174
    public static class AuthLoginResponse {
175
        private boolean associated;
176
        private String authCode;
177

178
        public boolean isAssociated() {
179
            return associated;
180
        }
181

182
        public void setAssociated(boolean associated) {
183
            this.associated = associated;
184
        }
185

186
        public String getAuthCode() {
187
            return authCode;
188
        }
189

190
        public void setAuthCode(String authCode) {
191
            this.authCode = authCode;
192
        }
193
    }
194

195
}

+ 58 - 0
src/main/java/com/ekexiu/portal/oauth/OAuthUser.java

@ -0,0 +1,58 @@
1
package com.ekexiu.portal.oauth;
2

3
public class OAuthUser {
4
	private String openId;
5
    private String type;
6
    private String accessToken;
7
    private long expiresIn;
8
    private String refreshToken;
9
    private String scope;
10

11
	public String getAccessToken() {
12
		return accessToken;
13
	}
14

15
	public void setAccessToken(String accessToken) {
16
		this.accessToken = accessToken;
17
	}
18

19
	public long getExpiresIn() {
20
		return expiresIn;
21
	}
22

23
	public void setExpiresIn(long expiresIn) {
24
		this.expiresIn = expiresIn;
25
	}
26

27
	public String getRefreshToken() {
28
		return refreshToken;
29
	}
30

31
	public void setRefreshToken(String refreshToken) {
32
		this.refreshToken = refreshToken;
33
	}
34

35
	public String getScope() {
36
		return scope;
37
	}
38

39
	public void setScope(String scope) {
40
		this.scope = scope;
41
	}
42

43
	public String getType() {
44
		return type;
45
	}
46

47
	public void setType(String type) {
48
		this.type = type;
49
	}
50

51
	public String getOpenId() {
52
		return openId;
53
	}
54

55
	public void setOpenId(String openId) {
56
		this.openId = openId;
57
	}
58
}

+ 77 - 0
src/main/java/com/ekexiu/portal/oauth/weixin/AccessTokenResponse.java

@ -0,0 +1,77 @@
1
package com.ekexiu.portal.oauth.weixin;
2

3

4
public class AccessTokenResponse {
5
	private String access_token ;	
6
	private long expires_in; 
7
	private String refresh_token;
8
	private String openid; 
9
	private String scope;
10
	private String unionid;
11
	private String errcode;
12
	private String errmsg;
13
	
14
	public long getExpires_in() {
15
		return expires_in;
16
	}
17

18
	public void setExpires_in(long expires_in) {
19
		this.expires_in = expires_in;
20
	}
21

22
	public String getRefresh_token() {
23
		return refresh_token;
24
	}
25

26
	public void setRefresh_token(String refresh_token) {
27
		this.refresh_token = refresh_token;
28
	}
29

30
	public String getOpenid() {
31
		return openid;
32
	}
33

34
	public void setOpenid(String openid) {
35
		this.openid = openid;
36
	}
37

38
	public String getScope() {
39
		return scope;
40
	}
41

42
	public void setScope(String scope) {
43
		this.scope = scope;
44
	}
45

46
	public String getUnionid() {
47
		return unionid;
48
	}
49

50
	public void setUnionid(String unionid) {
51
		this.unionid = unionid;
52
	}
53

54
	public String getErrcode() {
55
		return errcode;
56
	}
57

58
	public void setErrcode(String errcode) {
59
		this.errcode = errcode;
60
	}
61

62
	public String getErrmsg() {
63
		return errmsg;
64
	}
65

66
	public void setErrmsg(String errmsg) {
67
		this.errmsg = errmsg;
68
	}
69

70
	public String getAccess_token() {
71
		return access_token;
72
	}
73

74
	public void setAccess_token(String access_token) {
75
		this.access_token = access_token;
76
	}
77
}

+ 119 - 0
src/main/java/com/ekexiu/portal/oauth/weixin/WeiXinHandler.java

@ -0,0 +1,119 @@
1
package com.ekexiu.portal.oauth.weixin;
2

3
import java.io.IOException;
4

5
import org.jfw.apt.annotation.Bean;
6
import org.jfw.util.exception.JfwBaseException;
7
import org.jfw.util.json.JsonService;
8

9
import com.ekexiu.portal.oauth.OAuthHandler;
10
import com.ekexiu.portal.oauth.OAuthUser;
11
import com.ekexiu.portal.util.HttpUtil;
12

13
@Bean
14
public class WeiXinHandler implements OAuthHandler {
15
	public static final String OAUTH_TYPE = "weixin";
16

17
	/**
18
	 * 在微信上注册的APPID
19
	 */
20
	private String appid;
21
	/**
22
	 * 在微信上注册的APPID 对应的 APPSECRET
23
	 */
24
	private String appsecret;
25
	/**
26
	 * 微信请求OAUTH登录的URL
27
	 */
28
	private String codeUrl = "https://open.weixin.qq.com/connect/qrconnect";
29
	/**
30
	 * 微信登录授权后的跳转面页
31
	 */
32
	private String redirectUri;
33
	/**
34
	 * 微信请求OAUTH AccessToken的URL
35
	 */
36
	private String accessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
37

38
	public String getAccessTokenUrl() {
39
		return accessTokenUrl;
40
	}
41

42
	public void setAccessTokenUrl(String accessTokenUrl) {
43
		this.accessTokenUrl = accessTokenUrl;
44
	}
45

46
	public String getRedirectUri() {
47
		return redirectUri;
48
	}
49

50
	public void setRedirectUri(String redirectUri) {
51
		this.redirectUri = redirectUri;
52
	}
53

54
	public String getAppid() {
55
		return appid;
56
	}
57

58
	public void setAppid(String appid) {
59
		this.appid = appid;
60
	}
61

62
	public String getAppsecret() {
63
		return appsecret;
64
	}
65

66
	public void setAppsecret(String appsecret) {
67
		this.appsecret = appsecret;
68
	}
69

70
	public String getCodeUrl() {
71
		return codeUrl;
72
	}
73

74
	public void setCodeUrl(String codeUrl) {
75
		this.codeUrl = codeUrl;
76
	}
77

78
	@Override
79
	public String getType() {
80
		return OAUTH_TYPE;
81
	}
82

83
	@Override
84
	public String getLoginUrl() {
85
		StringBuilder sb = new StringBuilder();
86
		sb.append(this.codeUrl).append("?appid=").append(this.appid).append("&redirect_uri=").append(this.redirectUri)
87
				.append("&response_type=code&scope=snsapi_login&state=weixin#wechat_redirect");
88
		return sb.toString();
89
	}
90

91
	@Override
92
	public OAuthUser login(String code) throws JfwBaseException {
93
        AccessTokenResponse atr;
94
		try {
95
			atr = HttpUtil.loadJsonObject(this.buildAccessTokenURL(code),AccessTokenResponse.class);
96
		} catch (IOException e) {
97
			throw new JfwBaseException(91,e);
98
		}
99
        if(null!= atr.getErrcode()) throw new JfwBaseException(0,"访问微信access_token error:"+JsonService.toJson(atr));
100
		OAuthUser user = new OAuthUser();
101
		user.setType(this.getType());
102
		user.setOpenId(atr.getOpenid());
103
		user.setAccessToken(atr.getAccess_token());
104
		user.setExpiresIn(atr.getExpires_in());
105
		user.setScope(atr.getScope());
106
		user.setRefreshToken(atr.getRefresh_token());
107
		return user;
108
	}
109

110
	private String buildAccessTokenURL(String code) {
111
		StringBuilder sb = new StringBuilder();
112
		sb.append(this.accessTokenUrl).append("?appid=").append(this.appid)
113
		.append("&secret=").append(this.appsecret)
114
		.append("&code=").append(code)
115
		.append("&grant_type=authorization_code");
116
		return sb.toString();
117
	}
118

119
}

+ 66 - 0
src/main/java/com/ekexiu/portal/po/UserOpenId.java

@ -0,0 +1,66 @@
1
package com.ekexiu.portal.po;
2

3
import com.ekexiu.portal.basepo.CreateTimeSupported;
4
import com.ekexiu.portal.basepo.ModifyTimeSupported;
5

6
import org.jfw.apt.orm.annotation.entry.Column;
7
import org.jfw.apt.orm.annotation.entry.PrimaryKey;
8
import org.jfw.apt.orm.annotation.entry.Table;
9
import org.jfw.apt.orm.annotation.entry.Unique;
10
import org.jfw.apt.orm.annotation.entry.Uniques;
11
import org.jfw.apt.orm.core.defaultImpl.StringHandler;
12
import org.jfw.apt.orm.core.enums.DE;
13

14
@Table
15
@PrimaryKey({ "oauthType", "openid", "userid" })
16
@Uniques({ @Unique(clolumns = { "userid", "oauthType" }, name = "USER_OPEN_ID_UO"), @Unique(clolumns = { "oauthType", "openid" }, name = "USER_OPEN_ID_OO") })
17
public class UserOpenId implements CreateTimeSupported, ModifyTimeSupported {
18
    private String createTime;
19
    private String modifyTime;
20
    private String userid;
21
    private String oauthType;
22
    private String openid;
23

24
    @Column(DE.id_32)
25
    public String getUserid() {
26
        return this.userid;
27
    }
28

29
    public void setUserid(String userid) {
30
        this.userid = userid;
31
    }
32

33
    @Column(dbType = "text", handlerClass = StringHandler.class, insertable = true, nullable = false, queryable = true, renewable = true)
34
    public String getOauthType() {
35
        return this.oauthType;
36
    }
37

38
    public void setOauthType(String oauthType) {
39
        this.oauthType = oauthType;
40
    }
41

42
    @Column(dbType = "text", handlerClass = StringHandler.class, insertable = true, nullable = false, queryable = true, renewable = true)
43
    public String getOpenid() {
44
        return this.openid;
45
    }
46

47
    public void setOpenid(String openid) {
48
        this.openid = openid;
49
    }
50

51
    public String getModifyTime() {
52
        return this.modifyTime;
53
    }
54

55
    public void setModifyTime(String modifyTime) {
56
        this.modifyTime = modifyTime;
57
    }
58

59
    public String getCreateTime() {
60
        return this.createTime;
61
    }
62

63
    public void setCreateTime(String createTime) {
64
        this.createTime = createTime;
65
    }
66
}

+ 95 - 0
src/main/java/com/ekexiu/portal/util/HttpUtil.java

@ -0,0 +1,95 @@
1
package com.ekexiu.portal.util;
2

3
import java.io.IOException;
4
import java.lang.reflect.Type;
5
import java.net.HttpURLConnection;
6
import java.net.URL;
7
import org.jfw.util.ConstData;
8
import org.jfw.util.io.IoUtil;
9
import org.jfw.util.json.JsonService;
10

11
public final class HttpUtil {
12
    public static String loadAsString(String url, String enc) throws IOException {
13
        URL aurl = new URL(url);
14
        HttpURLConnection uc = (HttpURLConnection) aurl.openConnection();
15
        try {
16
            byte[] bs = IoUtil.readStream(uc.getInputStream(), true);
17
            return new String(bs, enc);
18
        } finally {
19
            try {
20
                uc.disconnect();
21
            } catch (Throwable th) {
22
            }
23
        }
24
    }
25

26
    public static String loadAsString(String url) throws IOException {
27
        URL aurl = new URL(url);
28
        HttpURLConnection uc = (HttpURLConnection) aurl.openConnection();
29
        try {
30
            byte[] bs = IoUtil.readStream(uc.getInputStream(), true);
31
            return new String(bs, ConstData.UTF8);
32
        } finally {
33
            try {
34
                uc.disconnect();
35
            } catch (Throwable th) {
36
            }
37
        }
38
    }
39

40
    public static <T> T loadJsonObject(String url, String enc, Type typeOfT) throws IOException {
41
        URL aurl = new URL(url);
42
        HttpURLConnection uc = (HttpURLConnection) aurl.openConnection();
43
        try {
44
            byte[] bs = IoUtil.readStream(uc.getInputStream(), true);
45
            return JsonService.fromJson(new String(bs, enc), typeOfT);
46
        } finally {
47
            try {
48
                uc.disconnect();
49
            } catch (Throwable th) {
50
            }
51
        }
52
    }
53

54
    public static <T> T loadJsonObject(String url, Type typeOfT) throws IOException {
55
        URL aurl = new URL(url);
56
        HttpURLConnection uc = (HttpURLConnection) aurl.openConnection();
57
        try {
58
            byte[] bs = IoUtil.readStream(uc.getInputStream(), true);
59
            return JsonService.fromJson(new String(bs, ConstData.UTF8), typeOfT);
60
        } finally {
61
            try {
62
                uc.disconnect();
63
            } catch (Throwable th) {
64
            }
65
        }
66
    }
67

68
    public static <T> T loadJsonObject(String url, String enc, Class<T> clazz) throws IOException {
69
        URL aurl = new URL(url);
70
        HttpURLConnection uc = (HttpURLConnection) aurl.openConnection();
71
        try {
72
            byte[] bs = IoUtil.readStream(uc.getInputStream(), true);
73
            return JsonService.fromJson(new String(bs, enc), clazz);
74
        } finally {
75
            try {
76
                uc.disconnect();
77
            } catch (Throwable th) {
78
            }
79
        }
80
    }
81

82
    public static <T> T loadJsonObject(String url, Class<T> clazz) throws IOException {
83
        URL aurl = new URL(url);
84
        HttpURLConnection uc = (HttpURLConnection) aurl.openConnection();
85
        try {
86
            byte[] bs = IoUtil.readStream(uc.getInputStream(), true);
87
            return JsonService.fromJson(new String(bs, ConstData.UTF8), clazz);
88
        } finally {
89
            try {
90
                uc.disconnect();
91
            } catch (Throwable th) {
92
            }
93
        }
94
    }
95
}