一,单点登录概述
(一)什么是单点登录:每个子系统从第三方认证系统中查找而不是每个系统都通过各自的session校验。
(三)单点登录实现框架:
apache Shiro
CAS
springsecurity
二。Oauth2认证微信认证第三方登录
1.授权码模式:资源拥有者(用户)发起微信登录,平台调用微信接口,到达授权页面,手机wx扫码登录用户同意授权,微信会对用户进行验证,通过后给平台一个授权码,平台
携带授权码到微信认证服务申请令牌,并返回令牌到平台,平台再携带令牌调微信用户信息服务,微信用户信息服务校验令牌合法性,响应给平台,
平台显示微信头像。
客户端(平台)拿到授权码去认证服务申请令牌,授权服务通过私钥加密生成令牌,
令牌给客户端,携带令牌访问资源服务
课程服务相当于资源存储公钥(根据公钥校验令牌合法性===公钥把令牌解开,放行;;解不开拒绝服务)
课程服务相当于资源服务
对swagger进行放行
"/swagger-resources","/swagger-resources/configuration/security",
"/swagger-ui.html","/webjars/**","/course/coursepic/list/*").permitAll()
mport org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)//激活方法上的PreAuthorize注解
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
//公钥
private static final String PUBLIC_KEY = "publickey.txt";
//定义JwtTokenStore,使用jwt令牌
@Bean
public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
return new JwtTokenStore(jwtAccessTokenConverter);
}
//定义JJwtAccessTokenConverter,使用jwt令牌
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setVerifierKey(getPubKey());
return converter;
}
/**
* 获取非对称加密公钥 Key
* @return 公钥 Key
*/
private String getPubKey() {
Resource resource = new ClassPathResource(PUBLIC_KEY);
try {
InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream());
BufferedReader br = new BufferedReader(inputStreamReader);
return br.lines().collect(Collectors.joining("\n"));
} catch (IOException ioe) {
return null;
}
}
//Http安全配置,对每个到达系统的http请求链接进行校验
@Override
public void configure(HttpSecurity http) throws Exception {
//所有请求必须认证通过
http.authorizeRequests()
.antMatchers("/v2/api-docs", "/swagger-resources/configuration/ui",
"/swagger-resources","/swagger-resources/configuration/security",
"/swagger-ui.html","/webjars/**","/course/coursepic/list/*").permitAll()
.anyRequest().authenticated();
}
}
访问课程服务只有:头部KEY:authorization
value:Bear+accesstoken
才可以访问
2.密码算法模式
不用申请授权码,用户名,密码就可以;
jwt中包含了用户信息,可以避免资源服务解决不了验证还要请求认证服务来验证。效率高
是个json串便于解析,易拓展,非对称安全,但长
分为头部(加密算法),负载(自己加),签名(认证服务端签发的唯一防止窃取)。
(一)认证服务的controller
如何申请令牌
clientid,clientpassword
bodyheader封装在HTTPentity
getHttpBasic
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("grant_type","password");
body.add("username","itcast");
body.add("password","123");
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Authorization",this.getHttpBasic("XcWebApp","XcWebApp"));
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body,headers);
private String getHttpBasic(String clientId, String clientPassword) {
String value =clientId+":"+clientPassword ;
byte[] encode = Base64Utils.encode(value.getBytes());
return "Basic "+new String(encode);
}
uri
//http://localhost:40400/auth/oauth/token
ServiceInstance serviceInstance = loadBalancerClient.choose(XcServiceList.XC_SERVICE_UCENTER_AUTH);
// http://localhost:40400
URI uri = serviceInstance.getUri();
String url = uri+"/auth/oauth/token";
ResponseEntity<Map> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Map.class);
Map map = responseEntity.getBody();
1 Override
2 @PostMapping("/userlogin")
3 public LoginResult login(LoginRequest loginRequest) {
4
5 //判断参数
6 if (StringUtils.isEmpty(loginRequest.getUsername())){
7 ExceptionCast.cast(AuthCode.AUTH_USERNAME_NONE);
8 }
9 if (StringUtils.isEmpty(loginRequest.getPassword())){
10 ExceptionCast.cast(AuthCode.AUTH_PASSWORD_NONE);
11 }
12
13 //申请令牌
14 AuthToken authToken = authService.login(loginRequest.getUsername(),loginRequest.getPassword(),clientId,clientSecret);
15
16 String jti = authToken.getJti();
17
18 //将令牌信息存入cookie
19 this.saveTokenToCookie(jti);
20
21 return new LoginResult(CommonCode.SUCCESS,jti);
22 }
23
24 private void saveTokenToCookie(String jti) {
25 HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
26
27 //httpOnly:false。 允许浏览器获取cookie
28 CookieUtil.addCookie(response,cookieDomain,"/","uid",jti,cookieMaxAge,false);
29 }
测试
实际结果
(二)认证服务的service
public AuthToken login(String username, String password, String clientId, String clientSecret) {
//申请令牌
AuthToken authToken = this.applyToken(username,password,clientId,clientSecret);
//将令牌存入redis
boolean result = this.saveTokenToRedis(authToken);
if (!result){
//存入失败
ExceptionCast.cast(AuthCode.AUTH_LOGIN_TOKEN_SAVEFAIL);
}
return authToken;
}
//存入redis
private boolean saveTokenToRedis(AuthToken authToken) {
String key = "user_token:"+authToken.getJti();
String tokenString = JSON.toJSONString(authToken);
stringRedisTemplate.boundValueOps(key).set(tokenString,tokenValiditySeconds, TimeUnit.SECONDS);
Long expire = stringRedisTemplate.getExpire(key);
return expire>0;
}
//申请令牌
private AuthToken applyToken(String username, String password, String clientId, String clientSecret) {
ServiceInstance serviceInstance = loadBalancerClient.choose(XcServiceList.XC_SERVICE_UCENTER_AUTH);
URI uri = serviceInstance.getUri();
String url = uri+"/auth/oauth/token";
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("grant_type","password");
body.add("username",username);
body.add("password",password);
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Authorization",this.getHttpBasic(clientId,clientSecret));
HttpEntity<MultiValueMap<String,String>> requestEntity = new HttpEntity<>(body,headers);
restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
@Override
public void handleError(ClientHttpResponse response) throws IOException {
if (response.getRawStatusCode() != 400 && response.getRawStatusCode() != 401){
super.handleError(response);
}
}
});
ResponseEntity<Map> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Map.class);
Map map = responseEntity.getBody();
if (map == null || map.get("access_token")==null || map.get("refresh_token")==null || map.get("jti")==null){
ExceptionCast.cast(AuthCode.AUTH_LOGIN_APPLYTOKEN_FAIL);
}
AuthToken authToken = new AuthToken();
authToken.setAccess_token((String) map.get("access_token"));
authToken.setRefresh_token((String) map.get("refresh_token"));
authToken.setJti((String) map.get("jti"));
return authToken;
}
三,具体单点登录实现认证服务
(一)配置文件
1
AuthorizationServerConfig
密钥非对称加密,私钥加密,公钥解密
package com.xuecheng.auth.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.bootstrap.encrypt.KeyProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.security.KeyPair;
@Configuration
@EnableAuthorizationServer
class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private DataSource dataSource;
//jwt令牌转换器
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Autowired
UserDetailsService userDetailsService;
@Autowired
AuthenticationManager authenticationManager;
@Autowired
TokenStore tokenStore;
@Autowired
private CustomUserAuthenticationConverter customUserAuthenticationConverter;
//读取密钥的配置
@Bean("keyProp")
public KeyProperties keyProperties(){
return new KeyProperties();
}
@Resource(name = "keyProp")
private KeyProperties keyProperties;
//客户端配置
@Bean
public ClientDetailsService clientDetails() {
return new JdbcClientDetailsService(dataSource);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(this.dataSource).clients(this.clientDetails());
/* clients.inMemory()
.withClient("XcWebApp")//客户端id
.secret("XcWebApp")//密码,要保密
.accessTokenValiditySeconds(60)//访问令牌有效期
.refreshTokenValiditySeconds(60)//刷新令牌有效期
//授权客户端请求认证服务的类型authorization_code:根据授权码生成令牌,
// client_credentials:客户端认证,refresh_token:刷新令牌,password:密码方式认证
.authorizedGrantTypes("authorization_code", "client_credentials", "refresh_token", "password")
.scopes("app");//客户端范围,名称自定义,必填*/
}
//token的存储方法
// @Bean
// public InMemoryTokenStore tokenStore() {
// //将令牌存储到内存
// return new InMemoryTokenStore();
// }
// @Bean
// public TokenStore tokenStore(RedisConnectionFactory redisConnectionFactory){
// RedisTokenStore redisTokenStore = new RedisTokenStore(redisConnectionFactory);
// return redisTokenStore;
// }
@Bean
@Autowired
public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
return new JwtTokenStore(jwtAccessTokenConverter);
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter(CustomUserAuthenticationConverter customUserAuthenticationConverter) {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyPair keyPair = new KeyStoreKeyFactory
(keyProperties.getKeyStore().getLocation(), keyProperties.getKeyStore().getSecret().toCharArray())
.getKeyPair(keyProperties.getKeyStore().getAlias(),keyProperties.getKeyStore().getPassword().toCharArray());
converter.setKeyPair(keyPair);
//配置自定义的CustomUserAuthenticationConverter
DefaultAccessTokenConverter accessTokenConverter = (DefaultAccessTokenConverter) converter.getAccessTokenConverter();
accessTokenConverter.setUserTokenConverter(customUserAuthenticationConverter);
return converter;
}
//授权服务器端点配置
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
/*Collection<TokenEnhancer> tokenEnhancers = applicationContext.getBeansOfType(TokenEnhancer.class).values();
TokenEnhancerChain tokenEnhancerChain=new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(new ArrayList<>(tokenEnhancers));
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setReuseRefreshToken(true);
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setTokenStore(tokenStore);
defaultTokenServices.setAccessTokenValiditySeconds(1111111);
defaultTokenServices.setRefreshTokenValiditySeconds(1111111);
defaultTokenServices.setTokenEnhancer(tokenEnhancerChain);
endpoints
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)
//.tokenStore(tokenStore);
.tokenServices(defaultTokenServices);*/
endpoints.accessTokenConverter(jwtAccessTokenConverter)
.authenticationManager(authenticationManager)//认证管理器
.tokenStore(tokenStore)//令牌存储
.userDetailsService(userDetailsService);//用户信息service
}
//授权服务器的安全配置
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
// oauthServer.checkTokenAccess("isAuthenticated()");//校验token需要认证通过,可采用http basic认证
oauthServer.allowFormAuthenticationForClients()
.passwordEncoder(new BCryptPasswordEncoder())
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
}
2
CustomUserAuthenticationConverter
生成令牌信息
package com.xuecheng.auth.config;
import com.xuecheng.auth.service.UserJwt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.Map;
@Component
public class CustomUserAuthenticationConverter extends DefaultUserAuthenticationConverter {
@Autowired
UserDetailsService userDetailsService;
@Override
public Map<String, ?> convertUserAuthentication(Authentication authentication) {
LinkedHashMap response = new LinkedHashMap();
String name = authentication.getName();
response.put("user_name", name);
Object principal = authentication.getPrincipal();
UserJwt userJwt = null;
if(principal instanceof UserJwt){
userJwt = (UserJwt) principal;
}else{
//refresh_token默认不去调用userdetailService获取用户信息,这里我们手动去调用,得到 UserJwt
UserDetails userDetails = userDetailsService.loadUserByUsername(name);
userJwt = (UserJwt) userDetails;
}
response.put("name", userJwt.getName());
response.put("id", userJwt.getId());
response.put("utype",userJwt.getUtype());
response.put("userpic",userJwt.getUserpic());
response.put("companyId",userJwt.getCompanyId());
if (authentication.getAuthorities() != null && !authentication.getAuthorities().isEmpty()) {
response.put("authorities", AuthorityUtils.authorityListToSet(authentication.getAuthorities()));
}
return response;
}
}
3
WebSecurityConfig
对登录放行
密码加盐加密
1 import org.springframework.context.annotation.Bean;
2 import org.springframework.context.annotation.Configuration;
3 import org.springframework.core.annotation.Order;
4 import org.springframework.security.authentication.AuthenticationManager;
5 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
6 import org.springframework.security.config.annotation.web.builders.WebSecurity;
7 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
8 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
9 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
10 import org.springframework.security.crypto.password.PasswordEncoder;
11
12 @Configuration
13 @EnableWebSecurity
14 @Order(-1)
15 class WebSecurityConfig extends WebSecurityConfigurerAdapter {
16
17 @Override
18 public void configure(WebSecurity web) throws Exception {
19 web.ignoring().antMatchers("/userlogin","/userlogout","/userjwt");
20
21 }
22 @Bean
23 @Override
24 public AuthenticationManager authenticationManagerBean() throws Exception {
25 AuthenticationManager manager = super.authenticationManagerBean();
26 return manager;
27 }
28 //采用bcrypt对密码进行编码
29 @Bean
30 public PasswordEncoder passwordEncoder() {
31 return new BCryptPasswordEncoder();
32 }
33
34 @Override
35 public void configure(HttpSecurity http) throws Exception {
36 http.csrf().disable()
37 .httpBasic().and()
38 .formLogin()
39 .and()
40 .authorizeRequests().anyRequest().authenticated();
41
42 }
43 }
authservice写认证
package com.xuecheng.auth.service;
import com.alibaba.fastjson.JSON;
import com.xuecheng.filesystem.framework.client.XcServiceList;
import com.xuecheng.filesystem.framework.domain.ucenter.ext.AuthToken;
import com.xuecheng.filesystem.framework.domain.ucenter.response.AuthCode;
import com.xuecheng.filesystem.framework.exception.ExceptionCast;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class AuthService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Value("${auth.tokenValiditySeconds}")
private long tokenValiditySeconds;
/**
* 用户认证登录,申请令牌
* @param username
* @param password
* @param clientId
* @param clientSecret
* @return
*/
public AuthToken login(String username, String password, String clientId, String clientSecret) {
//申请令牌
AuthToken authToken = this.applyToken(username,password,clientId,clientSecret);
//将令牌存入redis
boolean result = this.saveTokenToRedis(authToken);
if (!result){
//存入失败
ExceptionCast.cast(AuthCode.AUTH_LOGIN_TOKEN_SAVEFAIL);
}
return authToken;
}
//存入redis
private boolean saveTokenToRedis(AuthToken authToken) {
String key = "user_token:"+authToken.getJti();
String tokenString = JSON.toJSONString(authToken);
stringRedisTemplate.boundValueOps(key).set(tokenString,tokenValiditySeconds, TimeUnit.SECONDS);
Long expire = stringRedisTemplate.getExpire(key);
return expire>0;
}
//申请令牌
private AuthToken applyToken(String username, String password, String clientId, String clientSecret) {
ServiceInstance serviceInstance = loadBalancerClient.choose(XcServiceList.XC_SERVICE_UCENTER_AUTH);
URI uri = serviceInstance.getUri();
String url = uri+"/auth/oauth/token";
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("grant_type","password");
body.add("username",username);
body.add("password",password);
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Authorization",this.getHttpBasic(clientId,clientSecret));
HttpEntity<MultiValueMap<String,String>> requestEntity = new HttpEntity<>(body,headers);
restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
@Override
public void handleError(ClientHttpResponse response) throws IOException {
if (response.getRawStatusCode() != 400 && response.getRawStatusCode() != 401){
super.handleError(response);
}
}
});
ResponseEntity<Map> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Map.class);
Map map = responseEntity.getBody();
if (map == null || map.get("access_token")==null || map.get("refresh_token")==null || map.get("jti")==null){
ExceptionCast.cast(AuthCode.AUTH_LOGIN_APPLYTOKEN_FAIL);
}
AuthToken authToken = new AuthToken();
authToken.setAccess_token((String) map.get("access_token"));
authToken.setRefresh_token((String) map.get("refresh_token"));
authToken.setJti((String) map.get("jti"));
return authToken;
}
private String getHttpBasic(String clientId, String clientSecret) {
String value = clientId+":"+clientSecret;
byte[] encode = Base64Utils.encode(value.getBytes());
return "Basic "+new String(encode);
}
public AuthToken getTokenFormRedis(String jti) {
String key="user_token:"+jti;
String tokenString = stringRedisTemplate.boundValueOps(key).get();
AuthToken authToken = JSON.parseObject(tokenString, AuthToken.class);
return authToken;
}
public void delTokenFromRedis(String jti) {
String key="user_token:"+jti;
stringRedisTemplate.delete(key);
}
}
userjwt用户信息融到令牌中
import lombok.Data;
import lombok.ToString;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import java.util.Collection;
@Data
@ToString
public class UserJwt extends User {
private String id;
private String name;
private String userpic;
private String utype;
private String companyId;
public UserJwt(String username, String password, Collection<? extends GrantedAuthority> authorities) {
super(username, password, authorities);
}
}
yml配置
1访问路径,redis信息
2auth设置redis过期时间==session过期时间(过期重新登录用)
3私钥位置
4cookie域名(适配到不同域中)和maxage
server:
port: ${PORT:40400}
servlet:
context-path: /auth
spring:
application:
name: xc-service-ucenter-auth
redis:
host: ${REDIS_HOST:127.0.0.1}
port: ${REDIS_PORT:6379}
timeout: 5000 #连接超时 毫秒
jedis:
pool:
maxActive: 3
maxIdle: 3
minIdle: 1
maxWait: -1 #连接池最大等行时间 -1没有限制
datasource:
druid:
url: ${MYSQL_URL:jdbc:mysql://localhost:3306/xc_user?characterEncoding=utf-8}
username: root
password: root
driverClassName: com.mysql.jdbc.Driver
initialSize: 5 #初始建立连接数量
minIdle: 5 #最小连接数量
maxActive: 20 #最大连接数量
maxWait: 10000 #获取连接最大等待时间,毫秒
testOnBorrow: true #申请连接时检测连接是否有效
testOnReturn: false #归还连接时检测连接是否有效
timeBetweenEvictionRunsMillis: 60000 #配置间隔检测连接是否有效的时间(单位是毫秒)
minEvictableIdleTimeMillis: 300000 #连接在连接池的最小生存时间(毫秒)
auth:
tokenValiditySeconds: 1200 #token存储到redis的过期时间
clientId: XcWebApp
clientSecret: XcWebApp
cookieDomain: xuecheng.com
cookieMaxAge: -1
encrypt:
key-store:
location: classpath:/xc.keystore
secret: xuechengkeystore
alias: xckey
password: xuecheng
eureka:
client:
registerWithEureka: true #服务注册开关
fetchRegistry: true #服务发现开关
serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔
defaultZone: ${EUREKA_SERVER:http://localhost:50101/eureka/,http://localhost:50102/eureka/}
instance:
prefer-ip-address: true #将自己的ip地址注册到Eureka服务中
ip-address: ${IP_ADDRESS:127.0.0.1}
instance-id: ${spring.application.name}:${server.port} #指定实例id
ribbon:
MaxAutoRetries: 2 #最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试,如果eureka中找不到服务则直接走断路器
MaxAutoRetriesNextServer: 3 #切换实例的重试次数
OkToRetryOnAllOperations: false #对所有操作请求都进行重试,如果是get则可以,如果是post,put等操作没有实现幂等的情况下是很危险的,所以设置为false
ConnectTimeout: 5000 #请求连接的超时时间
ReadTimeout: 6000 #请求处理的超时时间