Skip to content

Commit 70fa210

Browse files
committed
优化OAuth2.0
1 parent a91d1d8 commit 70fa210

File tree

30 files changed

+1058
-84
lines changed

30 files changed

+1058
-84
lines changed

hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-server/hsweb-authorization-oauth2-server-api/src/main/java/org/hswebframework/web/authorization/oauth2/api/OAuth2ServerService.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
package org.hswebframework.web.authorization.oauth2.api;
2020

21-
import org.hswebframework.web.authorization.oauth2.entity.OAuth2AccessEntity;
22-
import org.hswebframework.web.authorization.oauth2.entity.OAuth2ClientEntity;
21+
import org.hswebframework.web.entity.authorization.oauth2.OAuth2AccessEntity;
22+
import org.hswebframework.web.entity.authorization.oauth2.OAuth2ClientEntity;
2323

2424
/**
2525
* @author zhouhao
@@ -40,6 +40,8 @@ public interface OAuth2ServerService {
4040

4141
OAuth2AccessEntity requestTokenByPassword(String username, String password);
4242

43+
OAuth2AccessEntity requestTokenByImplicit(String clientId, String scope);
44+
4345
OAuth2AccessEntity refreshToken(String clientId, String clientSecret, String refreshToken, String scope);
4446

4547
OAuth2AccessEntity getAccessToken(String accessToken);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright 2016 http://www.hswebframework.org
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ http://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
~
17+
~
18+
-->
19+
20+
<project xmlns="http://maven.apache.org/POM/4.0.0"
21+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
22+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
23+
<parent>
24+
<artifactId>hsweb-authorization-oauth2-server</artifactId>
25+
<groupId>org.hswebframework.web</groupId>
26+
<version>3.0-SNAPSHOT</version>
27+
</parent>
28+
<modelVersion>4.0.0</modelVersion>
29+
30+
<artifactId>hsweb-authorization-oauth2-server-controller</artifactId>
31+
32+
<dependencies>
33+
<dependency>
34+
<groupId>org.hswebframework.web</groupId>
35+
<artifactId>hsweb-commons-controller</artifactId>
36+
<version>${project.version}</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>org.hswebframework.web</groupId>
40+
<artifactId>hsweb-authorization-oauth2-server-model</artifactId>
41+
<version>${project.version}</version>
42+
</dependency>
43+
<dependency>
44+
<groupId>org.hswebframework.web</groupId>
45+
<artifactId>hsweb-authorization-oauth2-server-api</artifactId>
46+
<version>${project.version}</version>
47+
</dependency>
48+
<dependency>
49+
<groupId>org.apache.oltu.oauth2</groupId>
50+
<artifactId>org.apache.oltu.oauth2.authzserver</artifactId>
51+
<version>1.0.2</version>
52+
</dependency>
53+
</dependencies>
54+
</project>
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*
2+
* Copyright 2016 http://www.hswebframework.org
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*
17+
*/
18+
19+
package org.hswebframework.web.authorization.oauth2.controller;
20+
21+
import io.swagger.annotations.*;
22+
import org.apache.commons.codec.binary.Base64;
23+
import org.hswebframework.web.authorization.Authorization;
24+
import org.hswebframework.web.authorization.AuthorizationHolder;
25+
import org.hswebframework.web.authorization.annotation.Authorize;
26+
import org.hswebframework.web.authorization.oauth2.api.OAuth2ServerService;
27+
import org.hswebframework.web.entity.authorization.oauth2.OAuth2AccessEntity;
28+
import org.hswebframework.web.authorization.oauth2.model.AccessTokenModel;
29+
import org.hswebframework.web.authorization.oauth2.model.AuthorizationCodeModel;
30+
import org.hswebframework.web.authorization.oauth2.model.ImplicitAccessTokenModel;
31+
import org.hswebframework.web.controller.message.ResponseMessage;
32+
import org.springframework.web.bind.annotation.*;
33+
34+
import javax.annotation.Resource;
35+
36+
import static org.springframework.util.StringUtils.isEmpty;
37+
38+
/**
39+
*
40+
* @author zhouhao
41+
*/
42+
@RestController
43+
@Api(tags = "hsweb-authorization", description = "OAuth2授权", hidden = true)
44+
@RequestMapping("${hsweb.web.mappings.authorize-oauth2:oauth2/authorize}")
45+
public class OAuth2AuthorizationController {
46+
47+
@Resource
48+
private OAuth2ServerService oAuth2ServerService;
49+
50+
@RequestMapping(params = "response_type=code", method = RequestMethod.GET)
51+
@ApiOperation("登录用户获取OAuth2.0授权码")
52+
@Authorize
53+
public AuthorizationCodeModel requestCode(
54+
@RequestParam("client_id") String clientId,
55+
@RequestParam("redirect_uri") String redirectUri,
56+
@RequestParam(value = "scope", required = false) String scope,
57+
@RequestParam(value = "state", required = false) String state) {
58+
Authorization authorization = AuthorizationHolder.get();
59+
String code = oAuth2ServerService.requestCode(clientId, authorization.getUser().getId(), scope);
60+
AuthorizationCodeModel model = new AuthorizationCodeModel();
61+
model.setCode(code);
62+
model.setRedirectUri(redirectUri);
63+
model.setState(state);
64+
return model;
65+
}
66+
67+
68+
@RequestMapping(params = "response_type=token", method = RequestMethod.GET)
69+
@ApiOperation("implicit方式授权")
70+
public ImplicitAccessTokenModel authorizeByImplicit(
71+
@RequestParam(value = "client_id") String client_id,
72+
@RequestParam(value = "redirect_uri") String redirect_uri,
73+
@RequestParam(value = "state") String state,
74+
@RequestParam(value = "scope", required = false) String scope) {
75+
76+
// OAuth2ClientEntity clientEntity = oAuth2ServerService.getClient(client_id);
77+
// TODO: 17-3-6 validate redirect_uri
78+
79+
OAuth2AccessEntity accessEntity = oAuth2ServerService.requestTokenByImplicit(client_id, scope);
80+
ImplicitAccessTokenModel model = new ImplicitAccessTokenModel();
81+
model.setState(state);
82+
model.setToken_type("example");
83+
model.setAccess_token(accessEntity.getAccessToken());
84+
model.setExpire_in(accessEntity.getExpireIn());
85+
return model;
86+
}
87+
88+
@RequestMapping(params = "grant_type=authorization_code", method = RequestMethod.POST)
89+
@ApiOperation("authorization_code方式授权")
90+
public AccessTokenModel authorizeByCode(
91+
@RequestParam("code") String code,
92+
@RequestParam(value = "client_id", required = false) String clientId,
93+
@RequestParam(value = "client_secret", required = false) String clientSecret,
94+
@RequestHeader(value = "Authorization", required = false) String authorization,
95+
@RequestParam(value = "scope", required = false) String scope) {
96+
97+
String[] clientCredentials = getClientCredentials(clientId, clientSecret, authorization);
98+
clientId = clientCredentials[0];
99+
clientSecret = clientCredentials[1];
100+
101+
AccessTokenModel model = entityToModel(oAuth2ServerService.requestTokenByCode(code, clientId, clientSecret, scope));
102+
return model;
103+
}
104+
105+
@RequestMapping(params = "grant_type=client_credentials", method = RequestMethod.POST)
106+
@ApiOperation("client_credentials方式授权")
107+
public AccessTokenModel authorizeByClientCredentials(
108+
@RequestParam(value = "client_id", required = false) String clientId,
109+
@RequestParam(value = "client_secret", required = false) String clientSecret,
110+
@RequestHeader(value = "Authorization", required = false) String authorization) {
111+
String[] clientCredentials = getClientCredentials(clientId, clientSecret, authorization);
112+
clientId = clientCredentials[0];
113+
clientSecret = clientCredentials[1];
114+
AccessTokenModel model = entityToModel(oAuth2ServerService.requestTokenByClientCredential(clientId, clientSecret));
115+
return model;
116+
}
117+
118+
@RequestMapping(params = "grant_type=password", method = RequestMethod.POST)
119+
@ApiOperation("password方式授权")
120+
public AccessTokenModel authorizeByPassword(
121+
@RequestParam(value = "username") String username,
122+
@RequestParam(value = "password") String password,
123+
@RequestHeader(value = "Authorization", required = false) String authorization) {
124+
String[] clientCredentials = getClientCredentials(username, password, authorization);
125+
username = clientCredentials[0];
126+
password = clientCredentials[1];
127+
AccessTokenModel model = entityToModel(oAuth2ServerService.requestTokenByPassword(username, password));
128+
return model;
129+
}
130+
131+
@RequestMapping(params = "grant_type=refresh_token", method = RequestMethod.POST)
132+
@ApiOperation("刷新授权码")
133+
public AccessTokenModel refreshToken(
134+
@RequestHeader(value = "Authorization", required = false) String authorization,
135+
@RequestParam(value = "client_id", required = false) String clientId,
136+
@RequestParam(value = "client_secret", required = false) String clientSecret,
137+
@RequestParam(value = "refresh_token") String refreshToken,
138+
@RequestParam(value = "scope", required = false) String scope) {
139+
140+
String[] clientCredentials = getClientCredentials(clientId, clientSecret, authorization);
141+
clientId = clientCredentials[0];
142+
clientSecret = clientCredentials[1];
143+
144+
AccessTokenModel model = entityToModel(oAuth2ServerService.refreshToken(clientId, clientSecret, refreshToken, scope));
145+
return model;
146+
}
147+
148+
protected String[] getClientCredentials(String clientId, String clientSecret, String authorization) {
149+
if ((clientId == null || clientSecret == null) && authorization == null) {
150+
throw new IllegalArgumentException("authorization error!");
151+
}
152+
if (!isEmpty(authorization)) {
153+
String[] creds = decodeClientAuthenticationHeader(authorization);
154+
if (creds.length > 1) {
155+
clientId = creds[0];
156+
clientSecret = creds[1];
157+
} else {
158+
clientSecret = creds[0];
159+
}
160+
}
161+
return new String[]{clientId, clientSecret};
162+
}
163+
164+
protected AccessTokenModel entityToModel(OAuth2AccessEntity entity) {
165+
AccessTokenModel model = new AccessTokenModel();
166+
model.setAccess_token(entity.getAccessToken());
167+
model.setRefresh_token(entity.getRefreshToken());
168+
model.setExpire_in(entity.getExpireIn());
169+
model.setScope(entity.getScope());
170+
model.setToken_type("bearer");
171+
return model;
172+
}
173+
174+
175+
protected static String[] decodeClientAuthenticationHeader(String authenticationHeader) {
176+
if (isEmpty(authenticationHeader)) {
177+
return null;
178+
} else {
179+
String[] tokens = authenticationHeader.split(" ");
180+
if (tokens.length != 2) {
181+
return null;
182+
} else {
183+
String authType = tokens[0];
184+
if (!"basic".equalsIgnoreCase(authType)) {
185+
return null;
186+
} else {
187+
String encodedCreds = tokens[1];
188+
return decodeBase64EncodedCredentials(encodedCreds);
189+
}
190+
}
191+
}
192+
}
193+
194+
protected static String[] decodeBase64EncodedCredentials(String encodedCreds) {
195+
String decodedCreds = new String(Base64.decodeBase64(encodedCreds));
196+
String[] creds = decodedCreds.split(":", 2);
197+
return creds.length != 2 ? null : (!isEmpty(creds[0]) && !isEmpty(creds[1]) ? creds : null);
198+
}
199+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
*
1717
*/
1818

19-
package org.hswebframework.web.authorization.oauth2.dao;
19+
package org.hswebframework.web.dao.authorization.oauth2;
2020

21-
import org.hswebframework.web.authorization.oauth2.entity.AuthorizationCodeEntity;
21+
import org.hswebframework.web.entity.authorization.oauth2.AuthorizationCodeEntity;
2222
import org.hswebframework.web.dao.InsertDao;
2323
import org.hswebframework.web.dao.dynamic.DeleteByEntityDao;
2424
import org.hswebframework.web.dao.dynamic.QueryByEntityDao;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
*
1717
*/
1818

19-
package org.hswebframework.web.authorization.oauth2.dao;
19+
package org.hswebframework.web.dao.authorization.oauth2;
2020

21-
import org.hswebframework.web.authorization.oauth2.entity.OAuth2AccessEntity;
21+
import org.hswebframework.web.entity.authorization.oauth2.OAuth2AccessEntity;
2222
import org.hswebframework.web.dao.InsertDao;
2323
import org.hswebframework.web.dao.dynamic.DeleteByEntityDao;
2424
import org.hswebframework.web.dao.dynamic.QueryByEntityDao;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
*
1717
*/
1818

19-
package org.hswebframework.web.authorization.oauth2.dao;
19+
package org.hswebframework.web.dao.authorization.oauth2;
2020

21-
import org.hswebframework.web.authorization.oauth2.entity.OAuth2ClientEntity;
21+
import org.hswebframework.web.entity.authorization.oauth2.OAuth2ClientEntity;
2222
import org.hswebframework.web.dao.CrudDao;
2323

2424
/**
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright 2016 http://www.hswebframework.org
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ http://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
~
17+
~
18+
-->
19+
20+
<project xmlns="http://maven.apache.org/POM/4.0.0"
21+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
22+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
23+
<parent>
24+
<artifactId>hsweb-authorization-oauth2-server-dao</artifactId>
25+
<groupId>org.hswebframework.web</groupId>
26+
<version>3.0-SNAPSHOT</version>
27+
</parent>
28+
<modelVersion>4.0.0</modelVersion>
29+
30+
<artifactId>hsweb-authorization-oauth2-server-dao-mybatis</artifactId>
31+
32+
<dependencies>
33+
<dependency>
34+
<groupId>org.hswebframework.web</groupId>
35+
<artifactId>hsweb-authorization-oauth2-server-dao-api</artifactId>
36+
<version>${project.version}</version>
37+
</dependency>
38+
39+
<dependency>
40+
<groupId>org.hswebframework.web</groupId>
41+
<artifactId>hsweb-commons-dao-mybatis</artifactId>
42+
<version>${project.version}</version>
43+
</dependency>
44+
</dependencies>
45+
</project>

0 commit comments

Comments
 (0)