Commit 1ac02eca authored by suntao's avatar suntao

Merge branch 'v1'

* v1:
  日志
  未登录 或者 无权限 时 不抛出异常
  跨域设置
  session
  session 问题
parents b1d6f1e9 753e145f
...@@ -85,7 +85,7 @@ public class LoginServiceImpl implements LoginService { ...@@ -85,7 +85,7 @@ public class LoginServiceImpl implements LoginService {
// 保存用户最后登陆时间 // 保存用户最后登陆时间
user.setLastLoginTime(new Date()); user.setLastLoginTime(new Date());
userService.updateUser(user); userService.updateUser(user);
log.info("登陆成功sessionId="+ session.getId());
return session.getId(); return session.getId();
} }
......
package cn.quantgroup.cashloanflowboss.component.security; package cn.quantgroup.cashloanflowboss.component.security;
import cn.quantgroup.cashloanflowboss.core.base.Tuple;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
/** /**
...@@ -8,5 +10,5 @@ import org.aopalliance.intercept.MethodInvocation; ...@@ -8,5 +10,5 @@ import org.aopalliance.intercept.MethodInvocation;
* Created by WeiWei on 2018/12/24. * Created by WeiWei on 2018/12/24.
*/ */
public interface SecurityHandler { public interface SecurityHandler {
boolean doAuthentication(final MethodInvocation invocation, String authorityId, Authority[] authority) throws Throwable; Tuple<Boolean, ApplicationStatus> doAuthentication(final MethodInvocation invocation, String authorityId, Authority[] authority) throws Throwable;
} }
\ No newline at end of file
...@@ -2,9 +2,11 @@ package cn.quantgroup.cashloanflowboss.component.security; ...@@ -2,9 +2,11 @@ package cn.quantgroup.cashloanflowboss.component.security;
import cn.quantgroup.cashloanflowboss.component.security.annotiation.Security; import cn.quantgroup.cashloanflowboss.component.security.annotiation.Security;
import cn.quantgroup.cashloanflowboss.core.base.Result; import cn.quantgroup.cashloanflowboss.core.base.Result;
import cn.quantgroup.cashloanflowboss.core.base.Tuple;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus; import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.context.support.ApplicationObjectSupport; import org.springframework.context.support.ApplicationObjectSupport;
import java.io.Serializable; import java.io.Serializable;
...@@ -18,9 +20,10 @@ public class SecurityInterceptor extends ApplicationObjectSupport implements Met ...@@ -18,9 +20,10 @@ public class SecurityInterceptor extends ApplicationObjectSupport implements Met
public Object invoke(final MethodInvocation invocation) throws Throwable { public Object invoke(final MethodInvocation invocation) throws Throwable {
Security security = invocation.getMethod().getAnnotation(Security.class); Security security = invocation.getMethod().getAnnotation(Security.class);
Tuple<Boolean, ApplicationStatus> doAuthentication = this.getApplicationContext().getBean(SecurityHandler.class).doAuthentication(invocation, security.authorityId(), security.authorities());
if (!this.getApplicationContext().getBean(SecurityHandler.class).doAuthentication(invocation, security.authorityId(), security.authorities())) { if (BooleanUtils.isFalse(doAuthentication.getKey())) {
return Result.buildFail(ApplicationStatus.INVALID_AUTHORITY); // 未通过验证
return Result.buildFail(doAuthentication.getValue());
} }
return invocation.proceed(); return invocation.proceed();
......
...@@ -2,7 +2,9 @@ package cn.quantgroup.cashloanflowboss.core; ...@@ -2,7 +2,9 @@ package cn.quantgroup.cashloanflowboss.core;
import cn.quantgroup.cashloanflowboss.api.login.model.Principal; import cn.quantgroup.cashloanflowboss.api.login.model.Principal;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationDictionary; import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationDictionary;
import cn.quantgroup.cashloanflowboss.utils.IpUtil;
import cn.quantgroup.cashloanflowboss.utils.JSONTools; import cn.quantgroup.cashloanflowboss.utils.JSONTools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
...@@ -24,6 +26,7 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -24,6 +26,7 @@ import java.util.concurrent.ConcurrentHashMap;
/** /**
* Created by WeiWei on 2017/5/23. * Created by WeiWei on 2017/5/23.
*/ */
@Slf4j
@Component @Component
public class Application implements ApplicationContextAware, ServletContextAware { public class Application implements ApplicationContextAware, ServletContextAware {
...@@ -170,9 +173,15 @@ public class Application implements ApplicationContextAware, ServletContextAware ...@@ -170,9 +173,15 @@ public class Application implements ApplicationContextAware, ServletContextAware
* @return * @return
*/ */
public static Principal getPrincipal() { public static Principal getPrincipal() {
HttpSession session = getSession();
return Objects.nonNull(getSession()) ? JSONTools.deserialize(String.valueOf(getSession().getAttribute(ApplicationDictionary.PRINCIPAL)), Principal.class) : null; if (Objects.nonNull(session)) {
Principal principal = JSONTools.deserialize(String.valueOf(session.getAttribute(ApplicationDictionary.PRINCIPAL)), Principal.class);
log.info("后来访问获取sessionId={},userName={}", session.getId(), principal != null ? principal.getUserInfo().getUsername() : "null");
return principal;
} else {
log.info("后来访问获取session为空");
return null;
}
} }
/** /**
* 获取用户主要信息 * 获取用户主要信息
...@@ -182,9 +191,14 @@ public class Application implements ApplicationContextAware, ServletContextAware ...@@ -182,9 +191,14 @@ public class Application implements ApplicationContextAware, ServletContextAware
public static HttpSession getSession() { public static HttpSession getSession() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
if (Objects.nonNull(request)) {
return Objects.nonNull(request) && Objects.nonNull(request.getSession()) ? request.getSession() : null; HttpSession session = request.getSession();
if (Objects.nonNull(session)) {
log.info("后来访问获取sessionId={},requestIp={}", session.getId(), IpUtil.getRemoteIP(request));
return session;
}
}
return null;
} }
} }
\ No newline at end of file
...@@ -325,26 +325,22 @@ public class Assert { ...@@ -325,26 +325,22 @@ public class Assert {
public static Boolean isLastLogin(Map<String, Object> concurrentHashMapLoginInfo) { public static Boolean isLastLogin(Map<String, Object> concurrentHashMapLoginInfo) {
HttpSession session = Application.getSession(); HttpSession session = Application.getSession();
if (Objects.isNull(session)) { if (Objects.isNull(session)) {
System.out.println("session 为空");
return false; return false;
} }
Principal principal = Application.getPrincipal(); Principal principal = Application.getPrincipal();
if (Objects.isNull(principal)) { if (Objects.isNull(principal)) {
System.out.println("principal 为空");
return false; return false;
} }
Object userLastLoginTimeObject = concurrentHashMapLoginInfo.get(principal.getUserInfo().getUserId()+""); Object userLastLoginTimeObject = concurrentHashMapLoginInfo.get(principal.getUserInfo().getUserId()+"");
if (Objects.isNull(userLastLoginTimeObject)) { if (Objects.isNull(userLastLoginTimeObject)) {
// 没有登陆时间 不处理 // 没有登陆时间 不处理
System.out.println("userLastLoginTimeObject 为空");
return false; return false;
} }
// 获取session最后登陆时间 // 获取session最后登陆时间
Object creationTimeObject = session.getAttribute(ApplicationDictionary.USER_SESSION_LOGIN_TIME); Object creationTimeObject = session.getAttribute(ApplicationDictionary.USER_SESSION_LOGIN_TIME);
if (Objects.isNull(creationTimeObject)) { if (Objects.isNull(creationTimeObject)) {
System.out.println("lastAccessedTime 为空");
return false; return false;
} }
......
...@@ -8,10 +8,13 @@ import cn.quantgroup.cashloanflowboss.component.security.Authority; ...@@ -8,10 +8,13 @@ import cn.quantgroup.cashloanflowboss.component.security.Authority;
import cn.quantgroup.cashloanflowboss.component.security.SecurityHandler; import cn.quantgroup.cashloanflowboss.component.security.SecurityHandler;
import cn.quantgroup.cashloanflowboss.core.Application; import cn.quantgroup.cashloanflowboss.core.Application;
import cn.quantgroup.cashloanflowboss.core.asserts.Assert; import cn.quantgroup.cashloanflowboss.core.asserts.Assert;
import cn.quantgroup.cashloanflowboss.core.base.Tuple;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus; import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
import cn.quantgroup.cashloanflowboss.core.exception.ApplicationException; import cn.quantgroup.cashloanflowboss.core.exception.ApplicationException;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -22,6 +25,7 @@ import java.util.List; ...@@ -22,6 +25,7 @@ import java.util.List;
/** /**
* Created by WeiWei on 2019/7/26. * Created by WeiWei on 2019/7/26.
*/ */
@Slf4j
@Configuration @Configuration
public class ApplicationSecurityHandler implements SecurityHandler { public class ApplicationSecurityHandler implements SecurityHandler {
...@@ -29,31 +33,41 @@ public class ApplicationSecurityHandler implements SecurityHandler { ...@@ -29,31 +33,41 @@ public class ApplicationSecurityHandler implements SecurityHandler {
private LoginService loginService; private LoginService loginService;
@Override @Override
public boolean doAuthentication(MethodInvocation invocation, String authorityId, Authority[] authority) throws Throwable { public Tuple<Boolean, ApplicationStatus> doAuthentication(MethodInvocation invocation, String authorityId, Authority[] authority) {
Principal principal = Application.getPrincipal(); Principal principal = Application.getPrincipal();
// 检查是否已登录 // 检查是否已登录
Assert.isNull(principal, ApplicationStatus.AUTHENTICATION_LOGIN); if (principal == null) {
log.info("未曾登陆,需要重新登陆");
return new Tuple<>(Boolean.FALSE, ApplicationStatus.AUTHENTICATION_LOGIN);
}
// 是否 被挤下线 // 是否 被挤下线
Boolean isLogin = Assert.isLastLogin(loginService.getConcurrentHashMapLoginInfo()); Boolean isLogin = Assert.isLastLogin(loginService.getConcurrentHashMapLoginInfo());
if (isLogin != null && isLogin) { if (BooleanUtils.isTrue(isLogin)) {
log.info("已在其他地方登陆,需要重新登陆,userName=" + principal.getUserInfo().getUsername());
// 退出登陆 // 退出登陆
loginService.logout(); loginService.logout();
// 返回 信息 // 返回 信息
throw new ApplicationException(ApplicationStatus.AUTHENTICATION_LOGIN_CROWD_OUT); return new Tuple<>(Boolean.FALSE, ApplicationStatus.AUTHENTICATION_LOGIN_CROWD_OUT);
} }
// 如果是超级管理员跳过权限验证 // 如果是超级管理员跳过权限验证
return principal.isSuperAdministrator() || principal.getRoles().stream().anyMatch(role -> { boolean hasPrivilege = principal.isSuperAdministrator() || principal.getRoles().stream().anyMatch(role -> {
List<Role> roleList = getRoleAndParent(role); List<Role> roleList = getRoleAndParent(role);
if (CollectionUtils.isEmpty(roleList)) { if (CollectionUtils.isEmpty(roleList)) {
return false; return false;
} }
return roleList.stream().anyMatch(_role -> this.checkAuthority(authorityId, _role)); return roleList.stream().anyMatch(roleItem -> this.checkAuthority(authorityId, roleItem));
}); });
if (hasPrivilege) {
return new Tuple<>(Boolean.TRUE, null);
} else {
log.info("权限不足,userName={},authorityId={}" + principal.getUserInfo().getUsername(), authorityId);
return new Tuple<>(Boolean.FALSE, ApplicationStatus.INVALID_AUTHORITY);
}
} }
......
package cn.quantgroup.cashloanflowboss.core.configuration; package cn.quantgroup.cashloanflowboss.core.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.util.ArrayList;
import java.util.List;
/** /**
* function: * function:
* date: 2019/8/20 * date: 2019/8/20
...@@ -11,7 +18,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter ...@@ -11,7 +18,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
* @author: suntao * @author: suntao
*/ */
@Configuration @Configuration
public class CorsConfiguration extends WebMvcConfigurerAdapter { public class BossCorsConfiguration extends WebMvcConfigurerAdapter {
@Override @Override
public void addCorsMappings(CorsRegistry registry) { public void addCorsMappings(CorsRegistry registry) {
...@@ -23,4 +30,24 @@ public class CorsConfiguration extends WebMvcConfigurerAdapter { ...@@ -23,4 +30,24 @@ public class CorsConfiguration extends WebMvcConfigurerAdapter {
} }
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
List<String> list = new ArrayList<>();
list.add("*");
corsConfiguration.setAllowedOrigins(list);
/*
// 请求常用的三种配置,*代表允许所有,当时你也可以自定义属性(比如header只能带什么,只能是post方式等等)
*/
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}
//@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
} }
package cn.quantgroup.cashloanflowboss.utils;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
/**
* IP地址工具类
* @author mengfan.feng
* @time 2015-10-27 11:41
*/
public class IpUtil {
/**
* 通过指定请求获得对应的远程ip地址
* @param request
* @return
*/
public static String getRemoteIP(HttpServletRequest request) {
String ip = request.getHeader("x-real-ip");
if (StringUtils.isEmpty(ip)) {
ip = request.getRemoteAddr();
}
//过滤反向代理的ip
String[] stemps = ip.split(",");
if (stemps != null && stemps.length >= 1) {
//得到第一个IP,即客户端真实IP
ip = stemps[0];
}
ip = ip.trim();
int length = 23;
if (ip.length() > length) {
ip = ip.substring(0, 23);
}
return ip;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment