mirror of
https://github.com/hs-web/hsweb-framework.git
synced 2026-05-22 17:07:12 +08:00
优化jwt权限
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.hswebframework.web.authorization.basic.web;
|
||||
|
||||
/**
|
||||
* TODO 完成注释
|
||||
*
|
||||
* @author zhouhao
|
||||
*/
|
||||
public interface AuthorizedToken extends ParsedToken {
|
||||
String getUserId();
|
||||
}
|
||||
@@ -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();
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.hswebframework.web.authorization.basic.web;
|
||||
|
||||
/**
|
||||
* TODO 完成注释
|
||||
*
|
||||
* @author zhouhao
|
||||
*/
|
||||
public interface ParsedToken {
|
||||
String getToken();
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,5 +11,5 @@ import org.hswebframework.web.authorization.Authentication;
|
||||
public interface UserTokenGenerator {
|
||||
String getSupportTokenType();
|
||||
|
||||
TokenResult generate(Authentication authentication);
|
||||
GeneratedToken generate(Authentication authentication);
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@ import java.util.function.Predicate;
|
||||
*/
|
||||
public interface UserTokenParser {
|
||||
|
||||
String parseToken(HttpServletRequest request);
|
||||
ParsedToken parseToken(HttpServletRequest request);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user