作者 唐俊升

Merge remote-tracking branch 'origin/kako' into kako

正在显示 26 个修改的文件 包含 504 行增加 和 101 行删除
... ... @@ -6,11 +6,16 @@ server:
port: 8066
servlet:
context-path: ${SERVER_CONTEXTPATH:}
tomcat:
connection-timeout: 20000 # 20秒
max-threads: 200
accept-count: 100
max-connections: 8192
spring:
devtools:
add-properties: false
profiles:
active: dev
active: prd
mvc:
#静态资源,设置上传文件的访问,
static-path-pattern: /**
... ... @@ -28,6 +33,7 @@ spring:
# host: 127.0.0.1
host: 192.168.1.53
port: 6379
password: vmvnv1v2VV.
jackson:
serialization:
FAIL_ON_EMPTY_BEANS: false
... ... @@ -50,7 +56,7 @@ spring:
enabled: true
datasource:
type: com.alibaba.druid.pool.DruidDataSource
type: com.zaxxer.hikari.HikariDataSource
#oracle
#driver-class-name=oracle.jdbc.OracleDriver
#url=jdbc:oracle:thin:@10.50.3.68:1521:CGODW
... ... @@ -61,30 +67,26 @@ spring:
username: 110
password: QAHqCJf2kFYCLirM
driver-class-name: com.mysql.cj.jdbc.Driver
#配置初始化大小/最小/最大
druid:
initial-size: 1
min-idle: 1
max-active: 20
#获取连接等待超时时间
max-wait: 60000
#一个连接在池中最小生存的时间
min-evictable-idle-time-millis: 300000
#间隔多久进行一次检测,检测需要关闭的空闲连接
time-between-eviction-runs-millis: 60000
#mysql
validation-query: SELECT 1 FROM DUAL
#oracle
#druid.validation-query:SELECT 'x' FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
default-auto-commit: true
# tomcat:
# max-wait: 10
# max-idle: 10000
# min-idle: 5
# initial-size: 5
# HikariCP特有配置
hikari:
# 连接池名称
pool-name: KakoUserHikariCP-
# 最小空闲连接数
minimum-idle: 1
# 最大连接数
maximum-pool-size: 20
# 连接超时时间(毫秒)
connection-timeout: 60000
# 空闲连接超时时间(毫秒)
idle-timeout: 300000
# 连接测试超时时间
validation-timeout: 3000
# 连接最大生命周期
max-lifetime: 1800000
# 连接测试查询
connection-test-query: SELECT 1
# 初始化连接数
initialization-fail-timeout: 1
eureka:
instance:
... ... @@ -95,11 +97,7 @@ eureka:
hostname: ${spring.cloud.client.ip-address}
lease-renewal-interval-in-seconds: 15
lease-expiration-duration-in-seconds: 45
health-check-url-path: /actuator/health
metadata-map:
user:
name: "admin" #These two are needed so that the server
password: "123456"
health-check-url-path: /ac/health
client:
#eureka注册中心服务器地址
service-url:
... ... @@ -107,19 +105,27 @@ eureka:
defaultZone: http://192.168.1.53:12345/eureka/
registry-fetch-interval-seconds: 30
management:
endpoints:
enabled-by-default: true
web:
base-path: /ac # 端点路径更改为 /ac
exposure:
include: "*"
include: "health,info" # 仅暴露必要端点
endpoint:
health:
show-details: always
show-details: never # 不显示详细健康信息
shutdown:
enabled: true
enabled: false # 禁用关闭端点
env:
enabled: false # 禁用环境端点(防止敏感信息泄露)
mappings:
enabled: false # 禁用映射端点(防止接口路径泄露)
beans:
enabled: false # 禁用beans端点
configprops:
enabled: false # 禁用configprops端点
mybatis:
mapper-locations: classpath:mapping/*.xml
... ...
... ... @@ -184,7 +184,7 @@
</springProfile>
<!--生产环境:输出到文件-->
<springProfile name="pro">
<springProfile name="prd">
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
... ... @@ -194,4 +194,4 @@
</root>
</springProfile>
</configuration>
\ No newline at end of file
</configuration>
... ...
... ... @@ -4,9 +4,11 @@ VOLUME /tmp
ADD *.jar app.jar
EXPOSE 8066
EXPOSE 8067
# Ubuntu 时区 同步主机与docker容器时间
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata
ENTRYPOINT ["java","-Xms128m", "-Xmx256m","-jar","/app.jar"]
ENTRYPOINT ["java","-jar","/app.jar"]
# Ubuntu 时区 同步主机与docker容器时间
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
\ No newline at end of file
... ...
... ... @@ -11,9 +11,9 @@
</parent>
<groupId>com.tianbo</groupId>
<artifactId>usercenter</artifactId>
<version>2.3Kako</version>
<version>2.3.8Kako</version>
<name>usercenter</name>
<description>usercenter for springcloud</description>
<description>usercenter for kako system</description>
<properties>
<java.version>1.8</java.version>
... ... @@ -169,12 +169,6 @@
<version>${fastjson_version}</version>
</dependency>
<!-- tools-->
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<!-- mysql-->
<dependency>
<groupId>mysql</groupId>
... ...
... ... @@ -2,6 +2,7 @@ package com.tianbo.warehouse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
... ... @@ -13,6 +14,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@Profile({"dev", "test"}) // 只在dev和test环境启用
public class Swagger2 {
//swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等
@Bean
... ...
package com.tianbo.warehouse.annotation.cache.util.redis;
import com.alibaba.druid.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
... ... @@ -10,6 +10,7 @@ import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Arrays;
... ...
package com.tianbo.warehouse.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tianbo.warehouse.controller.response.ResultJson;
import com.tianbo.warehouse.dao.KakoUserMapper;
import com.tianbo.warehouse.model.KakoUser;
import com.tianbo.warehouse.util.RedisUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
@RestController()
@Slf4j
public class HeartBeatController {
@Autowired
private RedisUtils redisUtils;
@Resource
private KakoUserMapper kakoUserMapper;
//token头部标识类型,Bearer代表Bearer TOKEN
static final String AUTHORIZATION_HEADER = "Bearer ";
//检查token时效是否低于标准线
static final long TOKEN_TTL_CHECK_MIN= 36000L;
//重置token时效为标准线
static final long TOKEN_TTL_ADD= 86400L;
//心跳每次续费时长
static final long HEARTBEAT_TOKEN_TTL_ADD= 10L;
@ApiOperation(value = "用户心跳接口", notes = "心跳续期")
@PostMapping("/heartbeat")
public ResultJson heartbeat(HttpServletRequest request, HttpServletResponse response){
try {
//1. 获取客户端IP,因为有反向代理所以要从头部获取代理过来的头部IP
String clientIP =null;
clientIP = request.getRemoteAddr();
String header_forwarded = request.getHeader("x-forwarded-for");
if (StringUtils.isNotBlank(header_forwarded)) {
clientIP = request.getHeader("x-forwarded-for");
// 多次反向代理后会有多个ip值,第一个ip才是真实ip
if (clientIP.contains(",")) {
clientIP = clientIP.split(",")[0];
}
}
//2.获取token
String token = request.getHeader("Authorization");
/**
* key样式
* accessToken:token
*/
if (token!=null && !token.isEmpty() && token.startsWith(AUTHORIZATION_HEADER)){
token = token.substring(AUTHORIZATION_HEADER.length());
String accessToken = token;
String userDetailStr = redisUtils.get(accessToken);
//4. 更新用户心跳时间及在线状态IP等资料
if (StringUtils.isNotBlank(userDetailStr)){
JSONObject u = JSON.parseObject(userDetailStr);
String userId= u.getString("id");
String userInfo = u.getString("name");
String username = u.getString("username");
// userDetailStr = userDetailStr.replace("@","");
/**3.续期token过期时间
* 增加过期时间,考虑到程序及网络传输中间的时间损耗,
* 每10秒一个的心跳直接续费10秒的话,token的过期时间还是会随着时间逐步减少
*/
long tokenExpireTime= redisUtils.getExpire(accessToken);
if(tokenExpireTime < TOKEN_TTL_CHECK_MIN){
redisUtils.expire(accessToken, TOKEN_TTL_ADD);
redisUtils.expire(username, TOKEN_TTL_ADD);
}else{
redisUtils.expire(accessToken,tokenExpireTime+HEARTBEAT_TOKEN_TTL_ADD);
redisUtils.expire(username, tokenExpireTime+HEARTBEAT_TOKEN_TTL_ADD);
}
/**
* 多式联运用户表
*/
// Integer dsly_userId = u.getInteger("id");
// USER user = new USER();
// user.setId(dsly_userId);
// user.setLoginip(clientIP);
// user.setLogintime(new Date());
// user.setOnline(true);
// int ii = userMapper.updateByPrimaryKeySelective(user);
KakoUser kakoUser = new KakoUser();
kakoUser.setId(userId);
kakoUser.setLoginIp(clientIP);
kakoUser.setLoginDate(new Date());
kakoUser.setOnline(true);
int i = kakoUserMapper.updateByPrimaryKeySelective(kakoUser);
return i > 0 ? new ResultJson("200","心跳成功"): new ResultJson("400","心跳失败");
}
}
return new ResultJson("400","心跳失败");
}catch (Exception e){
log.error("[HEART-BEAT-ERROR]-",e);
return new ResultJson("400","心跳失败");
}
}
}
... ...
... ... @@ -46,7 +46,7 @@ public class PermssionController {
}
@LogAnnotation(moduleName = "权限管理",operate = "权限修改")
@PutMapping("/edit")
@PostMapping("/edit")
@ResponseBody
public ResultJson edit(@RequestBody @Valid PERMISSION permission){
... ... @@ -62,7 +62,7 @@ public class PermssionController {
}
@LogAnnotation(moduleName = "权限管理",operate = "权限删除")
@DeleteMapping("/del")
@PostMapping("/del")
public ResultJson reomve(@RequestBody PERMISSION permission, HttpServletRequest request, HttpServletResponse response){
int i =permissionService.deleteByPrimaryKey(permission.getPermissionId().toString());
... ...
... ... @@ -47,14 +47,14 @@ public class RoleController {
* @return
*/
@LogAnnotation(moduleName = "岗位/角色管理",operate = "权限设置")
@PutMapping("/permSet")
@PostMapping("/permSet")
public ResultJson permissionSet(@RequestBody RolePermission rolePermission){
int i = roleService.setRolePermissoin(rolePermission);
return i==1 ? new ResultJson("200","设置权限成功") :new ResultJson("500","设置权限失败");
}
@LogAnnotation(moduleName = "岗位/角色管理",operate = "岗位/角色修改")
@PutMapping("/edit")
@PostMapping("/edit")
@ResponseBody
public ResultJson edit(@RequestBody @Valid ROLE role){
... ... @@ -70,7 +70,7 @@ public class RoleController {
}
@LogAnnotation(moduleName = "岗位/角色管理",operate = "岗位/角色删除")
@DeleteMapping("/del")
@PostMapping("/del")
public ResultJson reomve(@RequestBody ROLE role, HttpServletRequest request, HttpServletResponse response){
int i =roleService.deleteByPrimaryKey(role.getRoleId());
... ...
... ... @@ -26,6 +26,7 @@ import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.context.SecurityContextHolder;
... ... @@ -71,10 +72,16 @@ public class UserController {
@RequestParam(value = "pageSize",required = false,defaultValue = "5")
int pageSize,
@RequestParam(value = "userName",required = false) String username,
@RequestParam(value = "realName",required = false) String realname)
@RequestParam(value = "realName",required = false) String realname,
@RequestParam(value = "online",required = false) Boolean online,
@RequestParam(value = "loginFlag",required = false) String loginFlag)
{
PageInfo<KakoUser> usersPageInfo = userService.selectAllUser(pageNum,pageSize, username, realname);
KakoUser kakoUser = new KakoUser();
kakoUser.setLoginFlag(loginFlag);
kakoUser.setLoginName(username);
kakoUser.setName(realname);
kakoUser.setOnline(online);
PageInfo<KakoUser> usersPageInfo = userService.selectAllUser(pageNum,pageSize, kakoUser);
return new ResultJson("200","success",usersPageInfo);
}
... ... @@ -86,17 +93,36 @@ public class UserController {
}
@LogAnnotation(moduleName = "用户管理",operate = "用户编辑")
@PutMapping("/edit")
@PostMapping("/edit")
public ResultJson updateUserById(@Validated(UpdateUser.class) @RequestBody KakoUser user){
user.setPassword(null);
int i = userService.updateByPrimaryKeySelective(user);
ResultJson resultJson = new ResultJson();
return i==1 ? new ResultJson("200","success") :new ResultJson("500","update faild");
}
@LogAnnotation(moduleName = "用户锁定",operate = "用户锁定")
@PostMapping("/lock")
public ResultJson lockUserById(@Validated(UpdateUser.class) @RequestBody KakoUser user){
KakoUser kakoUser = new KakoUser();
kakoUser.setId(user.getId());
kakoUser.setLoginFlag(user.getLoginFlag());
int i = userService.updateByPrimaryKeySelective(kakoUser);
//删除用户token缓存 及时生效锁定账号
if (i>0){
String userTokenStr = redisUtils.get(KakoUser.TOKEN_KEY + user.getLoginName());
if (StringUtils.isNotEmpty(userTokenStr)){
redisUtils.del(userTokenStr);
}
log.info("用户锁定成功:key:{}",userTokenStr);
}
return i==1 ? new ResultJson("200","success") :new ResultJson("500","lock user faild");
}
@LogAnnotation(moduleName = "用户管理",operate = "用户密码修改")
@PutMapping("/password")
@PostMapping("/password")
public ResultJson updateUserPassById(@RequestBody KakoUser user){
KakoUser kakoUser = new KakoUser();
kakoUser.setId(user.getId());
... ... @@ -114,21 +140,19 @@ public class UserController {
}
int i = userService.insertSelective(user);
ResultJson resultJson = new ResultJson();
return i==1 ? new ResultJson("200","新建账户成功") :new ResultJson("500","insert faild");
}
@LogAnnotation(moduleName = "用户管理",operate = "用户删除")
@DeleteMapping("/del")
@PostMapping("/del")
public ResultJson delUser(@RequestBody KakoUser user,HttpServletRequest request,HttpServletResponse response){
//String username = getusername();
int i = userService.deleteByPrimaryKey(user);
ResultJson resultJson = new ResultJson();
return i==1 ? new ResultJson("200","删除账户成功") :new ResultJson("500","delete faild");
}
@PutMapping("/roleset")
@PostMapping("/roleset")
public ResultJson roleSet(@RequestBody Map<String,Object> map,HttpServletRequest request,HttpServletResponse respons){
String id = map.get("userId").toString();
List<Integer> roles = (List<Integer>) map.get("roleIds");
... ... @@ -144,7 +168,7 @@ public class UserController {
*/
@ApiOperation(value = "更新用户权限缓存", notes = "重新生成用户的信息到redis")
@RedisCacheDelTarget(cacheKey = "com.tianbo.warehouse.service.imp.PermissionServiceImp")
@PutMapping("/resetToken")
@PostMapping("/resetToken")
public ResultJson resetToken(HttpServletRequest request,HttpServletResponse respons) {
/**
* 更新目标用户的权限缓存
... ...
... ... @@ -13,6 +13,7 @@ public interface KakoUserMapper {
KakoUser selectByPrimaryKey(String id);
int updateByPrimaryKeySelective(KakoUser record);
int updateByPrimaryKey(KakoUser record);
... ... @@ -21,7 +22,9 @@ public interface KakoUserMapper {
List<KakoUser> selectAllUser(KakoUser record);
List<KakoUser> selectOnlineUser();
int lockUser(KakoUser record);
}
\ No newline at end of file
}
... ...
package com.tianbo.warehouse.heatbeat;
import com.tianbo.warehouse.dao.KakoUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import com.tianbo.warehouse.model.KakoUser;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
@Component
@Slf4j
public class OfflineTheardJob implements Runnable {
private static OfflineTheardJob offlineTheardJob;
private KakoUser user;
//用户掉线判定时间差
static final long OFFLINE_= 60L;
@Resource
private KakoUserMapper userMapper;
OfflineTheardJob() {
}
OfflineTheardJob(KakoUser user) {
this.user = user;
}
@PostConstruct
public void init(){
offlineTheardJob = this;
}
@Override
public void run(){
Date userLoginTime = user.getLoginDate();
if(userLoginTime!=null){
long diff= Math.abs(System.currentTimeMillis() - userLoginTime.getTime());
long s = diff / 1000;
log.info("[HEAT-BEAT]-用户{}心跳-时间相差{}秒",user.getName(),s);
if (s > OFFLINE_){
setOffline();
}
}else {
setOffline();
}
}
private void setOffline(){
user.setOnline(false);
int i = offlineTheardJob.userMapper.updateByPrimaryKeySelective(user);
if (i>0){
log.info("用户id:{},用户名称:{},从IP:{}掉线",user.getId(),user.getName(),user.getLoginIp());
}
}
}
... ...
package com.tianbo.warehouse.heatbeat;
import com.tianbo.warehouse.dao.KakoUserMapper;
import com.tianbo.warehouse.model.KakoUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 清理心跳超时的在线用户,判定为离线
* @author xyh
* @date
* 记得给用户ID,用户名称,用户心跳时间,用户登录ip,用户在线状态的数据库字段设置索引。
*/
@Slf4j
@Component
public class OfflineUserTask {
@Resource
private KakoUserMapper userMapper;
@Scheduled(fixedRate = 60000)
private void offlineUserHeartBeat(){
//初始化线程池
ThreadPoolExecutor threadPool = XMLThreadPoolFactory.instance();
List<KakoUser> userList = userMapper.selectOnlineUser();
if (userList!=null && !userList.isEmpty()){
log.trace("用户掉线判定开始,共需判定{}个在线标识用户",userList.size());
for (KakoUser user:userList) {
OfflineTheardJob offlineTheardJob = new OfflineTheardJob(user);
threadPool.execute(offlineTheardJob);
}
}
}
}
... ...
package com.tianbo.warehouse.heatbeat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ThreadFactory;
public class XMLThreadFactory implements ThreadFactory {
private int counter;
private String name;
private List<String> stats;
public XMLThreadFactory(String name)
{
counter = 1;
this.name = name;
stats = new ArrayList<String>();
}
@Override
public Thread newThread(Runnable runnable)
{
Thread t = new Thread(runnable, name + "-Thread_" + counter);
counter++;
stats.add(String.format("Created thread %d with name %s on %s \n", t.getId(), t.getName(), new Date()));
return t;
}
public String getStats()
{
StringBuffer buffer = new StringBuffer();
Iterator<String> it = stats.iterator();
while (it.hasNext())
{
buffer.append(it.next());
}
return buffer.toString();
}
}
... ...
package com.tianbo.warehouse.heatbeat;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class XMLThreadPoolFactory {
private static ThreadPoolExecutor threadPool;
public static ThreadPoolExecutor instance(){
if (threadPool==null){
XMLThreadFactory xmlThreadFactory = new XMLThreadFactory("heartbeatTask");
threadPool = new ThreadPoolExecutor(12, 64,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(1024),
xmlThreadFactory,
new ThreadPoolExecutor.AbortPolicy());
}
return threadPool;
}
}
... ...
... ... @@ -18,6 +18,8 @@ import java.util.Date;
import java.util.List;
public class KakoUser implements UserDetails {
public static String TOKEN_KEY = "user:";
private String id;
private String companyId;
... ... @@ -67,6 +69,10 @@ public class KakoUser implements UserDetails {
private String token;
private Boolean online;
private Date expiryDate;
@JSONField(serialzeFeatures= {SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNullStringAsEmpty})
private List<ROLE> roles;
... ... @@ -269,13 +275,39 @@ public class KakoUser implements UserDetails {
this.token = token;
}
public Boolean getOnline() {
return online;
}
public void setOnline(Boolean online) {
this.online = online;
}
public Date getExpiryDate() {
return expiryDate;
}
public void setExpiryDate(Date expiryDate) {
this.expiryDate = expiryDate;
}
/**
*
* @return 账户未过期
* 未过期为true,已过期为false
*/
@Override
public boolean isAccountNonExpired(){
return true;
// 无过期时间字段时视为永不过期
if(expiryDate == null) {
return true;
}else {
Boolean check = new Date().before(expiryDate);
return check;
}
// 当前时间在过期时间之前视为未过期
}
/**
... ... @@ -327,4 +359,4 @@ public class KakoUser implements UserDetails {
}
return auths;
}
}
\ No newline at end of file
}
... ...
... ... @@ -7,8 +7,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.DefaultRedirectStrategy;
... ... @@ -69,6 +71,8 @@ public class MyAuthenticationFailHandler extends SimpleUrlAuthenticationFailureH
response.sendError(HttpStatus.UNAUTHORIZED.value(),"用户不存在或者密码错误");
} else if (exception instanceof DisabledException) {
response.sendError(HttpStatus.UNAUTHORIZED.value(),"账户被禁用,登录失败,请联系管理员!");
} else if (exception instanceof AccountExpiredException) {
response.sendError(HttpStatus.UNAUTHORIZED.value(),"账户已过期,登录失败,请联系管理员!");
} else {
response.sendError(HttpStatus.UNAUTHORIZED.value(),"登录失败");
}
... ...
... ... @@ -53,9 +53,11 @@ public class MyKakoAuthenticationSuccessHandler extends SavedRequestAwareAuthent
@Autowired
RedisUtils redisUtils;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
logger.info("登录成功");
int expirationSeconds = 3600*24*7;
if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())){
//将 authention 信息打包成json格式返回
response.setContentType("application/json;charset=UTF-8");
... ... @@ -77,7 +79,8 @@ public class MyKakoAuthenticationSuccessHandler extends SavedRequestAwareAuthent
loginedUser.setToken(jwtToken);
//这里将登录成功的[user]对象数据写入redis缓存,KEY为token value为user的JSON对象
String json = JSON.toJSONString(user);
redisUtils.set(jwtToken, json,3600*24*7);
redisUtils.set(jwtToken, json,expirationSeconds);
redisUtils.set(KakoUser.TOKEN_KEY + user.getUsername(),jwtToken,expirationSeconds);
Map<String,Object> menuMap = permissionService.getUserMenusKako(user.getId());
//返回用户信息和用户可访问的目录列表
response.getWriter().write(objectMapper.writeValueAsString(new AuthSuccessResponse(loginedUser,menuMap)));
... ...
... ... @@ -11,10 +11,7 @@ import org.apache.shiro.crypto.hash.Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
... ... @@ -63,6 +60,11 @@ public class MyLoginAuthenticationProvider extends CodecSupport implements Authe
throw new DisabledException("用户被禁用");
}
// 过期判定
if (!userInfo.isAccountNonExpired()){
throw new AccountExpiredException("用户已过期");
}
//取盐规则
byte[] salt = PasswordSaltUtils.getSalt16(userInfo.getPassword());
//真实密码
... ...
... ... @@ -13,7 +13,7 @@ public interface KakoUserService {
KakoUser loadByUsername(String username);
PageInfo<KakoUser> selectAllUser(int pageNum, int pageSize, String username, String realName);
PageInfo<KakoUser> selectAllUser(int pageNum, int pageSize, KakoUser kakoUser);
int insertSelective(KakoUser record);
... ...
... ... @@ -59,11 +59,8 @@ public class KakoUserServiceImpl implements KakoUserService{
}
@Override
public PageInfo<KakoUser> selectAllUser(int pageNum, int pageSize,String username, String realName){
public PageInfo<KakoUser> selectAllUser(int pageNum, int pageSize,KakoUser users){
Page<KakoUser> page = PageHelper.startPage(pageNum,pageSize);
KakoUser users = new KakoUser();
users.setLoginName(username);
users.setName(realName);
List<KakoUser> list = kakoUserMapper.selectAllUser(users);
for (KakoUser user: list) {
// List<PERMISSION> permissionList = permissionMapper.findByUserId(user.getUserId());
... ...
... ... @@ -23,11 +23,18 @@
<result column="update_date" property="updateDate" jdbcType="TIMESTAMP" />
<result column="remarks" property="remarks" jdbcType="VARCHAR" />
<result column="del_flag" property="delFlag" jdbcType="CHAR" />
<result column="online" property="online" jdbcType="BOOLEAN" />
<result column="expiry_date" property="expiryDate" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="Base_Column_List" >
id, company_id, office_id, login_name, password, no, name, email, phone, mobile,
user_type, photo, login_ip, login_date, login_flag, create_by, create_date, update_by,
update_date, remarks, del_flag
update_date, remarks, del_flag, online, expiry_date
</sql>
<sql id="Safe_Column_List">
id, company_id, office_id, login_name, no, name, email, phone, mobile,
user_type, photo, login_ip, login_date, login_flag, create_by, create_date, update_by,
update_date, remarks, del_flag, online, expiry_date
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
... ... @@ -37,16 +44,23 @@
</select>
<select id="selectAllUser" resultMap="BaseResultMap" parameterType="com.tianbo.warehouse.model.KakoUser" >
select
<include refid="Base_Column_List" />
<include refid="Safe_Column_List" />
from sys_user
WHERE 1=1
and del_flag= '0'
<if test=" loginName != null" >
and login_name like concat('%',#{loginName,jdbcType=VARCHAR},'%')
</if>
<if test="name != null" >
and name like concat('%',#{name,jdbcType=VARCHAR},'%')
</if>
<where>
and del_flag= '0'
<if test=" loginName != null" >
and login_name like concat('%',#{loginName,jdbcType=VARCHAR},'%')
</if>
<if test="name != null" >
and name like concat('%',#{name,jdbcType=VARCHAR},'%')
</if>
<if test="online != null" >
and online = #{online,jdbcType=BOOLEAN}
</if>
<if test="loginFlag != null" >
and login_flag = #{loginFlag,jdbcType=VARCHAR}
</if>
</where>
</select>
<select id="selectByUsername" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
... ... @@ -54,6 +68,14 @@
from sys_user
where login_name = #{login_name,jdbcType=VARCHAR}
</select>
<select id="selectOnlineUser" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List" />
from sys_user
where online > 0;
</select>
<update id="deleteByPrimaryKey" parameterType="java.lang.String" >
update sys_user
set
... ... @@ -67,7 +89,7 @@
mobile, user_type, photo,
login_ip, login_date, login_flag,
create_by, create_date, update_by,
update_date, remarks, del_flag
update_date, remarks, del_flag, expiry_date
)
values (#{id,jdbcType=VARCHAR}, #{companyId,jdbcType=VARCHAR}, #{officeId,jdbcType=VARCHAR},
#{loginName,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{no,jdbcType=VARCHAR},
... ... @@ -75,7 +97,7 @@
#{mobile,jdbcType=VARCHAR}, #{userType,jdbcType=CHAR}, #{photo,jdbcType=VARCHAR},
#{loginIp,jdbcType=VARCHAR}, #{loginDate,jdbcType=TIMESTAMP}, #{loginFlag,jdbcType=VARCHAR},
#{createBy,jdbcType=VARCHAR}, #{createDate,jdbcType=TIMESTAMP}, #{updateBy,jdbcType=VARCHAR},
#{updateDate,jdbcType=TIMESTAMP}, #{remarks,jdbcType=VARCHAR}, #{delFlag,jdbcType=CHAR}
#{updateDate,jdbcType=TIMESTAMP}, #{remarks,jdbcType=VARCHAR}, #{delFlag,jdbcType=CHAR}, #{expiryDate,jdbcType=TIMESTAMP}
)
</insert>
<insert id="insertSelective" parameterType="com.tianbo.warehouse.model.KakoUser" >
... ... @@ -144,6 +166,9 @@
<if test="delFlag != null" >
del_flag,
</if>
<if test="expiryDate != null" >
expiry_date,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
... ... @@ -209,6 +234,9 @@
<if test="delFlag != null" >
#{delFlag,jdbcType=CHAR},
</if>
<if test="expiryDate != null" >
#{expiryDate,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.tianbo.warehouse.model.KakoUser" >
... ... @@ -274,6 +302,12 @@
<if test="delFlag != null" >
del_flag = #{delFlag,jdbcType=CHAR},
</if>
<if test="online != null" >
online = #{online,jdbcType=BOOLEAN},
</if>
<if test="expiryDate != null" >
expiry_date = #{expiryDate,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
... ... @@ -298,7 +332,9 @@
update_by = #{updateBy,jdbcType=VARCHAR},
update_date = #{updateDate,jdbcType=TIMESTAMP},
remarks = #{remarks,jdbcType=VARCHAR},
del_flag = #{delFlag,jdbcType=CHAR}
del_flag = #{delFlag,jdbcType=CHAR},
online = #{online,jdbcType=BOOLEAN},
expiry_date = #{expiryDate,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=VARCHAR}
</update>
... ...
... ... @@ -19,7 +19,7 @@
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">Spring Security演示</a>
<a class="navbar-brand" href="#">u have no rights</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
... ... @@ -33,4 +33,4 @@
welcom
</div>
</body>
</html>
\ No newline at end of file
</html>
... ...
... ... @@ -19,7 +19,7 @@
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">Spring Security演示</a>
<a class="navbar-brand" href="#">user center</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
... ... @@ -33,4 +33,4 @@
</div>
</body>
</html>
\ No newline at end of file
</html>
... ...
... ... @@ -19,7 +19,7 @@
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">Spring Security演示</a>
<a class="navbar-brand" href="#">user center</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
... ... @@ -54,4 +54,4 @@
</body>
</html>
\ No newline at end of file
</html>
... ...
... ... @@ -19,7 +19,7 @@
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">Spring Security演示</a>
<a class="navbar-brand" href="#">user center</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
... ... @@ -53,4 +53,4 @@
</div>
</div>
</body>
</html>
\ No newline at end of file
</html>
... ...