Spring Security配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.7.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.9</version>
</dependency>
server:
port: 8088
tomcat:
uri-encoding: UTF-8
connection-timeout: 5000ms
threads:
max: 1000
min-spare: 30
servlet:
context-path: /gremlin
encoding:
charset: UTF-8
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/forum?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: root
redis:
database: 0
host: 127.0.0.1
port: 6379
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
- security配置 (编写SecurityConfig配置文件)
package com.gremlin.config;
import com.gremlin.common.utils.RedisUtils;
import com.gremlin.log.service.LogService;
import com.gremlin.power.mapper.PowerManagerMapper;
import com.gremlin.power.service.PowerManagerService;
import com.gremlin.security.fifter.JwtAuthenticationTokenFilter;
import com.gremlin.security.fifter.TokenLoginFilter;
import com.gremlin.security.handler.AjaxAccessDeniedHandler;
import com.gremlin.security.handler.AjaxAuthenticationEntryPoint;
import com.gremlin.security.handler.AjaxLogoutSuccessHandler;
import com.gremlin.security.service.MyUserDetailsServiceImpl;
import com.gremlin.security.strategy.CustomizeSessionInformationExpiredStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AjaxLogoutSuccessHandler logoutSuccessHandler;
@Autowired
private AjaxAccessDeniedHandler ajaxAccessDeniedHandler;
@Autowired
private AjaxAuthenticationEntryPoint authenticationEntryPoint;
@Autowired
private CustomizeSessionInformationExpiredStrategy sessionInformationExpiredStrategy;
@Autowired
private JwtAuthenticationTokenFilter tokenAuthenticationFilter;
@Autowired
private RedisUtils redisUtils;
@Autowired
private LogService logService;
@Autowired
private PowerManagerMapper powerManagerMapper;
@Autowired
private MyUserDetailsServiceImpl userDetailsService;
@Autowired
private PowerManagerService powerManagerService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
http.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.authorizeRequests()
.antMatchers(
"/swagger**/**",
"/swagger-ui.html",
"/swagger-resources/**",
"/webjars/**",
"/v3/**"
).permitAll()
.anyRequest()
.authenticated()
.and().logout().logoutUrl("/logout")
.logoutSuccessHandler(logoutSuccessHandler)
.and()
.logout().permitAll()
.and().sessionManagement()
.maximumSessions(1)
.expiredSessionStrategy(sessionInformationExpiredStrategy);
http.exceptionHandling().accessDeniedHandler(ajaxAccessDeniedHandler);
http.addFilter(new TokenLoginFilter(authenticationManager(),redisUtils,logService,powerManagerMapper)).httpBasic();
http.addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
package com.gremlin.security.service;
import com.gremlin.security.mapper.UserMapper;
import com.gremlin.security.vo.MyUserDetails;
import com.gremlin.security.vo.User;
import com.gremlin.security.vo.req.ReqUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class MyUserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String loginUsername) throws UsernameNotFoundException {
ReqUser reqUser = new ReqUser();
reqUser.setLoginUsername(loginUsername);
User userInfo = userMapper.getUserInfo(reqUser);
if (null == userInfo){
throw new UsernameNotFoundException("该用户不存在或被禁用请联系管理员");
}
String password = userInfo.getPassword();
return new MyUserDetails(loginUsername,password);
}
}
package com.gremlin.security.fifter;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.gremlin.account.vo.req.ReqAccount;
import com.gremlin.common.resp.ResponseResult;
import com.gremlin.common.resp.ResultEnum;
import com.gremlin.common.utils.AccessAddressUtils;
import com.gremlin.common.utils.JwtTokenUtils;
import com.gremlin.common.utils.RedisUtils;
import com.gremlin.log.service.LogService;
import com.gremlin.power.mapper.PowerManagerMapper;
import com.gremlin.power.vo.resp.RespRole;
import com.gremlin.security.vo.MyUserDetails;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {
private final RedisUtils redisUtil;
private final AuthenticationManager authenticationManager;
private final LogService logService;
private final PowerManagerMapper powerManagerMapper;
public TokenLoginFilter(AuthenticationManager authenticationManager, RedisUtils redisUtil,
LogService logService,PowerManagerMapper powerManagerMapper) {
this.authenticationManager = authenticationManager;
this.redisUtil = redisUtil;
this.logService = logService;
this.powerManagerMapper = powerManagerMapper;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
throws AuthenticationException {
System.out.println(2);
if ("POST".equals(req.getMethod())) {
String body = getBody(req);
JSONObject jsonObject = JSON.parseObject(body);
String username = jsonObject.getString("loginUsername");
String password = jsonObject.getString("password");
String ip = AccessAddressUtils.getIpAddress(req);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest =
new UsernamePasswordAuthenticationToken(username, password);
logService.insertLog(ip, "1", "登入", username);
return authenticationManager.authenticate(authRequest);
}
return null;
}
@Override
protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,
Authentication auth) throws IOException {
System.out.println(4);
Map<String, Object> map = new HashMap<>();
String ip = AccessAddressUtils.getIpAddress(req);
map.put("ip", ip);
MyUserDetails userDetails = (MyUserDetails) auth.getPrincipal();
String jwtToken = JwtTokenUtils.generateToken(userDetails.getUsername(),map);
userDetails.setToken(jwtToken);
ReqAccount reqAccount = new ReqAccount();
reqAccount.setLoginUsername(userDetails.getUsername());
RespRole respRole = new RespRole();
respRole = powerManagerMapper.queryRoleByUsername(reqAccount);
map.put("juese",respRole);
redisUtil.setTokenRefresh(userDetails.getUsername(), userDetails.getToken(), ip);
log.info("用户{}登录成功,信息已保存至redis", userDetails.getUsername());
res.setHeader("Content-type", "application/json;charset=UTF-8");
map.put("token", jwtToken);
redisUtil.set(userDetails.getUsername()+"token",jwtToken);
res.getWriter().write(JSON.toJSONString(ResponseResult.success(map, ResultEnum.SUCCESS.getCode(), ResultEnum.USER_LOGIN_SUCCESS.getMessage())));
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException e) throws IOException {
response.setHeader("Content-type", "application/json;charset=UTF-8");
if (e instanceof UsernameNotFoundException) {
response.getWriter().write(JSON.toJSONString(ResponseResult.failed(ResultEnum.USER_NOT_FIND.getMessage(), ResultEnum.USER_NOT_FIND.getCode())));
} else if (e instanceof BadCredentialsException) {
response.getWriter().write(JSON.toJSONString(ResponseResult.failed(ResultEnum.USER_LOGIN_FAILED.getMessage(), ResultEnum.USER_LOGIN_FAILED.getCode())));
} else if (e instanceof LockedException) {
response.getWriter().write(JSON.toJSONString(ResponseResult.failed("用户已被锁定", 207)));
}else {
response.getWriter().write(JSON.toJSONString(ResponseResult.failed(ResultEnum.USER_LOGIN_FAILED.getMessage(), ResultEnum.USER_LOGIN_FAILED.getCode())));
}
}
public String getBody(HttpServletRequest request) {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
BufferedReader reader = null;
try {
inputStream = request.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
}
package com.gremlin.security.fifter;
import com.alibaba.fastjson2.JSON;
import com.gremlin.common.resp.ResponseResult;
import com.gremlin.common.resp.ResultEnum;
import com.gremlin.common.utils.CollectionUtil;
import com.gremlin.common.utils.DateUtil;
import com.gremlin.common.utils.JwtTokenUtils;
import com.gremlin.common.utils.RedisUtils;
import com.gremlin.security.service.MyUserDetailsServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
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.Date;
import java.util.HashMap;
import java.util.Map;
@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
private MyUserDetailsServiceImpl userDetailsService;
@Autowired
private RedisUtils redisUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println(1);
String authToken = request.getHeader("token");
response.setHeader("Content-type", "application/json;charset=UTF-8");
if (null != authToken) {
if (!JwtTokenUtils.isTokenExpired(authToken)) {
response.getWriter().write(JSON.toJSONString(ResponseResult.failed(ResultEnum.LOGIN_IS_OVERDUE.getMessage(), ResultEnum.LOGIN_IS_OVERDUE.getCode())));
}
String username = JwtTokenUtils.parseToken(authToken);
if (StringUtils.isBlank(username)) {
return;
}
String ip = CollectionUtil.getMapValue(JwtTokenUtils.getClaims(authToken), "ip");
if (redisUtil.hasKey(username)) {
String expirationTime = redisUtil.hasGet(username, "expirationTime").toString();
if (JwtTokenUtils.isExpiration(expirationTime)) {
String tokenValidTime = (String) redisUtil.getTokenValidTimeByToken(username);
String currentTime = DateUtil.getTime();
if (DateUtil.compareDate(currentTime, tokenValidTime) && !DateUtil.compareDate(tokenValidTime, expirationTime)) {
log.info("{}已超过有效期,不予刷新", authToken);
response.getWriter().write(JSON.toJSONString(ResponseResult.success(null, ResultEnum.LOGIN_IS_OVERDUE.getCode(), ResultEnum.LOGIN_IS_OVERDUE.getMessage())));
return;
} else {
Date tokenTime = JwtTokenUtils.getTokenTime(authToken);
String usernameByToken = (String) redisUtil.getUsernameByToken(username);
username = usernameByToken;
ip = (String) redisUtil.getIpByToken(username);
if (DateUtil.compareDate(tokenTime, new Date())) {
Map<String, Object> map = new HashMap<>();
map.put("ip", ip);
String jwtToken = JwtTokenUtils.generateToken(usernameByToken,map);
redisUtil.setTokenRefresh(username, jwtToken, ip);
log.info("redis已删除旧token:{},新token:{}已更新redis", authToken, jwtToken);
authToken = jwtToken;
}
redisUtil.set(username + "token", authToken, 1200);
}
}
} else {
log.info("{}redis登录信息不存在", username);
response.getWriter().write(JSON.toJSONString(ResponseResult.failed(ResultEnum.LOGIN_IS_OVERDUE.getMessage(), ResultEnum.LOGIN_IS_OVERDUE.getCode())));
return;
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (userDetails != null) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
response.reset();
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
}
filterChain.doFilter(request, response);
}
}
package com.gremlin.security.vo;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class MyUserDetails implements UserDetails {
@ApiModelProperty(value = "用户账户")
private String username;
@ApiModelProperty(value = "用户密码")
private String password;
@ApiModelProperty(value = "用户token值")
private String token;
public MyUserDetails(String username, String password) {
this.username = username;
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setToken(String token) {
this.token = token;
}
public String getToken() {
return token;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
package com.gremlin.security.handler;
import com.alibaba.fastjson2.JSON;
import com.gremlin.common.resp.ResponseResult;
import com.gremlin.common.resp.ResultEnum;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class AjaxAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
httpServletResponse.getWriter().write(JSON.toJSONString(ResponseResult.failed(ResultEnum.USER_NO_ACCESS.getMessage(),ResultEnum.USER_NO_ACCESS.getCode())));
}
}
package com.gremlin.security.handler;
import com.alibaba.fastjson.JSON;
import com.gremlin.common.resp.ResponseResult;
import com.gremlin.common.resp.ResultEnum;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class AjaxAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.setHeader("Content-type", "application/json;charset=UTF-8");
response.getWriter().write(JSON.toJSONString(ResponseResult.failed(ResultEnum.USER_NEED_AUTHORITIES.getMessage(),ResultEnum.USER_NEED_AUTHORITIES.getCode())));
}
}
package com.gremlin.security.handler;
import com.alibaba.fastjson2.JSON;
import com.gremlin.common.resp.ResponseResult;
import com.gremlin.common.resp.ResultEnum;
import com.gremlin.common.utils.JwtTokenUtils;
import com.gremlin.common.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
@Slf4j
public class AjaxLogoutSuccessHandler implements LogoutSuccessHandler {
@Autowired
private RedisUtils redisUtil;
@Override
public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException {
String authToken = req.getHeader("token");
if (null != authToken) {
String username = JwtTokenUtils.parseToken(authToken);
redisUtil.deleteKeys(username);
log.info("用户登出成功!token:{}已从redis删除", authToken);
}
resp.setHeader("Content-type", "application/json;charset=UTF-8");
resp.getWriter().write(JSON.toJSONString(ResponseResult.failed(ResultEnum.USER_LOGOUT_SUCCESS.getMessage(), ResultEnum.USER_LOGOUT_SUCCESS.getCode())));
}
}
package com.gremlin.security.strategy;
import com.alibaba.fastjson2.JSON;
import com.gremlin.common.resp.ResponseResult;
import com.gremlin.common.resp.ResultEnum;
import org.springframework.security.web.session.SessionInformationExpiredEvent;
import org.springframework.security.web.session.SessionInformationExpiredStrategy;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomizeSessionInformationExpiredStrategy implements SessionInformationExpiredStrategy {
@Override
public void onExpiredSessionDetected(SessionInformationExpiredEvent sessionInformationExpiredEvent) throws IOException {
HttpServletResponse httpServletResponse = sessionInformationExpiredEvent.getResponse();
httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
httpServletResponse.getWriter().write(JSON.toJSONString(
ResponseResult.failed(ResultEnum.USER_NO_ACCESS.getMessage(),ResultEnum.USER_NO_ACCESS.getCode())));
}
}
package com.gremlin.common.resp;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.Serializable;
@Slf4j
@Data
public class ResponseResult<T> implements Serializable {
@ApiModelProperty(value = "返回数据")
private T data;
@ApiModelProperty(value = "返回信息")
private String msg;
@ApiModelProperty(value = "结果code")
private Integer code;
@ApiModelProperty(value = "是否成功")
private Boolean isSuccess = true;
public ResponseResult() {
}
public ResponseResult(T data,Integer code, String msg) {
this.code = code;
this.msg = msg;
this.data = data;
}
public ResponseResult(T data,Integer code, String msg,Boolean isSuccess) {
this.code = code;
this.msg = msg;
this.data = data;
this.isSuccess = isSuccess;
}
public ResponseResult(String msg,Integer code) {
this.code = code;
this.msg = msg;
}
public ResponseResult(String msg) {
this.msg = msg;
}
public static <T> ResponseResult<T> success(T data, Integer code, String msg) {
return new ResponseResult<T>(data,code,msg);
}
public static <T> ResponseResult<T> success(T data, Integer code, String msg,Boolean isSuccess) {
return new ResponseResult<T>(data,code,msg,isSuccess);
}
public static <T> ResponseResult<T> failed(String msg,Integer code) {
return new ResponseResult<T>(msg,code);
}
public static <T> ResponseResult<T> failed(String msg) {
return new ResponseResult<T>(msg);
}
}
package com.gremlin.common.resp;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
@Getter
public enum ResultEnum {
SUCCESS(200,"请求成功"),
FAILURE(102,"请求失败"),
USER_NEED_AUTHORITIES(201,"用户未登录"),
USER_LOGIN_SUCCESS(203,"login success!"),
USER_LOGIN_FAILED(202,"用户账号或密码错误"),
USER_NOT_FIND(206,"该用户不存在或被禁用请联系管理员"),
USER_LOGOUT_SUCCESS(205,"登出成功!"),
USER_NO_ACCESS(301,"用户无权访问"),
LOGIN_IS_OVERDUE(204,"您的操作已超时,请重新登录"),
ERROR_PHONE(50001,"手机号码不正确"),
ERROR_EMAIL(50002,"邮箱地址不正确"),
ERROR_CODE(50003,"验证码错误"),
SEND_EMAIL(205,"邮件发送成功!")
;
@ApiModelProperty(value = "返回code")
private final Integer code;
@ApiModelProperty(value = "返回信息")
private final String message;
ResultEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}
package com.gremlin.common.utils;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
public class AccessAddressUtils {
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
package com.gremlin.common.utils;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
public class DateUtil {
private final static SimpleDateFormat SDF_TIME = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final SimpleDateFormat SDF_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
public static String getTime() {
return SDF_TIME.format(new Date());
}
public static boolean compareDate(String s, String e) {
if(fomatDate(s)==null||fomatDate(e)==null){
return false;
}
return s.compareTo(e)>0;
}
public static boolean compareDate(Date s, Date e) {
if(s==null||e==null){
return false;
}
return s.getTime()-e.getTime()<=5*60*1000;
}
public static Date fomatDate(String date) {
DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
try {
return fmt.parse(date);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
public static String getAddDay(int i){
String currentTime = DateUtil.getTime();
GregorianCalendar gCal = new GregorianCalendar(
Integer.parseInt(currentTime.substring(0, 4)),
Integer.parseInt(currentTime.substring(5, 7)) - 1,
Integer.parseInt(currentTime.substring(8, 10)));
gCal.add(GregorianCalendar.DATE, i);
return SDF_DATE_FORMAT.format(gCal.getTime());
}
public static String getAddDayTime(int i){
Date date = new Date(System.currentTimeMillis()+ (long) i *24*60*60*1000);
return SDF_TIME.format(date);
}
public static String getAddDaySecond(int i){
Date date = new Date(System.currentTimeMillis()+i* 1000L);
return SDF_TIME.format(date);
}
}
package com.gremlin.common.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.CompressionCodecs;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
@Slf4j
public class JwtTokenUtils {
@ApiModelProperty(value = "令牌签名密钥")
private static final String tokenSignKey = "gremlin";
@ApiModelProperty(value = "token有效时长30分钟")
private static final long tokenExpiration = 30*60*1000;
public static String generateToken(String subject, Map<String,Object> claims) {
return Jwts.builder().setClaims(claims)
.setSubject(subject)
.setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
.signWith(SignatureAlgorithm.HS512, tokenSignKey)
.compressWith(CompressionCodecs.GZIP).compact();
}
public static Boolean isTokenExpired(String token) {
try {
return getTokenBody(token).getExpiration().before(new Date());
} catch (Exception e) {
return false;
}
}
public static String parseToken(String token) {
String subject = null;
try {
subject = getTokenBody(token).getSubject();
} catch (Exception e) {
log.info(String.valueOf(e));
}
return subject;
}
public static Map<String,Object> getClaims(String token){
Map<String,Object> claims = null;
try {
claims = getTokenBody(token);
}catch (Exception e) {
e.printStackTrace();
}
return claims;
}
public static Date getTokenTime(String token){
return getTokenBody(token).getExpiration();
}
public static boolean isExpiration(String expirationTime){
String currentTime = DateUtil.getTime();
if(DateUtil.compareDate(currentTime,expirationTime)){
return true;
}else{
return false;
}
}
private static Claims getTokenBody(String token){
return Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token).getBody();
}
public static String getUserByJwtToken(HttpServletRequest request) {
String jwtToken = request.getHeader("token");
if(!StringUtils.hasText(jwtToken)) {
return "";
}
Claims tokenBody = getTokenBody(jwtToken);
return tokenBody.getSubject();
}
}
package com.gremlin.common.utils;
import com.gremlin.security.vo.User;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtils {
@Autowired
private StringRedisTemplate redisTemplate;
@ApiModelProperty(value = "reids 中用户信息吗存储2小时 刷新时间")
private final int validTime = 2;
@ApiModelProperty(value = "过期时间 秒")
private final int expirationSeconds = 300;
public void deleteKey(String key) {
redisTemplate.opsForHash().getOperations().delete(key);
}
public void deleteKeys(String key) {
Set<String> keys = redisTemplate.keys(key + "*");
if (CollectionUtils.isNotEmpty(keys)){
redisTemplate.delete(keys);
}
}
public void delete(String key){
redisTemplate.opsForValue().getOperations().delete(key);
}
public Object get(String key){
return redisTemplate.opsForValue().get(key);
}
public void set(String key, String value){
redisTemplate.opsForValue().set(key,value, 7200, TimeUnit.SECONDS);
}
public void set(String key, String value,Integer expire){
redisTemplate.opsForValue().set(key,value, expire,TimeUnit.SECONDS);
}
public Object getTokenValidTimeByToken(String token) {
return redisTemplate.opsForHash().get(token, "tokenValidTime");
}
public Object getUsernameByToken(String token) {
return redisTemplate.opsForHash().get(token, "username");
}
public Object getIpByToken(String token) {
return redisTemplate.opsForHash().get(token, "ip");
}
public void setTokenRefresh(String username,String token,String ip){
Integer expire = validTime*60*60*1000;
hset(username, "tokenValidTime",DateUtil.getAddDayTime(validTime),expire);
hset(username, "expirationTime",DateUtil.getAddDaySecond(expirationSeconds),expire);
hset(username, "username",username,expire);
hset(username, "token",token,expire);
hset(username, "ip",ip,expire);
}
public void hset(String key,String filed,Object domain,Integer expire){
redisTemplate.opsForHash().put(key, filed, domain);
redisTemplate.expire(key, expire,TimeUnit.SECONDS);
}
public Boolean hasKey(String key,String field) {
return redisTemplate.opsForHash().hasKey(key,field);
}
public Boolean hasKey(String key) {
return redisTemplate.opsForHash().getOperations().hasKey(key);
}
public Object hasGet(String key,String field) {
return redisTemplate.opsForHash().get(key, field);
}
public Object hasGet(String key) {
return redisTemplate.opsForHash().entries(key);
}
public static User getUser(){
UserDetails userDetails
= (UserDetails) SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
User user = new User();
user.setUsername(userDetails.getUsername());
return user;
}
}
package com.gremlin.common.utils;
import com.gremlin.security.vo.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
@Service
public class TokenResponse {
@Autowired
private RedisUtils redisUtil;
public void getResponse(HttpServletResponse response) {
User user = RedisUtils.getUser();
Object token = redisUtil.get(user.getUsername()+"token");
if (StringUtils.isNotBlank((String)token)) {
response.reset();
response.setHeader("token", String.valueOf(token));
} else {
response.reset();
response.setHeader("token", String.valueOf(token));
}
}
}
|