1.架構圖
技術團隊通過一段時間的積累后,我們打算對往后的一些新項目采用Spring Cloud技術棧來實現。大概微服務的架構如下:

- Euraka注冊中心集群
- Zuul網關集群
- 各模塊微服務集群
- Nginx實現負載均衡
- Spring Cloud Config 統一配置中心
- Monitor微服務監控
2.注冊中心
注冊中心很簡單,這里主要說一下注冊中心的高可用配置‘

這里看到我設置了node-1,node-2兩個配置文件,就是在啟動應用的時候,分別啟動不同的配置。
node-1的端口為9010,並向node-2注冊,配置如下:
server: port: 9010 spring: application: name: register ##name必須一樣,不然高可用會導致unavailable-replicas eureka: instance: hostname: register1 client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://register2:9011/eureka/
node-2的端口為9011,並向node-1注冊,配置如下:
server: port: 9011 spring: application: name: register ##name必須一樣,不然高可用會導致unavailable-replicas eureka: instance: hostname: register2 client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://register2:9010/eureka/
這里注意一下:spring.application.name需要一致,不然會出現unavailable-replicas的情況
3.OAUTH2認證服務器
我這里采用認證服務器與資源服務器分離的方式。
3.1 oauth2 server 配置
我采取了數據庫和redis兩種方式來存儲token,可以方便切換,生成環境下建議使用redis方式。
AuthorizationServer:
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private DataSource dataSource;
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Bean
RedisTokenStore redisTokenStore(){
return new RedisTokenStore(redisConnectionFactory);
}
token存儲數據庫
// @Bean
// public JdbcTokenStore jdbcTokenStore(){
// return new JdbcTokenStore(dataSource);
// }
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetails());
}
@Bean
public ClientDetailsService clientDetails() {
return new JdbcClientDetailsService(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(redisTokenStore())
.userDetailsService(userDetailsService)
.authenticationManager(authenticationManager);
endpoints.tokenServices(defaultTokenServices());
}
/**
* <p>注意,自定義TokenServices的時候,需要設置@Primary,否則報錯,</p>
* @return
*/
@Primary
@Bean
public DefaultTokenServices defaultTokenServices(){
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(redisTokenStore());
tokenServices.setSupportRefreshToken(true);
tokenServices.setClientDetailsService(clientDetails());
tokenServices.setAccessTokenValiditySeconds(60*60*12); // token有效期自定義設置,默認12小時
tokenServices.setRefreshTokenValiditySeconds(60 * 60 * 24 * 7);//默認30天,這里修改
return tokenServices;
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()");
security .checkTokenAccess("isAuthenticated()");
security.allowFormAuthenticationForClients();
}
}
WebSecurityConfig:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().and()
.csrf().disable()
.httpBasic();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/favor.ioc");
}
}
3.2 ResourceServer
因為我們認證中心會提供User信息,所以也是資源服務器。
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter{
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(new Http401AuthenticationEntryPoint("Bearer realm=\"webrealm\""))
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.httpBasic();
}
}
4.資源服務器 Resource
ResourceServer:
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(new Http401AuthenticationEntryPoint("Bearer realm=\"webrealm\""))
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.httpBasic();
}
}
主要是application.yml的配置
security: oauth2: resource: id: resource user-info-uri: http://10.10.8.2:9030/uaa/user prefer-token-info: false
5.Zuul網關
5.1開啟支持Sso
@Configuration
@EnableOAuth2Sso
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
5.2配置
spring:
application:
name: Gateway
zipkin:
base-url: http://10.10.8.2:9050
server:
port: 9030
eureka:
instance:
prefer-ip-address: true #使用IP注冊
instance-id: ${spring.cloud.client.ipAddress}:${server.port}
client:
service-url:
defaultZone: http://register1:9010/eureka/,http://register2:9011/eureka/
###actuator監控點 start####
endpoints:
health:
sensitive: false
enabled: true
##默認情況下很多端點是不允許訪問的,會返回401:Unauthorized
management:
security:
enabled: false
###actuator監控點 end####
zuul:
host:
connect-timeout-millis: 10000
socket-timeout-millis: 60000
routes:
uaa:
path: /uaa/**
strip-prefix: true
sensitiveHeaders:
serviceId: auth2.0-center
security:
basic:
enabled: false
oauth2:
client:
access-token-uri: http://10.10.8.2:9030/uaa/oauth/token ##網關的地址
user-authorization-uri: http://10.10.8.2:9030/uaa/oauth/authorize
resource:
user-info-uri: http://10.10.8.2:9030/uaa/user
prefer-token-info: false
##############end#####################
####超時配置####
ribbon:
ReadTimeout: 10000
ConnectTimeout: 10000
MaxAutoRetries: 1
MaxAutoRetriesNextServer: 2
eureka:
enabled: true
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 600000
###超時配置###
6.展示
分別啟動register、auth-center、gateway、resource。效果如下:

6.1獲取access_token

6.2刷新token

6.3用access_token獲取資源


7.結束
到這里Spring Cloud OAUTH2.0統一認證的骨架就完成了,具體項目拿過來修改就可以滿足項目的需求了。
