优化jwt权限

This commit is contained in:
zhouhao
2017-08-31 15:13:42 +08:00
parent e727f1fe60
commit bc8c200680
14 changed files with 137 additions and 68 deletions

View File

@@ -67,10 +67,10 @@ public class MemoryUserTokenManager implements UserTokenManager {
private SimpleUserToken checkTimeout(SimpleUserToken detail) {
if (null == detail) return null;
if(detail.getMaxInactiveInterval()<=0){
if (detail.getMaxInactiveInterval() <= 0) {
return detail;
}
if (System.currentTimeMillis() - detail.getLastRequestTime() >detail.getMaxInactiveInterval()) {
if (System.currentTimeMillis() - detail.getLastRequestTime() > detail.getMaxInactiveInterval()) {
detail.setState(TokenState.expired);
return detail;
}
@@ -155,7 +155,7 @@ public class MemoryUserTokenManager implements UserTokenManager {
}
@Override
public UserToken signIn(String token, String userId,long maxInactiveInterval) {
public UserToken signIn(String token, String userId, long maxInactiveInterval) {
SimpleUserToken detail = new SimpleUserToken(userId, token);
if (null != authorizationListenerDispatcher)
authorizationListenerDispatcher.doEvent(new UserSignInEvent(detail));

View File

@@ -0,0 +1,10 @@
package org.hswebframework.web.authorization.basic.web;
/**
* TODO 完成注释
*
* @author zhouhao
*/
public interface AuthorizedToken extends ParsedToken {
String getUserId();
}

View File

@@ -6,7 +6,7 @@ import java.util.Map;
/**
* Created by zhouhao on 2017/8/30.
*/
public interface TokenResult extends Serializable {
public interface GeneratedToken extends Serializable {
Map<String,Object> getResponse();
String getToken();

View File

@@ -0,0 +1,10 @@
package org.hswebframework.web.authorization.basic.web;
/**
* TODO 完成注释
*
* @author zhouhao
*/
public interface ParsedToken {
String getToken();
}

View File

@@ -19,7 +19,7 @@ public class SessionIdUserTokenGenerator implements UserTokenGenerator ,Serializ
}
@Override
public TokenResult generate(Authentication authentication) {
public GeneratedToken generate(Authentication authentication) {
HttpServletRequest request= WebUtil.getHttpServletRequest();
if(null==request)throw new UnsupportedOperationException();
@@ -28,7 +28,7 @@ public class SessionIdUserTokenGenerator implements UserTokenGenerator ,Serializ
String sessionId = request.getSession().getId();
return new TokenResult() {
return new GeneratedToken() {
@Override
public Map<String, Object> getResponse() {
return Collections.emptyMap();

View File

@@ -9,12 +9,12 @@ import java.util.function.Predicate;
*/
public class SessionIdUserTokenParser implements UserTokenParser {
@Override
public String parseToken(HttpServletRequest request) {
public ParsedToken parseToken(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
return session.getId();
return session::getId;
}
return null;

View File

@@ -47,7 +47,7 @@ public class UserOnSignIn implements AuthorizationListener<AuthorizationSuccessE
userTokenManager.signOutByToken(token.getToken());
}
//创建token
TokenResult newToken = userTokenGenerators.stream()
GeneratedToken newToken = userTokenGenerators.stream()
.filter(generator->generator.getSupportTokenType().equals(tokenType))
.findFirst()
.orElseThrow(()->new UnsupportedOperationException(tokenType))
@@ -55,22 +55,8 @@ public class UserOnSignIn implements AuthorizationListener<AuthorizationSuccessE
//登入
userTokenManager.signIn(newToken.getToken(), event.getAuthentication().getUser().getId(),newToken.getTimeout());
//响应结果
event.getResult().putAll(newToken.getResponse());
}
protected String createToken(String type) {
switch (type) {
case "simple":
return DigestUtils.md5Hex(UUID.randomUUID().toString().concat(String.valueOf(Math.random())));
default:
return Optional.ofNullable(WebUtil.getHttpServletRequest())
.orElseThrow(UnsupportedOperationException::new)
.getSession()
.getId();
}
}
}

View File

@@ -11,5 +11,5 @@ import org.hswebframework.web.authorization.Authentication;
public interface UserTokenGenerator {
String getSupportTokenType();
TokenResult generate(Authentication authentication);
GeneratedToken generate(Authentication authentication);
}

View File

@@ -10,5 +10,5 @@ import java.util.function.Predicate;
*/
public interface UserTokenParser {
String parseToken(HttpServletRequest request);
ParsedToken parseToken(HttpServletRequest request);
}

View File

@@ -8,6 +8,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* TODO 完成注释
@@ -27,22 +28,27 @@ public class WebUserTokenInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = userTokenParser.stream()
.map(parser->parser.parseToken(request))
List<ParsedToken> tokens = userTokenParser.stream()
.map(parser -> parser.parseToken(request))
.filter(Objects::nonNull)
.filter(userTokenManager::tokenIsLoggedIn)
.findFirst()
.orElse(null);
.collect(Collectors.toList());
if (null == token) {
if (tokens.isEmpty()) {
return true;
}
userTokenManager.touch(token);
UserToken userToken = userTokenManager.getByToken(token);
if (userToken == null) {
return true;
} else {
UserTokenHolder.setCurrent(userToken);
for (ParsedToken parsedToken : tokens) {
UserToken userToken = null;
String token = parsedToken.getToken();
if (userTokenManager.tokenIsLoggedIn(token)) {
userToken = userTokenManager.getByToken(token);
}
// if ((userToken == null || userToken.isExpired()) && parsedToken instanceof AuthorizedToken) {
// userToken = userTokenManager.signIn(parsedToken.getToken(), ((AuthorizedToken) parsedToken).getUserId(), -1);
// }
if (null != userToken) {
userTokenManager.touch(token);
UserTokenHolder.setCurrent(userToken);
}
}
return true;
}

View File

@@ -0,0 +1,39 @@
package org.hswebframework.web.authorization.jwt;
import org.hswebframework.web.authorization.basic.web.AuthorizedToken;
/**
*
* @author zhouhao
*/
public class DefaultAuthorizedToken implements AuthorizedToken {
private String token;
private String userId;
public DefaultAuthorizedToken() {
}
public DefaultAuthorizedToken(String token, String userId) {
this.token = token;
this.userId = userId;
}
@Override
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@Override
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}

View File

@@ -10,13 +10,13 @@ import javax.crypto.spec.SecretKeySpec;
*/
public class JwtConfig {
private String id;
private String id = "hsweb-jwt";
private String secret;
private String secret = Base64.encodeBase64String("hsweb.jwt.secret".getBytes());
private int ttl=60*60*1000;
private int ttl = 60 * 60 * 1000;
private int refreshTtl=12*60*60*1000;
private int refreshTtl = 12 * 60 * 60 * 1000;
public String getSecret() {
return secret;
@@ -42,7 +42,7 @@ public class JwtConfig {
this.refreshTtl = refreshTtl;
}
public SecretKey generalKey(){
public SecretKey generalKey() {
byte[] encodedKey = Base64.decodeBase64(secret);
return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
}

View File

@@ -1,12 +1,11 @@
package org.hswebframework.web.authorization.jwt;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.codec.binary.Base64;
import org.hswebframework.web.Maps;
import org.hswebframework.web.authorization.Authentication;
import org.hswebframework.web.authorization.basic.web.TokenResult;
import org.hswebframework.web.authorization.basic.web.GeneratedToken;
import org.hswebframework.web.authorization.basic.web.UserTokenGenerator;
import org.hswebframework.web.id.IDGenerator;
@@ -31,25 +30,29 @@ public class JwtTokenGenerator implements UserTokenGenerator {
return "jwt";
}
private String createToken(){
private String createToken() {
return IDGenerator.MD5.generate();
}
@Override
public TokenResult generate(Authentication authentication) {
public GeneratedToken generate(Authentication authentication) {
String token = createToken();
String userId = authentication.getUser().getId();
String jwtToken = createJWT(jwtConfig.getId(),token,jwtConfig.getTtl());
String subject = JSON.toJSONString(new DefaultAuthorizedToken(token, userId));
String refreshToken = createJWT(jwtConfig.getId(),token,jwtConfig.getRefreshTtl());
String jwtToken = createJWT(jwtConfig.getId(), subject, jwtConfig.getTtl());
// String refreshToken = createJWT(jwtConfig.getId(), userId, jwtConfig.getRefreshTtl());
int timeout = jwtConfig.getTtl();
return new TokenResult() {
return new GeneratedToken() {
@Override
public Map<String, Object> getResponse() {
Map<String,Object> map = new HashMap<>();
map.put("token",jwtToken);
map.put("refreshToken",refreshToken);
Map<String, Object> map = new HashMap<>();
map.put("token", jwtToken);
// map.put("refreshToken", refreshToken);
return map;
}
@@ -66,10 +69,10 @@ public class JwtTokenGenerator implements UserTokenGenerator {
}
public String createJWT(String id, String subject, long ttlMillis){
public String createJWT(String id, String subject, long ttlMillis) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date();
Date now = new Date(nowMillis);
SecretKey key = jwtConfig.generalKey();
JwtBuilder builder = Jwts.builder()
.setId(id)

View File

@@ -1,8 +1,12 @@
package org.hswebframework.web.authorization.jwt;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.hswebframework.web.authorization.basic.web.ParsedToken;
import org.hswebframework.web.authorization.basic.web.UserTokenParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.crypto.SecretKey;
@@ -13,6 +17,8 @@ import javax.servlet.http.HttpServletRequest;
*/
public class JwtTokenParser implements UserTokenParser {
private static final Logger logger = LoggerFactory.getLogger(JwtTokenParser.class);
private JwtConfig jwtConfig;
public JwtTokenParser(JwtConfig jwtConfig) {
@@ -20,31 +26,40 @@ public class JwtTokenParser implements UserTokenParser {
}
@Override
public String parseToken(HttpServletRequest request) {
public ParsedToken parseToken(HttpServletRequest request) {
String headerToken = request.getHeader("jwt-token");
if(StringUtils.isEmpty(headerToken)){
headerToken=request.getHeader("Authorization");
if(!StringUtils.isEmpty(headerToken)){
if(headerToken.contains(" ")){
String[] auth =headerToken.split("[ ]");
// if(auth[0].equalsIgnoreCase("jwt")){
headerToken=auth[1];
if (StringUtils.isEmpty(headerToken)) {
headerToken = request.getHeader("Authorization");
if (!StringUtils.isEmpty(headerToken)) {
if (headerToken.contains(" ")) {
String[] auth = headerToken.split("[ ]");
// if(auth[0].equalsIgnoreCase("jwt")){
headerToken = auth[1];
//}
}
}
}
if(headerToken!=null){
return parseJWT(headerToken).getSubject();
if (headerToken != null) {
try {
Claims claims = parseJWT(headerToken);
if (claims.getExpiration().getTime() <= System.currentTimeMillis()) {
return null;
}
return JSON.parseObject(claims.getSubject(), DefaultAuthorizedToken.class);
} catch (Exception e) {
logger.error("parse token [{}] error", headerToken, e);
return null;
}
}
return null;
}
public Claims parseJWT(String jwt){
public Claims parseJWT(String jwt) {
SecretKey key = jwtConfig.generalKey();
Claims claims = Jwts.parser()
return Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(jwt).getBody();
return claims;
}