Skip to content

Commit 4be7a98

Browse files
committed
加入oauth2
1 parent ab79b73 commit 4be7a98

File tree

23 files changed

+644
-81
lines changed

23 files changed

+644
-81
lines changed

pom.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@
4242
<module>spring-cloud-starter-gray-eureka-server</module>
4343
</modules>
4444

45+
<distributionManagement>
46+
<repository>
47+
<id>releases</id>
48+
<url>http://maven.zmops.cc:8081/nexus/content/repositories/releases</url>
49+
</repository>
50+
<snapshotRepository>
51+
<id>snapshots</id>
52+
<url>http://maven.zmops.cc:8081/nexus/content/repositories/snapshots</url>
53+
</snapshotRepository>
54+
</distributionManagement>
55+
4556

4657
<licenses>
4758
<license>

spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayDecisionFactoryConfiguration.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ public TrackAttributeGrayDecisionFactory trackAttributeGrayDecisionFactory() {
5353
return new TrackAttributeGrayDecisionFactory();
5454
}
5555

56+
@Bean
57+
public TrackAttributesGrayDecisionFactory trackAttributesGrayDecisionFactory() {
58+
return new TrackAttributesGrayDecisionFactory();
59+
}
60+
5661
@Bean
5762
public FlowRateGrayDecisionFactory flowRateGrayDecisionFactory(){
5863
return new FlowRateGrayDecisionFactory();
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package cn.springcloud.gray.decision.factory;
2+
3+
import cn.springcloud.gray.decision.GrayDecision;
4+
import cn.springcloud.gray.decision.compare.Comparators;
5+
import cn.springcloud.gray.decision.compare.PredicateComparator;
6+
import cn.springcloud.gray.request.GrayHttpTrackInfo;
7+
import lombok.Getter;
8+
import lombok.Setter;
9+
10+
import java.util.Arrays;
11+
import java.util.Collection;
12+
import java.util.Collections;
13+
import java.util.List;
14+
15+
16+
public class TrackAttributesGrayDecisionFactory extends CompareGrayDecisionFactory<TrackAttributesGrayDecisionFactory.Config> {
17+
18+
public TrackAttributesGrayDecisionFactory() {
19+
super(Config.class);
20+
}
21+
22+
23+
@Override
24+
public GrayDecision apply(Config configBean) {
25+
return args -> {
26+
GrayHttpTrackInfo grayTrackInfo = (GrayHttpTrackInfo) args.getGrayRequest().getGrayTrackInfo();
27+
if (grayTrackInfo == null) {
28+
return false;
29+
}
30+
PredicateComparator<Collection<String>> predicateComparator = Comparators.getCollectionStringComparator(configBean.getCompareMode());
31+
if (predicateComparator == null) {
32+
return false;
33+
}
34+
return predicateComparator.test(Arrays.asList(grayTrackInfo.getAttribute(configBean.getName())), configBean.getValues());
35+
};
36+
}
37+
38+
@Setter
39+
@Getter
40+
public static class Config extends CompareGrayDecisionFactory.CompareConfig {
41+
private String name;
42+
private List<String> values;
43+
44+
public void setValues(List<String> values) {
45+
this.values = values;
46+
Collections.sort(values);
47+
}
48+
}
49+
50+
}

spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpIPGrayInfoTracker.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ public class HttpIPGrayInfoTracker implements HttpGrayInfoTracker {
1212

1313

1414
public void call(GrayHttpTrackInfo trackInfo, HttpServletRequest request) {
15-
trackInfo.setTraceIp(WebUtils.getIpAddr(request));
15+
String ip = WebUtils.getIpAddr(request);
16+
trackInfo.setTraceIp(ip);
17+
trackInfo.setAttribute("track_ip", ip);
1618
log.debug("记录下ip:{}", trackInfo.getTraceIp());
1719
}
1820

spring-cloud-gray-samples/spring-cloud-gray-server-sample/src/main/java/cn/springcloud/gray/server/app/web/domain/fo/LoginFO.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package cn.springcloud.gray.server.app.web.domain.fo;
22

3+
import lombok.Data;
4+
import lombok.NoArgsConstructor;
5+
6+
@Data
7+
@NoArgsConstructor
38
public class LoginFO {
49
private String username;
510
private String password;

spring-cloud-gray-samples/spring-cloud-gray-server-sample/src/main/java/cn/springcloud/gray/server/app/web/rest/UserResource.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,50 @@
22

33
import cn.springcloud.gray.server.app.web.domain.fo.LoginFO;
44
import cn.springcloud.gray.server.app.web.domain.vo.LoginVO;
5+
import cn.springcloud.gray.server.oauth2.Oauth2Service;
6+
import cn.springcloud.gray.server.oauth2.TokenRequestInfo;
57
import cn.springcloud.gray.server.resources.domain.ApiRes;
68
import com.google.common.collect.ImmutableBiMap;
9+
import org.apache.commons.lang3.StringUtils;
710
import org.slf4j.Logger;
811
import org.slf4j.LoggerFactory;
12+
import org.springframework.beans.factory.annotation.Autowired;
13+
import org.springframework.security.core.GrantedAuthority;
14+
import org.springframework.security.core.authority.SimpleGrantedAuthority;
15+
import org.springframework.security.core.userdetails.User;
16+
import org.springframework.security.oauth2.common.OAuth2AccessToken;
917
import org.springframework.web.bind.annotation.*;
1018

19+
import java.util.ArrayList;
20+
import java.util.List;
1121
import java.util.Map;
1222

13-
@RequestMapping("/user")
23+
@RequestMapping("/gray/user")
1424
@RestController
1525
public class UserResource {
1626

1727
private static final Logger log = LoggerFactory.getLogger(UserResource.class);
1828

29+
@Autowired
30+
private Oauth2Service oauth2Service;
1931

2032
@PostMapping(value = "/login")
2133
public ApiRes<Map<String, String>> login(@RequestBody LoginFO fo) {
34+
if(!StringUtils.equals("stu-admin", fo.getUsername())
35+
|| !StringUtils.equals("stu~!@345", fo.getPassword())){
36+
return ApiRes.<Map<String, String>>builder()
37+
.code("1")
38+
.message("用户名或密码不正确")
39+
.build();
40+
}
41+
42+
List<GrantedAuthority> authorities = new ArrayList<>();
43+
User user = new User(fo.getUsername(), fo.getPassword(), authorities);
44+
OAuth2AccessToken oAuth2AccessToken = oauth2Service.getAccessToken(
45+
TokenRequestInfo.builder().userDetails(user).build());
2246
return ApiRes.<Map<String, String>>builder()
2347
.code("0")
24-
.data(ImmutableBiMap.of("token", "admin-token"))
48+
.data(ImmutableBiMap.of("token", oAuth2AccessToken.getValue()))
2549
.build();
2650
}
2751

spring-cloud-gray-server/pom.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@
119119
<!-- <optional>true</optional>-->
120120
</dependency>
121121

122+
<dependency>
123+
<groupId>org.springframework.security.oauth</groupId>
124+
<artifactId>spring-security-oauth2</artifactId>
125+
</dependency>
126+
<dependency>
127+
<groupId>org.springframework.security</groupId>
128+
<artifactId>spring-security-jwt</artifactId>
129+
</dependency>
130+
122131
</dependencies>
123132

124133
</project>
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
package cn.springcloud.gray.server.configuration;
2+
3+
import cn.springcloud.gray.server.oauth2.DefaultTokenGranter;
4+
import cn.springcloud.gray.server.oauth2.Oauth2Service;
5+
import cn.springcloud.gray.server.resources.domain.ApiRes;
6+
import cn.springcloud.gray.server.utils.WebHelper;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
11+
import org.springframework.context.annotation.Bean;
12+
import org.springframework.context.annotation.Configuration;
13+
import org.springframework.core.io.ClassPathResource;
14+
import org.springframework.http.HttpMethod;
15+
import org.springframework.security.access.AccessDeniedException;
16+
import org.springframework.security.authentication.AuthenticationManager;
17+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
18+
import org.springframework.security.core.AuthenticationException;
19+
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
20+
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
21+
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
22+
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
23+
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
24+
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
25+
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
26+
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
27+
import org.springframework.security.oauth2.provider.ClientDetailsService;
28+
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
29+
import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter;
30+
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
31+
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
32+
import org.springframework.security.oauth2.provider.token.TokenStore;
33+
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
34+
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
35+
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
36+
import org.springframework.security.web.AuthenticationEntryPoint;
37+
import org.springframework.security.web.access.AccessDeniedHandler;
38+
39+
import javax.servlet.http.HttpServletRequest;
40+
import javax.servlet.http.HttpServletResponse;
41+
import java.io.IOException;
42+
import java.security.KeyPair;
43+
44+
@ConditionalOnProperty(value = "gray.server.security.oauth2.enabled", matchIfMissing = true)
45+
@Configuration
46+
public class OAuth2Config {
47+
48+
private static final Logger log = LoggerFactory.getLogger(OAuth2Config.class);
49+
50+
@Bean
51+
public JwtTokenStore tokenStore() {
52+
return new JwtTokenStore(jwtAccessTokenConverter());
53+
}
54+
55+
/**
56+
* This bean generates an token enhancer, which manages the exchange between JWT acces tokens and Authentication
57+
* in both direction.
58+
*
59+
* @return an access token converter configured with the authorization server's public/private keys
60+
*/
61+
@Bean
62+
public JwtAccessTokenConverter jwtAccessTokenConverter() {
63+
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
64+
KeyPair keyPair = new KeyStoreKeyFactory(
65+
new ClassPathResource("keystore.jks"), "password".toCharArray())
66+
.getKeyPair("selfsigned");
67+
converter.setKeyPair(keyPair);
68+
return converter;
69+
}
70+
71+
@Bean
72+
public OAuth2RequestFactory requestFactory(ClientDetailsService clientDetailsService) {
73+
return new DefaultOAuth2RequestFactory(clientDetailsService);
74+
}
75+
76+
@Bean
77+
public RefreshTokenGranter refreshTokenGranter(AuthorizationServerTokenServices tokenServices,
78+
ClientDetailsService clientDetailsService,
79+
OAuth2RequestFactory requestFactory) {
80+
return new RefreshTokenGranter(tokenServices, clientDetailsService, requestFactory);
81+
}
82+
83+
@Bean
84+
public DefaultTokenGranter defaultTokenGranter(AuthorizationServerTokenServices tokenServices,
85+
ClientDetailsService clientDetailsService,
86+
OAuth2RequestFactory requestFactory) {
87+
return new DefaultTokenGranter(tokenServices, clientDetailsService, requestFactory);
88+
}
89+
90+
91+
@Bean
92+
public Oauth2Service oauth2Service(
93+
ClientDetailsService clientDetailsService,
94+
OAuth2RequestFactory requestFactory,
95+
DefaultTokenGranter defaultTokenGranter){
96+
return new Oauth2Service(clientDetailsService, requestFactory, defaultTokenGranter);
97+
}
98+
99+
100+
@Configuration
101+
@EnableResourceServer
102+
public static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
103+
104+
@Autowired
105+
private TokenStore tokenStore;
106+
107+
@Override
108+
public void configure(HttpSecurity http) throws Exception {
109+
http.formLogin().and()
110+
.authorizeRequests()
111+
.antMatchers("/gray/user/login").permitAll()
112+
.antMatchers("/gray/user/login").permitAll()
113+
.antMatchers("/gray/instances/enable").permitAll()
114+
.antMatchers("/gray/instances").permitAll()
115+
.antMatchers("/gray/trackDefinitions").permitAll()
116+
117+
.antMatchers(HttpMethod.OPTIONS, "/gray/**").permitAll()
118+
.antMatchers("/gray/service/**").authenticated()
119+
.antMatchers("/gray/track/**").authenticated()
120+
.anyRequest().permitAll()
121+
.and()
122+
.csrf().disable();
123+
}
124+
125+
@Override
126+
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
127+
resources.authenticationEntryPoint(new AuthenticationEntryPoint() {
128+
@Override
129+
public void commence(HttpServletRequest request, HttpServletResponse response,
130+
AuthenticationException authException)
131+
throws IOException {
132+
log.debug("path:{} -> {}", request.getServletPath(), authException.getMessage());
133+
134+
response.setContentType("application/json");
135+
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
136+
137+
ApiRes<Void> res = ApiRes.<Void>builder()
138+
.code(String.valueOf(HttpServletResponse.SC_UNAUTHORIZED)).message("无权访问").build();
139+
WebHelper.response(response, res);
140+
}
141+
}).accessDeniedHandler(new AccessDeniedHandler() {
142+
@Override
143+
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
144+
log.debug("path:{} -> {}", request.getServletPath(), accessDeniedException.getMessage());
145+
146+
response.setContentType("application/json");
147+
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
148+
ApiRes<Void> res = ApiRes.<Void>builder()
149+
.code(String.valueOf(HttpServletResponse.SC_BAD_REQUEST)).message("无权访问").build();
150+
WebHelper.response(response, res);
151+
}
152+
});
153+
}
154+
}
155+
156+
157+
@Configuration
158+
@EnableAuthorizationServer
159+
public static class OAuth2Config2 extends AuthorizationServerConfigurerAdapter {
160+
@Autowired
161+
private AuthenticationManager authenticationManager;
162+
@Autowired
163+
private JwtTokenStore tokenStore;
164+
@Autowired
165+
private JwtAccessTokenConverter jwtAccessTokenConverter;
166+
167+
168+
@Override
169+
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
170+
clients.inMemory()
171+
.withClient("gray-server")
172+
.secret("V@JA-#i+6BkDhhq9")
173+
.authorizedGrantTypes("client_credentials", "refresh_token", "default")
174+
.accessTokenValiditySeconds(3600 * 24 * 30)
175+
.refreshTokenValiditySeconds(3600 * 24 * 30 * 2)
176+
;
177+
}
178+
179+
180+
@Override
181+
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
182+
security.tokenKeyAccess("permitAll()").checkTokenAccess(
183+
"isAuthenticated()");
184+
}
185+
186+
@Override
187+
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
188+
// super.configure(endpoints);
189+
endpoints.tokenStore(tokenStore).tokenEnhancer(jwtAccessTokenConverter).authenticationManager(authenticationManager);
190+
endpoints.exceptionTranslator(null);
191+
192+
// endpoints.getFrameworkEndpointHandlerMapping().setMappings("/oauth/confirm_access", "/oauth/confirm_access2"); //oatuh2 授权码确认页面
193+
194+
}
195+
}
196+
}

0 commit comments

Comments
 (0)