package com.kidgrow.oauth2.service.impl; import com.kidgrow.common.constant.SecurityConstants; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.oauth2.common.exceptions.InvalidClientException; import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.NoSuchClientException; import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService; import org.springframework.util.CollectionUtils; import javax.sql.DataSource; import java.util.List; /** * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020
* * @Description:
* 类说明 * 将oauth_client_details表数据缓存到redis,这里做个缓存优化 * layui模块中有对oauth_client_details的crud, 注意同步redis的数据 * 注意对oauth_client_details清楚redis db部分数据的清空 * @Project:
* @CreateDate: Created in 2020/2/20 09:19
* @Author: liuke */ @Slf4j public class RedisClientDetailsService extends JdbcClientDetailsService { private RedisTemplate redisTemplate; public RedisClientDetailsService(DataSource dataSource) { super(dataSource); } public RedisTemplate getRedisTemplate() { return redisTemplate; } public void setRedisTemplate(RedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } @Override public ClientDetails loadClientByClientId(String clientId) { // 先从redis获取 ClientDetails clientDetails = (ClientDetails) redisTemplate.opsForValue().get(clientRedisKey(clientId)); if (clientDetails == null) { clientDetails = cacheAndGetClient(clientId); } return clientDetails; } /** * 缓存client并返回client * @param clientId * @return */ private ClientDetails cacheAndGetClient(String clientId) { // 从数据库读取 ClientDetails clientDetails = null; try { clientDetails = super.loadClientByClientId(clientId); if (clientDetails != null) { // 写入redis缓存 redisTemplate.opsForValue().set(clientRedisKey(clientId), clientDetails); log.info("缓存clientId:{},{}", clientId, clientDetails); } } catch (NoSuchClientException e) { log.error("clientId:{},{}", clientId, clientId); } catch (InvalidClientException e) { log.error("cacheAndGetClient-invalidClient:{}", clientId, e); } return clientDetails; } @Override public void updateClientDetails(ClientDetails clientDetails) { super.updateClientDetails(clientDetails); cacheAndGetClient(clientDetails.getClientId()); } @Override public void updateClientSecret(String clientId, String secret) { super.updateClientSecret(clientId, secret); cacheAndGetClient(clientId); } @Override public void removeClientDetails(String clientId) { super.removeClientDetails(clientId); removeRedisCache(clientId); } /** * 删除redis缓存 * * @param clientId */ private void removeRedisCache(String clientId) { redisTemplate.opsForValue().get(clientRedisKey(clientId)); } /** * 将oauth_client_details全表刷入redis */ public void loadAllClientToCache() { List list = super.listClientDetails(); if (CollectionUtils.isEmpty(list)) { log.error("oauth_client_details表数据为空,请检查"); return; } list.parallelStream().forEach(client -> redisTemplate.opsForValue().set(clientRedisKey(client.getClientId()), client)); } private String clientRedisKey(String clientId) { return SecurityConstants.CACHE_CLIENT_KEY + ":" + clientId; } }