From 391782996849c3c8182b4a783fd3480006951242 Mon Sep 17 00:00:00 2001 From: fanxb Date: Tue, 12 Mar 2019 19:17:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0sso=E5=8D=95=E7=82=B9?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E4=BE=8B=E5=AD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.SSO单点登录/sso/bin/.gitignore | 26 +++ 1.SSO单点登录/sso/bin/pom.xml | 69 +++++++ .../sso/bin/src/main/resources/application.yml | 28 +++ .../sso/bin/src/main/resources/static/index.html | 63 ++++++ .../sso/bin/src/main/resources/static/login.html | 42 ++++ .../sso/bin/src/main/resources/static/main.js | 24 +++ 1.SSO单点登录/sso/pom.xml | 18 +- .../java/com/infinova/sso/SsoApplication.java | 2 - .../java/com/infinova/sso/config/RedisConfig.java | 67 +++++++ .../java/com/infinova/sso/entity/JwtInfo.java | 34 ++++ .../main/java/com/infinova/sso/entity/User.java | 93 +++------ .../java/com/infinova/sso/mapper/UserMapper.java | 25 --- .../java/com/infinova/sso/service/JwtService.java | 180 ++++++++++++++++++ .../com/infinova/sso/service/RedisService.java | 66 +++++++ .../java/com/infinova/sso/util/ArrayUtil.java | 26 --- .../main/java/com/infinova/sso/util/JwtUtil.java | 9 +- .../java/com/infinova/sso/util/PasswordUtil.java | 80 -------- .../java/com/infinova/sso/util/RedisUtil.java | 58 ++++++ .../sso/src/main/resources/application.yml | 28 ++- .../sso/src/main/resources/static/index.html | 1 - .../infinova/sso/service_test/JwtServiceTest.java | 9 - .../sso/service_test/RedisServiceTest.java | 60 ++++++ 22 files changed, 768 insertions(+), 240 deletions(-) create mode 100644 1.SSO单点登录/sso/bin/.gitignore create mode 100644 1.SSO单点登录/sso/bin/pom.xml create mode 100644 1.SSO单点登录/sso/bin/src/main/resources/application.yml create mode 100644 1.SSO单点登录/sso/bin/src/main/resources/static/index.html create mode 100644 1.SSO单点登录/sso/bin/src/main/resources/static/login.html create mode 100644 1.SSO单点登录/sso/bin/src/main/resources/static/main.js create mode 100644 1.SSO单点登录/sso/src/main/java/com/infinova/sso/config/RedisConfig.java create mode 100644 1.SSO单点登录/sso/src/main/java/com/infinova/sso/entity/JwtInfo.java delete mode 100644 1.SSO单点登录/sso/src/main/java/com/infinova/sso/mapper/UserMapper.java create mode 100644 1.SSO单点登录/sso/src/main/java/com/infinova/sso/service/JwtService.java create mode 100644 1.SSO单点登录/sso/src/main/java/com/infinova/sso/service/RedisService.java delete mode 100644 1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/ArrayUtil.java delete mode 100644 1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/PasswordUtil.java create mode 100644 1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/RedisUtil.java create mode 100644 1.SSO单点登录/sso/src/test/java/com/infinova/sso/service_test/RedisServiceTest.java diff --git a/1.SSO单点登录/sso/bin/.gitignore b/1.SSO单点登录/sso/bin/.gitignore new file mode 100644 index 0000000..ba5cb5c --- /dev/null +++ b/1.SSO单点登录/sso/bin/.gitignore @@ -0,0 +1,26 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ diff --git a/1.SSO单点登录/sso/bin/pom.xml b/1.SSO单点登录/sso/bin/pom.xml new file mode 100644 index 0000000..02ca007 --- /dev/null +++ b/1.SSO单点登录/sso/bin/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.1.3.RELEASE + + + com.example + sso + 0.0.1-SNAPSHOT + jar + sso + Demo project for Spring Boot + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + com.alibaba + fastjson + 1.2.4 + + + com.auth0 + java-jwt + 3.7.0 + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + CAS + + + org.springframework.boot + spring-boot-maven-plugin + + + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + diff --git a/1.SSO单点登录/sso/bin/src/main/resources/application.yml b/1.SSO单点登录/sso/bin/src/main/resources/application.yml new file mode 100644 index 0000000..7e9dce4 --- /dev/null +++ b/1.SSO单点登录/sso/bin/src/main/resources/application.yml @@ -0,0 +1,28 @@ +server: + port: 8081 + servlet: + context-path: /sso +spring: + application: + name: SSO + cache: + type: redis + redis: + database: 0 + host: 192.168.226.5 + port: 6379 + password: + # 连接超时时间(ms) + timeout: 1000ms + # 高版本springboot中使用jedis或者lettuce + jedis: + pool: + # 连接池最大连接数(负值表示无限制) + max-active: 8 + # 连接池最大阻塞等待时间(负值无限制) + max-wait: 5000ms + # 最大空闲链接数 + max-idle: 8 + # 最小空闲链接数 + min-idle: 0 + diff --git a/1.SSO单点登录/sso/bin/src/main/resources/static/index.html b/1.SSO单点登录/sso/bin/src/main/resources/static/index.html new file mode 100644 index 0000000..8d40c7e --- /dev/null +++ b/1.SSO单点登录/sso/bin/src/main/resources/static/index.html @@ -0,0 +1,63 @@ + + + + + 认证中心 + +
这里是认证中心主页
+
+ +
+ + + + + + \ No newline at end of file diff --git a/1.SSO单点登录/sso/bin/src/main/resources/static/login.html b/1.SSO单点登录/sso/bin/src/main/resources/static/login.html new file mode 100644 index 0000000..e0e5da1 --- /dev/null +++ b/1.SSO单点登录/sso/bin/src/main/resources/static/login.html @@ -0,0 +1,42 @@ + + + + + 认证中心登录页面 + + +
+
+
+ +
+ + + + + + + \ No newline at end of file diff --git a/1.SSO单点登录/sso/bin/src/main/resources/static/main.js b/1.SSO单点登录/sso/bin/src/main/resources/static/main.js new file mode 100644 index 0000000..07c0a87 --- /dev/null +++ b/1.SSO单点登录/sso/bin/src/main/resources/static/main.js @@ -0,0 +1,24 @@ +function getToken() { + return window.localStorage.token || null; +} + +function setToken(token) { + window.localStorage.token = token; +} + +function getUserName() { + var token = getToken(); + if (token == null) { + return "未登录"; + } else { + var info = token.split(".")[1]; + return JSON.parse(window.atob(info)).name; + } +} + +function getUrlParam(name) { + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 + var r = window.location.search.substr(1).match(reg); //匹配目标参数 + if (r != null) return unescape(r[2]); + return null; //返回参数值 +} \ No newline at end of file diff --git a/1.SSO单点登录/sso/pom.xml b/1.SSO单点登录/sso/pom.xml index 7b885cb..02ca007 100644 --- a/1.SSO单点登录/sso/pom.xml +++ b/1.SSO单点登录/sso/pom.xml @@ -24,24 +24,10 @@ org.springframework.boot spring-boot-starter-web - - - org.mybatis.spring.boot - mybatis-spring-boot-starter - 1.3.2 - - - - - com.alibaba - druid-spring-boot-starter - 1.1.9 - - mysql - mysql-connector-java - 6.0.6 + org.springframework.boot + spring-boot-starter-data-redis diff --git a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/SsoApplication.java b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/SsoApplication.java index fb9e789..4b2cd6d 100644 --- a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/SsoApplication.java +++ b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/SsoApplication.java @@ -1,13 +1,11 @@ package com.infinova.sso; -import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController -@MapperScan("com.infinova.sso.mapper") public class SsoApplication { public static void main(String[] args) { diff --git a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/config/RedisConfig.java b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/config/RedisConfig.java new file mode 100644 index 0000000..ed26de3 --- /dev/null +++ b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/config/RedisConfig.java @@ -0,0 +1,67 @@ +package com.infinova.sso.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import java.time.Duration; + +/** + * 类功能简述: + * 类功能详述: + * + * @author fanxb + * @date 2019/3/8 13:10 + */ +@EnableCaching//开启缓存 +@Configuration +public class RedisConfig extends CachingConfigurerSupport { + + /** + * 设置缓存管理器,这里可以配置默认过期时间等 + * + * @param connectionFactory 连接池 + * @return + */ + @Bean + public CacheManager cacheManager(RedisConnectionFactory connectionFactory) { + RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration + .defaultCacheConfig() + .entryTtl(Duration.ofSeconds(60)); + RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory); + RedisCacheManager manager = new RedisCacheManager(redisCacheWriter, redisCacheConfiguration); + return manager; + } + + @SuppressWarnings("all") + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + StringRedisTemplate template = new StringRedisTemplate(factory); + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper om = new ObjectMapper(); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + RedisSerializer stringSerializer = new StringRedisSerializer(); + template.setKeySerializer(stringSerializer); + template.setValueSerializer(jackson2JsonRedisSerializer); + template.setHashKeySerializer(stringSerializer); + template.setHashValueSerializer(jackson2JsonRedisSerializer); + template.afterPropertiesSet(); + return template; + } +} diff --git a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/entity/JwtInfo.java b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/entity/JwtInfo.java new file mode 100644 index 0000000..1394468 --- /dev/null +++ b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/entity/JwtInfo.java @@ -0,0 +1,34 @@ +package com.infinova.sso.entity; + +/** + * 类功能简述: + * 类功能详述: + * + * @author fanxb + * @date 2019/3/7 16:46 + */ +public class JwtInfo { + private String secret; + private long lastRefreshTime; + + public JwtInfo(String secret, long lastRefreshTime) { + this.secret = secret; + this.lastRefreshTime = lastRefreshTime; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + public long getLastRefreshTime() { + return lastRefreshTime; + } + + public void setLastRefreshTime(long lastRefreshTime) { + this.lastRefreshTime = lastRefreshTime; + } +} diff --git a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/entity/User.java b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/entity/User.java index 152c7ef..a37ac2c 100644 --- a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/entity/User.java +++ b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/entity/User.java @@ -1,85 +1,40 @@ package com.infinova.sso.entity; -import java.util.Date; +import java.io.Serializable; /** - * 类功能简述: - * 类功能详述: + * 类功能简述: 类功能详述: * * @author fanxb * @date 2019/2/28 18:34 */ -public class User { - private String recId; - private String userType; - private String loginId; - private String password; - private String question; - private String answer; - private Date passwordChangedDateTime; - private Date lastModDateTime; +public class User implements Serializable { + private String name; + private String password; - public String getRecId() { - return recId; - } + public User() { - public void setRecId(String recId) { - this.recId = recId; - } + } - public String getUserType() { - return userType; - } + public User(String name, String password) { + super(); + this.name = name; + this.password = password; + } - public void setUserType(String userType) { - this.userType = userType; - } + public String getName() { + return name; + } - public String getLoginId() { - return loginId; - } + public void setName(String name) { + this.name = name; + } - public void setLoginId(String loginId) { - this.loginId = loginId; - } + public String getPassword() { + return password; + } - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getQuestion() { - return question; - } - - public void setQuestion(String question) { - this.question = question; - } - - public String getAnswer() { - return answer; - } - - public void setAnswer(String answer) { - this.answer = answer; - } - - public Date getPasswordChangedDateTime() { - return passwordChangedDateTime; - } - - public void setPasswordChangedDateTime(Date passwordChangedDateTime) { - this.passwordChangedDateTime = passwordChangedDateTime; - } - - public Date getLastModDateTime() { - return lastModDateTime; - } - - public void setLastModDateTime(Date lastModDateTime) { - this.lastModDateTime = lastModDateTime; - } + public void setPassword(String password) { + this.password = password; + } } diff --git a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/mapper/UserMapper.java b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/mapper/UserMapper.java deleted file mode 100644 index 1a8819f..0000000 --- a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/mapper/UserMapper.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.infinova.sso.mapper; - -import com.infinova.sso.entity.User; -import org.apache.ibatis.annotations.Select; - -/** - * 类功能简述: - * 类功能详述: - * - * @author fanxb - * @date 2019/3/5 9:34 - */ -public interface UserMapper { - - /** - * Description:通过loginID获取用户信息 - * - * @author fanxb - * @date 2019/3/5 9:55 - * @param id - * @return com.infinova.sso.entity.User - */ - @Select("select RecID recId,LoginID loginId,Pwd password from siteviewusers where LoginID=#{id}") - User selectByLoginId(String id); -} diff --git a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/service/JwtService.java b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/service/JwtService.java new file mode 100644 index 0000000..e14c126 --- /dev/null +++ b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/service/JwtService.java @@ -0,0 +1,180 @@ +package com.infinova.sso.service; + +import com.alibaba.fastjson.JSONArray; +import com.auth0.jwt.JWT; +import com.infinova.sso.entity.JwtInfo; +import com.infinova.sso.entity.User; +import com.infinova.sso.exception.CustomException; +import com.infinova.sso.util.HttpUtil; +import com.infinova.sso.util.JwtUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import javax.servlet.http.Cookie; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 类功能简述: + * 类功能详述: + * + * @author fanxb + * @date 2019/3/4 18:17 + */ +@Service +@EnableScheduling +public class JwtService { + + public static final String JWT_KEY = "jwt_token"; + + private Logger logger = LoggerFactory.getLogger(JwtService.class); + + /** + * 存储jwt与secret对应关系 + */ + private static Map jwtMap = new ConcurrentHashMap<>(); + + /** + * jwt token超时时间,单位s + */ + private static final int TIME_OUT = 60 * 60; + /** + * 在此时间段内,一个jwt不能重复刷新 + */ + private static final int REFRESH_INTERVAL = 5 * 60 * 1000; + + /** + * Description:登录获取token + * + * @param user user + * @return java.lang.String + * @author fanxb + * @date 2019/3/4 18:45 + */ + public String login(User user) { + //进行登录校验 + try { + if (user.getName().equalsIgnoreCase(user.getPassword())) { + String token = this.generateNewJwt(user.getName()); + setCookie(token, TIME_OUT); + return token; + } else { + logger.info("账号密码错误:{}{}", user.getName(), user.getPassword()); + throw new CustomException("账号密码错误"); + } + } catch (Exception e) { + logger.info("账号密码错误:{},{}", user.getName(), user.getPassword()); + throw new CustomException("账号密码错误"); + } + } + + /** + * Description:刷新token + * + * @return java.lang.String + * @author fanxb + * @date 2019/3/5 11:06 + */ + public String refreshJwt(String token) { + try { + JwtInfo info = jwtMap.get(token); + Long nowTime = System.currentTimeMillis(); + if (nowTime - info.getLastRefreshTime() < REFRESH_INTERVAL) { + throw new CustomException("token刷新间隔过短"); + } + info.setLastRefreshTime(nowTime); + String id = JwtUtil.decode(token, info.getSecret()).get("loginId").asString(); + String newToken = generateNewJwt(id); + setCookie(newToken, TIME_OUT); + return newToken; + } catch (Exception e) { + throw new CustomException(e, "token校验失败"); + } + } + + /** + * Description: 生成新的jwt,并放入jwtMap中 + * + * @return java.lang.String + * @author fanxb + * @date 2019/3/5 10:44 + */ + private String generateNewJwt(String name) { + String secret = UUID.randomUUID().toString().replaceAll("-", ""); + String token = JwtUtil.encode(name, secret, TIME_OUT); + jwtMap.put(token, new JwtInfo(secret, 0)); + return token; + } + + /** + * Description:检查jwt有效性,返回失效jwt + * + * @return List 失效jwt列表 + * @author fanxb + * @date 2019/3/4 18:47 + */ + public List checkJwt(JSONArray tokens) { + List res = new ArrayList<>(); + tokens.forEach(item -> { + String jwt = (String) item; + try { + String secret = jwtMap.get(jwt).getSecret(); + JwtUtil.decode(jwt, secret); + } catch (Exception e) { + e.printStackTrace(); + res.add(jwt); + } + }); + return res; + } + + /** + * Description: 使该jwt失效 + * + * @author fanxb + * @date 2019/3/4 19:58 + */ + public void inValid(String jwt) { + jwtMap.remove(jwt); + setCookie("", 0); + } + + /** + * Description:定时检查过期的jwt,并从map中删除 + * + * @author fanxb + * @date 2019/3/5 18:16 + */ + @Scheduled(fixedRate = 10 * 1000) + private void cleanJwtMap() { + Date now = new Date(); + Set keys = jwtMap.keySet(); + keys.forEach(item -> { + if (now.getTime() > JWT.decode(item).getExpiresAt().getTime()) { + jwtMap.remove(item); + logger.info("清理掉了:{}", item); + } + }); + } + + /** + * Description: 写入jwt token到cookie + * + * @param token token + * @param maxAge 失效时间 单位s + * @return void + * @author fanxb + * @date 2019/3/5 18:43 + */ + private void setCookie(String token, int maxAge) { + Cookie cookie = new Cookie(JWT_KEY, token); + cookie.setMaxAge(maxAge); + cookie.setPath("/"); + HttpUtil.getResponse().addCookie(cookie); + } + + +} diff --git a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/service/RedisService.java b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/service/RedisService.java new file mode 100644 index 0000000..23af5a9 --- /dev/null +++ b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/service/RedisService.java @@ -0,0 +1,66 @@ +package com.infinova.sso.service; + +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.cache.annotation.Caching; +import org.springframework.stereotype.Service; + +import com.infinova.sso.entity.User; + +/** + * 类功能简述:使用此类演示一些redis的缓存操作 + * 加上CacheConfig注解可为当前泪下类下所有redis缓存做配置,比如cacheNames给类下所有的key加上前缀 + * + * @author fanxb + * @date 2019/3/8 13:53 + */ +@CacheConfig(cacheNames = "redis_test") +@Service +public class RedisService { + + /** + * 缓存时间,首次查询后会缓存结果,key中的值可使用表达式计算 + * + * @return long + */ + @Cacheable(key = "'currentTime'") + public long getTime() { + return System.currentTimeMillis(); + } + + @CacheEvict(key = "'currentTime'") + public void deleteTime() { + + } + + @Cacheable(key = "'currentTime'+#id") + public Long getTime(String id) { + return null; + } + + /** + * 一般用于更新查插入操作,每次都会请求db + */ + @CachePut(key = "'currentTime'+#id") + public long updateTime(String id) { + return System.currentTimeMillis(); + } + + /** + * 清除缓存 + * + * @param id id + */ + @CacheEvict(key = "'currentTime'+#id", allEntries = false) + public void deleteTime(String id) { + } + + @Caching(put = {@CachePut(value = "user", key = "'name_'+#user.name"), + @CachePut(value = "user", key = "'pass_'+#user.password")}) + public User testCaching(User user) { + return user; + } + +} diff --git a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/ArrayUtil.java b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/ArrayUtil.java deleted file mode 100644 index 33be405..0000000 --- a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/ArrayUtil.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.infinova.sso.util; - -/** - * 类功能简述: 数组工具类 - * - * @author fanxb - * @date 2019/3/4 17:06 - */ -public class ArrayUtil { - /** - * Description: 从指定数组指定下标复制指定长度到目标数组指定下标 - * - * @author fanxb - * @date 2019/3/4 17:16 - * @param source 源数组 - * @param sourceStart 原数组copy开始下标 - * @param target 目标数组 - * @param targetStart 目标数组接收开始下标 - * @param length copy长度 - */ - public static void copyTo(byte[] source, int sourceStart, byte[] target, int targetStart, int length) { - for (int i = 0; i < length; i++) { - target[targetStart + i] = source[sourceStart + i]; - } - } -} diff --git a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/JwtUtil.java b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/JwtUtil.java index 5f03719..6b6bfaa 100644 --- a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/JwtUtil.java +++ b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/JwtUtil.java @@ -22,21 +22,20 @@ public class JwtUtil { /** * Description: 生成一个jwt字符串 * - * @param recId 用户id - * @param loginId 登录id + * @param name 用户名 * @param secret 秘钥 * @param timeOut 超时时间(单位s) * @return java.lang.String * @author fanxb * @date 2019/3/4 17:26 */ - public static String encode(String loginId, String secret, long timeOut) { + public static String encode(String name, String secret, long timeOut) { Algorithm algorithm = Algorithm.HMAC256(secret); String token = JWT.create() //设置过期时间为一个小时 .withExpiresAt(new Date(System.currentTimeMillis() + timeOut * 1000)) //设置负载 - .withClaim("loginId", loginId) + .withClaim("name", name) .sign(algorithm); return token; } @@ -46,7 +45,7 @@ public class JwtUtil { * * @param token token * @param secret secret - * @return java.util.Map + * @return java.util.Map * @author fanxb * @date 2019/3/4 18:14 */ diff --git a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/PasswordUtil.java b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/PasswordUtil.java deleted file mode 100644 index 0fb1f6b..0000000 --- a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/PasswordUtil.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.infinova.sso.util; - -import javax.xml.bind.DatatypeConverter; -import java.security.MessageDigest; -import java.security.SecureRandom; - -/** - * 类功能简述: - * 类功能详述: - * - * @author fanxb - * @date 2019/3/4 17:20 - */ -public class PasswordUtil { - /** - * Description: plainText加salt使用sha1计算hash - * - * @param plainText 原文 - * @param salt 盐 - * @return byte[] - * @author fanxb - * @date 2019/3/4 17:20 - */ - private static byte[] computeHashValue(String plainText, byte[] salt) throws Exception { - byte[] plainBytes = plainText.getBytes("utf-16LE"); - byte[] arr = new byte[salt.length + plainBytes.length]; - MessageDigest md = MessageDigest.getInstance("SHA1"); - ArrayUtil.copyTo(plainBytes, 0, arr, 0, plainBytes.length); - ArrayUtil.copyTo(salt, 0, arr, plainBytes.length, salt.length); - return md.digest(arr); - } - - - /** - * Description: 根据原文计算出密文,计算方法:使用一个随机数做盐值和密码一起使用sha1做hash,再和盐值拼接到一起, - * 最后生成base64字符串 - * - * @param pass 原文 - * @return java.lang.String - * @author fanxb - * @date 2019/3/4 17:21 - */ - public static String createPassword(String pass) throws Exception { - byte[] salt = SecureRandom.getSeed(0x10); - byte[] buffer2 = computeHashValue(pass, salt); - byte[] array = new byte[0x24]; - ArrayUtil.copyTo(salt, 0, array, 0, salt.length); - ArrayUtil.copyTo(buffer2, 0, array, salt.length, salt.length); - return DatatypeConverter.printBase64Binary(array); - } - - /** - * Description: 判断密文原文是否一致 - * - * @param cipherPassword 密文 - * @param plainPassword 原文 - * @return boolean - * @author fanxb - * @date 2019/3/4 17:23 - */ - public static boolean checkPassword(String cipherPassword, String plainPassword) { - try { - byte[] cipherPasswordBytes = DatatypeConverter.parseBase64Binary(cipherPassword); - byte[] saltBytes = new byte[0x10]; - ArrayUtil.copyTo(cipherPasswordBytes, 0, saltBytes, 0, saltBytes.length); - byte[] passwordBytes = computeHashValue(plainPassword, saltBytes); - byte[] realPasswordBytes = new byte[20]; - ArrayUtil.copyTo(cipherPasswordBytes, saltBytes.length, realPasswordBytes, 0, realPasswordBytes.length); - for (int i = 0; i < realPasswordBytes.length; i++) { - if (passwordBytes[i] != realPasswordBytes[i]) { - return false; - } - } - return true; - } catch (Exception e) { - e.printStackTrace(); - return false; - } - } -} diff --git a/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/RedisUtil.java b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/RedisUtil.java new file mode 100644 index 0000000..4dbe147 --- /dev/null +++ b/1.SSO单点登录/sso/src/main/java/com/infinova/sso/util/RedisUtil.java @@ -0,0 +1,58 @@ +package com.infinova.sso.util; + +import com.alibaba.fastjson.JSON; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +/** + * 类功能简述: + * 类功能详述: + * + * @author fanxb + * @date 2019/3/8 13:26 + */ +@Component +public class RedisUtil { + private static final int DEFAULT_EXPIRE_TIME = 60 * 1000; + + public static RedisTemplate redisTemplate; + + @Autowired + public void setRedisTemplate(RedisTemplate redisTemplate) { + RedisUtil.redisTemplate = redisTemplate; + } + + /** + * 设置键值对,使用默认过期时间 + * + * @param key 键 + * @param value 值 + */ + public static void set(String key, Object value) { + set(key, value, DEFAULT_EXPIRE_TIME); + } + + /** + * 设置键值对,指定过期时间 + * + * @param key key + * @param value value + * @param expireTime 过期时间 + */ + public static void set(String key, Object value, long expireTime) { + redisTemplate.opsForValue().set(key, JSON.toJSONString(value)); + redisTemplate.expire(key, expireTime, TimeUnit.MILLISECONDS); + } + + /** + * 删除key + * + * @param key key + */ + public static void delete(String key) { + redisTemplate.delete(key); + } +} diff --git a/1.SSO单点登录/sso/src/main/resources/application.yml b/1.SSO单点登录/sso/src/main/resources/application.yml index 168bf40..f00ada3 100644 --- a/1.SSO单点登录/sso/src/main/resources/application.yml +++ b/1.SSO单点登录/sso/src/main/resources/application.yml @@ -5,10 +5,24 @@ server: spring: application: name: SSO - datasource: - type: com.alibaba.druid.pool.DruidDataSource - druid: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3308/itoss?useUnicode=true&characterEncoding=gbk&serverTimezone=UTC&useSSL=false - username: root - password: root + cache: + type: redis + redis: + database: 0 + host: 10.82.27.177 + port: 6379 + password: + # 连接超时时间(ms) + timeout: 1000ms + # 高版本springboot中使用jedis或者lettuce + jedis: + pool: + # 连接池最大连接数(负值表示无限制) + max-active: 8 + # 连接池最大阻塞等待时间(负值无限制) + max-wait: 5000ms + # 最大空闲链接数 + max-idle: 8 + # 最小空闲链接数 + min-idle: 0 + diff --git a/1.SSO单点登录/sso/src/main/resources/static/index.html b/1.SSO单点登录/sso/src/main/resources/static/index.html index be5c304..8d40c7e 100644 --- a/1.SSO单点登录/sso/src/main/resources/static/index.html +++ b/1.SSO单点登录/sso/src/main/resources/static/index.html @@ -4,7 +4,6 @@ 认证中心 -
这里是认证中心主页
diff --git a/1.SSO单点登录/sso/src/test/java/com/infinova/sso/service_test/JwtServiceTest.java b/1.SSO单点登录/sso/src/test/java/com/infinova/sso/service_test/JwtServiceTest.java index 9c245f4..d7f2600 100644 --- a/1.SSO单点登录/sso/src/test/java/com/infinova/sso/service_test/JwtServiceTest.java +++ b/1.SSO单点登录/sso/src/test/java/com/infinova/sso/service_test/JwtServiceTest.java @@ -1,16 +1,12 @@ package com.infinova.sso.service_test; -import com.infinova.sso.entity.User; import com.infinova.sso.service.JwtService; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import javax.xml.bind.DatatypeConverter; - /** * 类功能简述: * 类功能详述: @@ -28,11 +24,6 @@ public class JwtServiceTest { @Test public void loginTest() throws Exception { - User user = new User(); - user.setLoginId("admin"); - user.setPassword(DatatypeConverter.printBase64Binary("manage".getBytes("utf-8"))); - String token = jwtService.login(user); - Assert.assertTrue(token != null && token.length() > 0); } } diff --git a/1.SSO单点登录/sso/src/test/java/com/infinova/sso/service_test/RedisServiceTest.java b/1.SSO单点登录/sso/src/test/java/com/infinova/sso/service_test/RedisServiceTest.java new file mode 100644 index 0000000..066a878 --- /dev/null +++ b/1.SSO单点登录/sso/src/test/java/com/infinova/sso/service_test/RedisServiceTest.java @@ -0,0 +1,60 @@ +package com.infinova.sso.service_test; + +import com.infinova.sso.entity.User; +import com.infinova.sso.service.RedisService; +import com.infinova.sso.util.RedisUtil; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * 类功能简述: 类功能详述: + * + * @author fanxb + * @date 2019/3/8 14:31 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class RedisServiceTest { + + private Logger logger = LoggerFactory.getLogger(RedisService.class); + + @Autowired + private RedisService redisService; + @Autowired + private RedisUtil redisUtil; + + @Test + public void getTimeTest() throws Exception { + logger.info("时间为:{}", redisService.getTime()); + Thread.sleep(1000); + logger.info("时间为:{}", redisService.getTime()); + Thread.sleep(1000); + logger.info("时间为:{}", redisService.getTime()); + redisService.deleteTime(); + Thread.sleep(1000); + logger.info("时间为:{}", redisService.getTime()); + } + + @Test + public void getTimeIdTest() throws Exception { + logger.info("缓存时间:{}", redisService.updateTime("1")); + Thread.sleep(1000); + logger.info("1s后取数据:{}", redisService.getTime("1")); + Thread.sleep(1000); + logger.info("1s后更新时间:{}", redisService.updateTime("1")); + Thread.sleep(1000); + logger.info("1s后取数据:{}", redisService.getTime("1")); + RedisUtil.set("test1", "test1", 100000); + } + + @Test + public void testCaching() throws Exception { + User user = new User("aaa","bbb"); + redisService.testCaching(user); + } +}