wei.zhang2 2017-12-29 14:31:15 +08:00
parent e6e35afce7
commit 69d3f3c48f
2 changed files with 96 additions and 22 deletions

View File

@ -1,8 +1,17 @@
package com.boot.security.server.service.impl; package com.boot.security.server.service.impl;
import java.security.Key;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -15,6 +24,10 @@ import com.boot.security.server.model.TokenModel;
import com.boot.security.server.service.SysLogService; import com.boot.security.server.service.SysLogService;
import com.boot.security.server.service.TokenService; import com.boot.security.server.service.TokenService;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/** /**
* token * token
* *
@ -24,6 +37,7 @@ import com.boot.security.server.service.TokenService;
@Service @Service
public class TokenServiceDbImpl implements TokenService { public class TokenServiceDbImpl implements TokenService {
private static final Logger log = LoggerFactory.getLogger("adminLogger");
/** /**
* token * token
*/ */
@ -33,17 +47,23 @@ public class TokenServiceDbImpl implements TokenService {
private TokenDao tokenDao; private TokenDao tokenDao;
@Autowired @Autowired
private SysLogService logService; private SysLogService logService;
/**
*
*/
@Value("${token.jwtSecret}")
private String jwtSecret;
private static Key KEY = null;
private static final String LOGIN_USER_KEY = "LOGIN_USER_KEY";
@Override @Override
public Token saveToken(LoginUser loginUser) { public Token saveToken(LoginUser loginUser) {
String token = UUID.randomUUID().toString(); loginUser.setToken(UUID.randomUUID().toString());
loginUser.setToken(token);
loginUser.setLoginTime(System.currentTimeMillis()); loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireSeconds * 1000); loginUser.setExpireTime(loginUser.getLoginTime() + expireSeconds * 1000);
TokenModel model = new TokenModel(); TokenModel model = new TokenModel();
model.setId(token); model.setId(loginUser.getToken());
model.setCreateTime(new Date()); model.setCreateTime(new Date());
model.setUpdateTime(new Date()); model.setUpdateTime(new Date());
model.setExpireTime(new Date(loginUser.getExpireTime())); model.setExpireTime(new Date(loginUser.getExpireTime()));
@ -53,7 +73,25 @@ public class TokenServiceDbImpl implements TokenService {
// 登陆日志 // 登陆日志
logService.save(loginUser.getId(), "登陆", true, null); logService.save(loginUser.getId(), "登陆", true, null);
return new Token(token, loginUser.getLoginTime()); String jwtToken = createJWTToken(loginUser);
return new Token(jwtToken, loginUser.getLoginTime());
}
/**
* jwt
*
* @param loginUser
* @return
*/
private String createJWTToken(LoginUser loginUser) {
Map<String, Object> claims = new HashMap<>();
claims.put(LOGIN_USER_KEY, loginUser.getToken());// 放入一个随机字符串,通过该串可找到登陆用户
String jwtToken = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, getKeyInstance())
.compact();
return jwtToken;
} }
@Override @Override
@ -71,19 +109,27 @@ public class TokenServiceDbImpl implements TokenService {
@Override @Override
public LoginUser getLoginUser(String token) { public LoginUser getLoginUser(String token) {
TokenModel model = tokenDao.getById(token); String string = getUUIDFromJWT(token);
return toLoginUser(model); if (string != null) {
TokenModel model = tokenDao.getById(string);
return toLoginUser(model);
}
return null;
} }
@Override @Override
public boolean deleteToken(String token) { public boolean deleteToken(String token) {
TokenModel model = tokenDao.getById(token); String string = getUUIDFromJWT(token);
LoginUser loginUser = toLoginUser(model); if (string != null) {
if (loginUser != null) { TokenModel model = tokenDao.getById(string);
tokenDao.delete(token); LoginUser loginUser = toLoginUser(model);
logService.save(loginUser.getId(), "退出", true, null); if (loginUser != null) {
tokenDao.delete(token);
logService.save(loginUser.getId(), "退出", true, null);
return true; return true;
}
} }
return false; return false;
@ -96,4 +142,31 @@ public class TokenServiceDbImpl implements TokenService {
return JSONObject.parseObject(model.getVal(), LoginUser.class); return JSONObject.parseObject(model.getVal(), LoginUser.class);
} }
private Key getKeyInstance() {
if (KEY == null) {
synchronized (TokenServiceJWTImpl.class) {
if (KEY == null) {// 双重锁
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(jwtSecret);
KEY = new SecretKeySpec(apiKeySecretBytes, SignatureAlgorithm.HS256.getJcaName());
}
}
}
return KEY;
}
private String getUUIDFromJWT(String jwt) {
Map<String, Object> jwtClaims = null;
try {
jwtClaims = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody();
} catch (ExpiredJwtException e) {
log.error("{}已过期", jwt);
return null;
} catch (Exception e) {
throw e;
}
return MapUtils.getString(jwtClaims, LOGIN_USER_KEY);
}
} }

View File

@ -61,11 +61,12 @@ public class TokenServiceJWTImpl implements TokenService {
@Override @Override
public Token saveToken(LoginUser loginUser) { public Token saveToken(LoginUser loginUser) {
loginUser.setToken(UUID.randomUUID().toString()); loginUser.setToken(UUID.randomUUID().toString());
String jwtToken = createJWTToken(loginUser);
cacheLoginUser(loginUser); cacheLoginUser(loginUser);
// 登陆日志 // 登陆日志
logService.save(loginUser.getId(), "登陆", true, null); logService.save(loginUser.getId(), "登陆", true, null);
String jwtToken = createJWTToken(loginUser);
return new Token(jwtToken, loginUser.getLoginTime()); return new Token(jwtToken, loginUser.getLoginTime());
} }
@ -75,7 +76,7 @@ public class TokenServiceJWTImpl implements TokenService {
* @param loginUser * @param loginUser
* @return * @return
*/ */
public String createJWTToken(LoginUser loginUser) { private String createJWTToken(LoginUser loginUser) {
Map<String, Object> claims = new HashMap<>(); Map<String, Object> claims = new HashMap<>();
claims.put(LOGIN_USER_KEY, loginUser.getToken());// 放入一个随机字符串,通过该串可找到登陆用户 claims.put(LOGIN_USER_KEY, loginUser.getToken());// 放入一个随机字符串,通过该串可找到登陆用户
@ -101,8 +102,8 @@ public class TokenServiceJWTImpl implements TokenService {
} }
@Override @Override
public LoginUser getLoginUser(String token) { public LoginUser getLoginUser(String jwtToken) {
String string = getUUIDFromJWT(token); String string = getUUIDFromJWT(jwtToken);
if (string != null) { if (string != null) {
return redisTemplate.boundValueOps(getTokenKey(string)).get(); return redisTemplate.boundValueOps(getTokenKey(string)).get();
} }
@ -111,8 +112,8 @@ public class TokenServiceJWTImpl implements TokenService {
} }
@Override @Override
public boolean deleteToken(String token) { public boolean deleteToken(String jwtToken) {
String string = getUUIDFromJWT(token); String string = getUUIDFromJWT(jwtToken);
if (string != null) { if (string != null) {
String key = getTokenKey(string); String key = getTokenKey(string);
LoginUser loginUser = redisTemplate.opsForValue().get(key); LoginUser loginUser = redisTemplate.opsForValue().get(key);
@ -145,12 +146,12 @@ public class TokenServiceJWTImpl implements TokenService {
return KEY; return KEY;
} }
private String getUUIDFromJWT(String jwt) { private String getUUIDFromJWT(String jwtToken) {
Map<String, Object> jwtClaims = null; Map<String, Object> jwtClaims = null;
try { try {
jwtClaims = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody(); jwtClaims = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken).getBody();
} catch (ExpiredJwtException e) { } catch (ExpiredJwtException e) {
log.error("{}已过期", jwt); log.error("{}已过期", jwtToken);
return null; return null;
} catch (Exception e) { } catch (Exception e) {
throw e; throw e;