mirror of
https://codeup.aliyun.com/64f7d6b8ce01efaafef1e678/coal/coal.git
synced 2026-01-25 07:46:40 +08:00
校验用户每次请求IP地址
This commit is contained in:
@@ -53,6 +53,7 @@ public class ControllerAop {
|
||||
|
||||
Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
|
||||
sessionService.rebuildSession(request.getHeader("X-Token"));
|
||||
|
||||
|
||||
@@ -65,7 +66,7 @@ public class ControllerAop {
|
||||
if (anonymous == null || !anonymous.value()) {
|
||||
|
||||
|
||||
throw new BizException("invalidToken", "登录状态失效,请重新登录");
|
||||
throw new BizException("invalidToken", "登录状态失效,请重新登录");
|
||||
|
||||
|
||||
}
|
||||
@@ -76,45 +77,49 @@ public class ControllerAop {
|
||||
|
||||
if (!Ctx.isSysAdmin()) {
|
||||
|
||||
OrgAdmin orgAdmin = ObjectUtils.defaultIfNull(AnnotationUtils.findAnnotation(method, OrgAdmin.class), AnnotationUtils.findAnnotation(method.getClass(), OrgAdmin.class));
|
||||
|
||||
if (orgAdmin != null && orgAdmin.value() && !Ctx.isOrgAdmin()) {
|
||||
if (!Ctx.isSysAdmin()) {
|
||||
|
||||
OrgAdmin orgAdmin = ObjectUtils.defaultIfNull(AnnotationUtils.findAnnotation(method, OrgAdmin.class), AnnotationUtils.findAnnotation(method.getClass(), OrgAdmin.class));
|
||||
|
||||
if (orgAdmin != null && orgAdmin.value() && !Ctx.isOrgAdmin()) {
|
||||
|
||||
|
||||
throw new BizException("invalidAccess", "非法访问,请联系机构管理员。");
|
||||
throw new BizException("invalidAccess", "非法访问,请联系机构管理员。");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SysAdmin sysAdmin = ObjectUtils.defaultIfNull(AnnotationUtils.findAnnotation(method, SysAdmin.class), AnnotationUtils.findAnnotation(method.getClass(), SysAdmin.class));
|
||||
SysAdmin sysAdmin = ObjectUtils.defaultIfNull(AnnotationUtils.findAnnotation(method, SysAdmin.class), AnnotationUtils.findAnnotation(method.getClass(), SysAdmin.class));
|
||||
|
||||
if (sysAdmin != null && sysAdmin.value() && !Ctx.isSysAdmin()) {
|
||||
if (sysAdmin != null && sysAdmin.value() && !Ctx.isSysAdmin()) {
|
||||
|
||||
|
||||
throw new BizException("invalidAccess", "非法访问,请联系系统管理员。");
|
||||
throw new BizException("invalidAccess", "非法访问,请联系系统管理员。");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UserEntity user = Ctx.currentUser();
|
||||
UserEntity user = Ctx.currentUser();
|
||||
|
||||
|
||||
if (ObjectUtils.<List<RoleEntity>>defaultIfNull(user.getRoles(), new ArrayList<>())
|
||||
.stream()
|
||||
.flatMap((RoleEntity r) -> ObjectUtils.<List<PermissionEntity>>defaultIfNull(r.getPermissions(), new ArrayList<>()).stream())
|
||||
.flatMap((PermissionEntity r) -> ObjectUtils.<List<ResourceEntity>>defaultIfNull(r.getResources(), new ArrayList<>()).stream())
|
||||
.noneMatch(x -> x.getUrl().equalsIgnoreCase(request.getRequestURI().replaceAll(request.getContextPath(), "")))) {
|
||||
if (ObjectUtils.<List<RoleEntity>>defaultIfNull(user.getRoles(), new ArrayList<>())
|
||||
.stream()
|
||||
.flatMap((RoleEntity r) -> ObjectUtils.<List<PermissionEntity>>defaultIfNull(r.getPermissions(), new ArrayList<>()).stream())
|
||||
.flatMap((PermissionEntity r) -> ObjectUtils.<List<ResourceEntity>>defaultIfNull(r.getResources(), new ArrayList<>()).stream())
|
||||
.noneMatch(x -> x.getUrl().equalsIgnoreCase(request.getRequestURI().replaceAll(request.getContextPath(), "")))) {
|
||||
|
||||
|
||||
}
|
||||
{
|
||||
throw new BizException("invalidAccess", "当前资源未授权,请联系机构管理员处理。");
|
||||
}
|
||||
{
|
||||
throw new BizException("invalidAccess", "当前资源未授权,请联系机构管理员处理。");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -136,8 +141,6 @@ public class ControllerAop {
|
||||
throw e;
|
||||
|
||||
|
||||
|
||||
|
||||
} finally {
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import cn.lihongjie.coal.dto.UserDto;
|
||||
import cn.lihongjie.coal.service.SessionService;
|
||||
import cn.lihongjie.coal.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -45,7 +46,10 @@ public class LoginController {
|
||||
@PostMapping("/logout")
|
||||
@SysLog(action = "退出")
|
||||
public Object logout() {
|
||||
this.service.logout();
|
||||
if (Ctx.isLoggedIn()) {
|
||||
|
||||
this.service.logout(((SessionService.MyAuthentication) SecurityContextHolder.getContext().getAuthentication()).getSessionId());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,4 +10,8 @@ public class LoginDto {
|
||||
private String password;
|
||||
private String captchaId;
|
||||
private String captcha;
|
||||
private String ip;
|
||||
private String ua;
|
||||
private String userId;
|
||||
private String sessionId;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
package cn.lihongjie.coal.service;
|
||||
|
||||
|
||||
import cn.lihongjie.coal.common.RequestUtils;
|
||||
import cn.lihongjie.coal.dto.CaptchaDto;
|
||||
import cn.lihongjie.coal.dto.LoginDto;
|
||||
import cn.lihongjie.coal.entity.OrganizationEntity;
|
||||
import cn.lihongjie.coal.entity.UserEntity;
|
||||
import cn.lihongjie.coal.exception.BizException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.wf.captcha.SpecCaptcha;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.Data;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -18,6 +23,8 @@ import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
@@ -63,8 +70,12 @@ public class SessionService {
|
||||
@Autowired
|
||||
OrganizationService organizationService;
|
||||
|
||||
public void login(LoginDto dto) {
|
||||
@Autowired
|
||||
ObjectMapper objectMapper;
|
||||
|
||||
@SneakyThrows
|
||||
public void login(LoginDto dto) {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
|
||||
String captchaId = dto.getCaptchaId();
|
||||
|
||||
@@ -102,7 +113,13 @@ public class SessionService {
|
||||
|
||||
context.setAuthentication(new MyAuthentication(dto, user, sessionId));
|
||||
|
||||
stringRedisTemplate.opsForValue().set(sessionId, user.getId(), 1, TimeUnit.HOURS);
|
||||
SecurityContextHolder.setContext(context);
|
||||
dto.setUserId(user.getId());
|
||||
dto.setSessionId(sessionId);
|
||||
dto.setUa(RequestUtils.getUa(request));
|
||||
dto.setIp(RequestUtils.getIp(request));
|
||||
|
||||
stringRedisTemplate.opsForValue().set(sessionId, objectMapper.writeValueAsString(dto), 1, TimeUnit.HOURS);
|
||||
|
||||
}
|
||||
|
||||
@@ -115,28 +132,52 @@ public class SessionService {
|
||||
}
|
||||
|
||||
|
||||
String userId = stringRedisTemplate.opsForValue().getAndExpire(sessionId, 1, TimeUnit.HOURS);
|
||||
String jsonstring = stringRedisTemplate.opsForValue().getAndExpire(sessionId, 1, TimeUnit.HOURS);
|
||||
|
||||
if (StringUtils.isEmpty(userId)) {
|
||||
throw new BizException("会话已过期,请重新登录");
|
||||
if (StringUtils.isEmpty(jsonstring)) {
|
||||
throw new BizException("invalidToken", "会话已过期,请重新登录");
|
||||
}
|
||||
LoginDto loginDto = null;
|
||||
|
||||
try {
|
||||
loginDto = objectMapper.readValue(jsonstring, LoginDto.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new BizException("invalidToken", "会话异常,请重新登录");
|
||||
}
|
||||
|
||||
UserEntity user = userService.get(userId);
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
String currentIp = RequestUtils.getIp(request);
|
||||
String currentUa = RequestUtils.getUa(request);
|
||||
if (!StringUtils.equalsIgnoreCase(currentIp, loginDto.getIp())) {
|
||||
|
||||
log.warn("检测到IP变化: {} {}", loginDto, currentIp);
|
||||
logout(loginDto.getSessionId());
|
||||
throw new BizException("invalidToken", "检测到IP发生变化,请重新登录");
|
||||
}
|
||||
if (!StringUtils.equalsIgnoreCase(currentUa, loginDto.getUa())) {
|
||||
|
||||
log.warn("检测到浏览器变化: {} {}", loginDto, currentUa);
|
||||
logout(loginDto.getSessionId());
|
||||
throw new BizException("invalidToken", "检测到浏览器发生变化,请重新登录");
|
||||
}
|
||||
|
||||
UserEntity user = userService.get(loginDto.getUserId());
|
||||
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
|
||||
context.setAuthentication(new MyAuthentication(null, user, sessionId));
|
||||
context.setAuthentication(new MyAuthentication(loginDto, user, sessionId));
|
||||
|
||||
SecurityContextHolder.setContext(context);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void logout(String sessionId) {
|
||||
|
||||
public void logout() {
|
||||
if (sessionId != null) {
|
||||
|
||||
String sessionId = ((MyAuthentication) SecurityContextHolder.getContext().getAuthentication()).sessionId;
|
||||
stringRedisTemplate.opsForValue().getAndDelete(sessionId);
|
||||
stringRedisTemplate.opsForValue().getAndDelete(sessionId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user