add
This commit is contained in:
@ -0,0 +1,96 @@
|
||||
package com.qiaoba.auth.config;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import com.qiaoba.auth.constants.SecurityConstant;
|
||||
import com.qiaoba.auth.filters.JwtAuthenticationTokenFilter;
|
||||
import com.qiaoba.auth.handler.AccessDeniedHandler;
|
||||
import com.qiaoba.auth.handler.LogoutHandler;
|
||||
import com.qiaoba.auth.properties.AuthConfigProperties;
|
||||
import com.qiaoba.auth.utils.TokenUtil;
|
||||
import com.qiaoba.common.redis.service.RedisService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* SpringSecurity安全配置
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/15 11:23
|
||||
*/
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
@Slf4j
|
||||
public class SpringSecurityConfig {
|
||||
|
||||
private final AuthConfigProperties authConfigProperties;
|
||||
private final AccessDeniedHandler accessDeniedHandler;
|
||||
private final LogoutHandler logoutHandler;
|
||||
private final JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
|
||||
private final RedisService redisService;
|
||||
|
||||
/**
|
||||
* 创建Token秘钥
|
||||
*/
|
||||
@PostConstruct
|
||||
public void initSecret() {
|
||||
if (redisService.hasKey(SecurityConstant.REDIS_SECRET_KEY)) {
|
||||
TokenUtil.secret = SecureUtil.md5(SecureUtil.md5(redisService.get(SecurityConstant.REDIS_SECRET_KEY).toString()));
|
||||
} else {
|
||||
String random = RandomUtil.randomString(8);
|
||||
TokenUtil.secret = SecureUtil.md5(SecureUtil.md5(random));
|
||||
redisService.set(SecurityConstant.REDIS_SECRET_KEY, random);
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
|
||||
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
|
||||
//白名单
|
||||
for (String url : authConfigProperties.getWhitelist()) {
|
||||
registry.antMatchers(url).permitAll();
|
||||
}
|
||||
|
||||
// 由于使用的是JWT,我们这里不需要csrf
|
||||
httpSecurity.csrf()
|
||||
.disable()
|
||||
//添加自定义未授权和未登录结果返回
|
||||
.exceptionHandling()
|
||||
.authenticationEntryPoint(accessDeniedHandler)
|
||||
.and()
|
||||
// 基于token,所以不需要session
|
||||
.sessionManagement()
|
||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
//跨域请求会先进行一次options请求
|
||||
.antMatchers(HttpMethod.OPTIONS)
|
||||
.permitAll()
|
||||
// 除上面外的所有请求全部需要鉴权认证
|
||||
.anyRequest()
|
||||
.authenticated();
|
||||
// 禁用缓存
|
||||
httpSecurity.headers().cacheControl();
|
||||
// 退出处理
|
||||
httpSecurity.logout().logoutUrl(SecurityConstant.LOGOUT_URL).logoutSuccessHandler(logoutHandler);
|
||||
// 添加JWT filter
|
||||
httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
return httpSecurity.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.qiaoba.auth.constants;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 安全常量
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2022/9/8 0008 下午 14:54
|
||||
*/
|
||||
public class SecurityConstant {
|
||||
|
||||
public static final int MAX_ERROR_COUNT = 5;
|
||||
public static final String LOGOUT_URL = "/logout";
|
||||
public static final String HAS_BEEN_PULLED_BLACK = "您的IP已经被系统拉黑";
|
||||
public static final String ACCESS_DENIED = "暂无权限访问, 请重新登录";
|
||||
public static final String BLACKLIST_KEY = "login:blacklist";
|
||||
public static final String LOGIN_ERROR_COUNT = "login:errorCount:";
|
||||
public static final String BLACKLIST_ON = "true";
|
||||
public static final String BLACKLIST_ON_OFF_KEY = "sys_config:sys.account.blacklistOnOff";
|
||||
public static final String CAPTCHA_KEY = "login:captcha:";
|
||||
public static final String CAPTCHA_ON_OFF_KEY = "sys_config:sys.account.captchaOnOff";
|
||||
public static final String CAPTCHA_ON = "true";
|
||||
public static final String REGISTER_ON_OFF_KEY = "sys_config:sys.account.registerUser";
|
||||
public static final String REGISTER_ON = "true";
|
||||
public static final String REDIS_SECRET_KEY = "sys:secret:secret";
|
||||
/**
|
||||
* 登录成功
|
||||
*/
|
||||
public static final String LOGIN_SUCCESS = "登录成功";
|
||||
/**
|
||||
* 登录失败
|
||||
*/
|
||||
public static final String LOGIN_FAIL = "登录失败";
|
||||
/**
|
||||
* 密码错误
|
||||
*/
|
||||
public static final String PASSWORD_ERROR = "密码错误";
|
||||
|
||||
/**
|
||||
* token header
|
||||
*/
|
||||
public static final String TOKEN_HEADER = "Authorization";
|
||||
|
||||
/**
|
||||
* token前缀
|
||||
*/
|
||||
public static final String TOKEN_HEAD = "Bearer ";
|
||||
|
||||
|
||||
/**
|
||||
* Xss过滤白名单
|
||||
*/
|
||||
public final static List<String> XSS_WHITELIST = Arrays.asList(
|
||||
"/captchaImage" ,
|
||||
"/login",
|
||||
"/workflow/process/start",
|
||||
"/workflow/model/save"
|
||||
);
|
||||
|
||||
/**
|
||||
* 需要限流的接口
|
||||
*/
|
||||
public final static List<String> LIMIT_URI = Arrays.asList(
|
||||
"/captchaImage" ,
|
||||
"/login" ,
|
||||
"/register"
|
||||
);
|
||||
|
||||
/**
|
||||
* 限流的RedisKey
|
||||
*/
|
||||
public final static String RATE_LIMIT_KEY = "rateLimit:";
|
||||
|
||||
/**
|
||||
* 同IP每秒最大允许访问次数
|
||||
*/
|
||||
public final static Integer MAX_RATE_LIMIT_TOTAL = 5;
|
||||
}
|
172
qiaoba-auth/src/main/java/com/qiaoba/auth/entity/LoginUser.java
Normal file
172
qiaoba-auth/src/main/java/com/qiaoba/auth/entity/LoginUser.java
Normal file
@ -0,0 +1,172 @@
|
||||
package com.qiaoba.auth.entity;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 登录用户身份权限
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2021/10/15 0015 上午 10:05
|
||||
*/
|
||||
public class LoginUser implements UserDetails {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
private String deptId;
|
||||
|
||||
/**
|
||||
* 登录账号
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 用户名称
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
|
||||
/**
|
||||
* 角色列表
|
||||
*/
|
||||
private List<String> roleIds;
|
||||
|
||||
|
||||
/**
|
||||
* 权限列表
|
||||
*/
|
||||
private Set<String> permissions;
|
||||
|
||||
|
||||
public LoginUser() {
|
||||
}
|
||||
|
||||
public LoginUser(String userId, String deptId, String username, String nickname, List<String> roleIds, Set<String> permissions) {
|
||||
this.userId = userId;
|
||||
this.deptId = deptId;
|
||||
this.username = username;
|
||||
this.permissions = permissions;
|
||||
this.nickname = nickname;
|
||||
this.roleIds = roleIds;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getDeptId() {
|
||||
return deptId;
|
||||
}
|
||||
|
||||
public void setDeptId(String deptId) {
|
||||
this.deptId = deptId;
|
||||
}
|
||||
|
||||
|
||||
public List<String> getRoleIds() {
|
||||
return roleIds;
|
||||
}
|
||||
|
||||
public void setRoleIds(List<String> roleIds) {
|
||||
this.roleIds = roleIds;
|
||||
}
|
||||
|
||||
public Set<String> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(Set<String> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 账户是否未过期,过期无法验证
|
||||
*/
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定用户是否解锁,锁定的用户无法进行身份验证
|
||||
*/
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否可用 ,禁用的用户不能身份验证
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
//返回当前用户的权限
|
||||
return permissions.stream()
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.map(SimpleGrantedAuthority::new)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package com.qiaoba.auth.filters;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.qiaoba.auth.constants.SecurityConstant;
|
||||
import com.qiaoba.auth.properties.AuthConfigProperties;
|
||||
import com.qiaoba.auth.utils.TokenUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* JwtAuthenticationTokenFilter
|
||||
* 为了保证 SecurityContext 上下文中 userInfo 是最新的
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2021/10/21 0021 下午 14:13
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
||||
|
||||
private final UserDetailsService userDetailsService;
|
||||
private final AuthConfigProperties authConfigProperties;
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
FilterChain chain) throws ServletException, IOException {
|
||||
// 鉴权白名单, 放行
|
||||
if (authConfigProperties.getWhitelist().contains(request.getRequestURI())) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
// 取Header中的Token
|
||||
String authHeader = request.getHeader(SecurityConstant.TOKEN_HEADER);
|
||||
if (StrUtil.isNotBlank(authHeader) && authHeader.startsWith(SecurityConstant.TOKEN_HEAD)) {
|
||||
String authToken = authHeader.substring(SecurityConstant.TOKEN_HEAD.length());
|
||||
if (TokenUtil.validateToken(authToken)) {
|
||||
String username = TokenUtil.getUserNameFromToken(authToken);
|
||||
if (StrUtil.isNotBlank(username) && Objects.isNull(SecurityContextHolder.getContext().getAuthentication())) {
|
||||
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
|
||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.qiaoba.auth.handler;
|
||||
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.qiaoba.auth.constants.SecurityConstant;
|
||||
import com.qiaoba.common.base.result.AjaxResult;
|
||||
import com.qiaoba.common.web.utils.ResponseUtil;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 无权限处理器
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/15 14:14
|
||||
*/
|
||||
@Component
|
||||
public class AccessDeniedHandler implements AuthenticationEntryPoint {
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
|
||||
AjaxResult result = AjaxResult.error(HttpStatus.HTTP_UNAUTHORIZED, SecurityConstant.ACCESS_DENIED);
|
||||
ResponseUtil.response(response, JSONUtil.toJsonStr(result));
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.qiaoba.auth.handler;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 退出处理器
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2022/1/4 0004 下午 16:20
|
||||
*/
|
||||
@Component
|
||||
public class LogoutHandler implements LogoutSuccessHandler {
|
||||
|
||||
@Override
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse httpServletResponse, Authentication authentication) {
|
||||
//删除SecurityContext上下文中的信息
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.qiaoba.auth.properties;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 鉴权配置(白名单/XSS)
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/15 11:09
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "qiaoba.auth")
|
||||
@Data
|
||||
@EnableConfigurationProperties
|
||||
public class AuthConfigProperties {
|
||||
|
||||
private List<String> whitelist;
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package com.qiaoba.auth.utils;
|
||||
|
||||
import com.qiaoba.auth.entity.LoginUser;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
|
||||
/**
|
||||
* SecurityUtil
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2022/8/16 0016 下午 14:51
|
||||
*/
|
||||
public class SecurityUtil {
|
||||
|
||||
private static final BCryptPasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder();
|
||||
|
||||
/**
|
||||
* 获取登录用户的账号
|
||||
*
|
||||
* @return username
|
||||
*/
|
||||
public static String getLoginUsername() {
|
||||
return getLoginUser().getUsername();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户的账号
|
||||
*
|
||||
* @return nickname
|
||||
*/
|
||||
public static String getLoginNickname() {
|
||||
return getLoginUser().getNickname();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户的ID
|
||||
*
|
||||
* @return userId
|
||||
*/
|
||||
public static String getLoginUserId() {
|
||||
return getLoginUser().getUserId();
|
||||
}
|
||||
|
||||
|
||||
public static LoginUser getLoginUser() {
|
||||
SecurityContext ctx = SecurityContextHolder.getContext();
|
||||
Authentication auth = ctx.getAuthentication();
|
||||
return (LoginUser) auth.getPrincipal();
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密密码
|
||||
*
|
||||
* @param password 原密码
|
||||
* @return 加密后密码
|
||||
*/
|
||||
public static String encryptPassword(String password) {
|
||||
return PASSWORD_ENCODER.encode(password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断密码是否相同
|
||||
*
|
||||
* @param rawPassword 真实密码
|
||||
* @param encodedPassword 加密后字符
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean matchesPassword(String rawPassword, String encodedPassword) {
|
||||
return PASSWORD_ENCODER.matches(rawPassword, encodedPassword);
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.qiaoba.auth.utils;
|
||||
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.jwt.JWTPayload;
|
||||
import cn.hutool.jwt.JWTUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* TokenUtil
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2022/6/8 0008 上午 11:44
|
||||
*/
|
||||
public class TokenUtil {
|
||||
|
||||
|
||||
/**
|
||||
* jwt 加解密密钥,第一次项目启动时创建随机数
|
||||
*/
|
||||
public static String secret;
|
||||
|
||||
|
||||
public static String generateToken(String username) {
|
||||
DateTime now = DateTime.now();
|
||||
// 3天过期
|
||||
DateTime newTime = now.offsetNew(DateField.HOUR, 72);
|
||||
|
||||
Map<String, Object> payload = new HashMap<String, Object>(4);
|
||||
//签发时间
|
||||
payload.put(JWTPayload.ISSUED_AT, now);
|
||||
//过期时间
|
||||
payload.put(JWTPayload.EXPIRES_AT, newTime);
|
||||
//生效时间
|
||||
payload.put(JWTPayload.NOT_BEFORE, now);
|
||||
//载荷
|
||||
payload.put(JWTPayload.SUBJECT, username);
|
||||
|
||||
return JWTUtil.createToken(payload, secret.getBytes());
|
||||
}
|
||||
|
||||
public static String getUserNameFromToken(String token) {
|
||||
try {
|
||||
return JWTUtil.parseToken(token).getPayload(JWTPayload.SUBJECT).toString();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证Token是否有效
|
||||
*
|
||||
* @param token token
|
||||
* @return 是/否
|
||||
*/
|
||||
public static boolean validateToken(String token) {
|
||||
try {
|
||||
if (!JWTUtil.verify(token, secret.getBytes())) {
|
||||
return false;
|
||||
}
|
||||
long expireTime = Long.parseLong(JWTUtil.parseToken(token).getPayload(JWTPayload.EXPIRES_AT).toString() + "000");
|
||||
return new DateTime(expireTime).after(DateTime.now());
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user