基于oltu的oauth2 server

名词解释

主框架使用Spring + Spring Security 搭建。因为遗留的项目采用了低版本的Spring 3.0.x,所以放弃了Spring提供的spring-security-oauth2spring-security-oauth2官网提供的例子也像一坨屎,无法让人信服。

由于Client端的实现较为简单且多样,所以本文主要介绍Authorization Server的实现方式。以authorization_code模式为例

代码示例

  • authorize
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@GetMapping(value = "/authorize")
public String authorize(HttpServletRequest request, Model model) {
try {
//构建OAuth请求
OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(request);
String responseType = oauthRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE);
if (!ResponseType.CODE.toString().equals(responseType)) {
throw OAuthProblemException.error("response_type不正确");
}
String clientId = oauthRequest.getClientId();
// 验证clientId是否正确
if (!validateOAuth2ClientId(clientId)) {
// ...
}
String redirectURI = oauthRequest.getRedirectURI();
// 验证redirectURI
if (!validateRedirectUri(redirectURI)) {
// ...
}
// 查询app信息
String appName = getAppInfo();
// 用户是否登录
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String code = new OAuthIssuerImpl(new MD5Generator()).authorizationCode();
OAuthResponse oauthResponse = OAuthASResponse
.authorizationResponse(request, HttpServletResponse.SC_FOUND)
.setCode(code)
.location(redirectURI)
.buildQueryMessage();
return "redirect:" + oauthResponse.getLocationUri();
} catch (OAuthProblemException ex) {
ex.printStackTrace();
model.addAttribute("message", ex.getDescription());
} catch (OAuthSystemException e) {
model.addAttribute("message", e.getMessage());
e.printStackTrace();
}
return "site/500";
}
  • access_token
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public ResponseEntity<?> accessToken(HttpServletRequest request) {
//构建oauth2请求
try {
OAuthTokenRequest oauthRequest = new OAuthTokenRequest(request);
// TODO 校验appInfo
String clientId = oauthRequest.getClientId();
if (!validateOAuth2ClientId(clientId)) {
// ...
}
String clientSecret = oauthRequest.getClientSecret();
if (!validateOauth2ClientSecret(clientSecret)) {
// ...
}
String grantType = oauthRequest.getGrantType();
if (!validateOauth2GrantType(grantType)) {
// ...
}
String code = oauthRequest.getCode();
String openId = oAuth2Service.getOpenId(code);
if (openId == null) {
// ...
}
// 生成AccessToken
OAuthIssuerImpl oAuthIssuer = new OAuthIssuerImpl(new MD5Generator());
String accessToken = oAuthIssuer.accessToken();
oAuth2Service.addAccessToken(accessToken, openId);
oAuth2Service.evict(code);
//生成OAuth响应
OAuthResponse response = OAuthASResponse
.tokenResponse(HttpServletResponse.SC_OK)
.setAccessToken(accessToken)
.setParam("openId", openId)
.setExpiresIn(String.valueOf(oAuth2Service.getExpireIn()))
.buildJSONMessage();
return ResponseEntity.ok(response.getBody());
} catch (OAuthProblemException e) {
e.printStackTrace();
return ResponseEntity.badRequest().body(e.getDescription());
} catch (OAuthSystemException e) {
e.printStackTrace();
}
return ResponseEntity.badRequest().body("未知错误");
}

完整示例请参考开源项目:microbbs

参考资料: