zoukankan      html  css  js  c++  java
  • 单点登录

    一,单点登录概述

    (一)什么是单点登录:每个子系统从第三方认证系统中查找而不是每个系统都通过各自的session校验。

    (二)单点登录的特点是:
    1、认证系统为独立的系统。
    2、各子系统通过Http或其它协议与认证系统通信,完成用户认证。
    3、用户身份信息存储在Redis集群。

    (三)单点登录实现框架:

    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("
    "));
            } 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 #请求处理的超时时间

    当一个男人不再对你啰嗦,不再缠着你,不再没事找你,对你说话也客气了,也不再气你了。那么恭喜你,你已经成功的失去了他。别嫌弃男人幼稚,那是他喜欢你,爱你。女人说男人像小孩子一样不成熟,可又有谁知道,男人在自己喜欢的女人面前才像小孩子,如果不喜欢你了,不爱你了,他比你爸还成熟。
  • 相关阅读:
    (基于Java)编写编译器和解释器第5章:解析表达式和赋值语句第一部分(连载)
    (基于Java)编写编译器和解释器第6章:解释执行表达式和赋值语句(连载)
    (基于Java)编写编译器和解释器第9章:解析声明第一部分(连载)
    (基于Java)编写编译器和解释器第5章:解析表达式和赋值语句第二部分(连载)
    (基于Java)编写编译器和解释器第4章:符号表(连载)
    (基于Java)编写编译器和解释器第8A章:基于Antlr解析&解释执行Pascal控制语句(连载)
    (基于Java)编写编译器和解释器第7章:解析(Parsing)控制语句第一部分(连载)
    (基于Java)编写编译器和解释器第5A章:基于Antlr解析表达式和赋值语句及计算(连载)
    (基于Java)编写编译器和解释器第7章:解析(Parsing)控制语句第二部分(连载)
    (基于Java)编写编译器和解释器第8章:解释Pascal控制语句(连载)
  • 原文地址:https://www.cnblogs.com/fengtangjiang/p/11147245.html
Copyright © 2011-2022 走看看