!4 token重构

Merge pull request !4 from zwzw1219/token
master
zwzw1219 2017-11-30 10:23:30 +08:00
parent 28e04154de
commit 5b3724e252
11 changed files with 73 additions and 102 deletions

View File

@ -2,7 +2,6 @@ package com.boot.security.server.dao;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Insert;
@ -49,6 +48,4 @@ public interface RoleDao {
@Delete("delete from sys_role_user where roleId = #{roleId}") @Delete("delete from sys_role_user where roleId = #{roleId}")
int deleteRoleUser(Long roleId); int deleteRoleUser(Long roleId);
@Select("select ru.userId from sys_role r inner join sys_role_user ru on r.id = ru.roleId where ru.roleId = #{roleId}")
Set<Long> listUserIds(Long roleId);
} }

View File

@ -19,6 +19,10 @@ public class LoginUser extends SysUser implements UserDetails {
private List<Permission> permissions; private List<Permission> permissions;
private String token; private String token;
/** 登陆时间戳(毫秒) */
private Long loginTime;
/** 过期时间戳 */
private Long expireTime;
public List<Permission> getPermissions() { public List<Permission> getPermissions() {
return permissions; return permissions;
@ -71,4 +75,20 @@ public class LoginUser extends SysUser implements UserDetails {
return true; return true;
} }
public Long getLoginTime() {
return loginTime;
}
public void setLoginTime(Long loginTime) {
this.loginTime = loginTime;
}
public Long getExpireTime() {
return expireTime;
}
public void setExpireTime(Long expireTime) {
this.expireTime = expireTime;
}
} }

View File

@ -14,10 +14,13 @@ public class Token implements Serializable {
private static final long serialVersionUID = 6314027741784310221L; private static final long serialVersionUID = 6314027741784310221L;
private String token; private String token;
/** 登陆时间戳(毫秒) */
private Long loginTime;
public Token(String token) { public Token(String token, Long loginTime) {
super(); super();
this.token = token; this.token = token;
this.loginTime = loginTime;
} }
public String getToken() { public String getToken() {
@ -28,4 +31,12 @@ public class Token implements Serializable {
this.token = token; this.token = token;
} }
public Long getLoginTime() {
return loginTime;
}
public void setLoginTime(Long loginTime) {
this.loginTime = loginTime;
}
} }

View File

@ -11,6 +11,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
@ -31,6 +32,9 @@ public class TokenFilter extends OncePerRequestFilter {
@Autowired @Autowired
private TokenService tokenService; private TokenService tokenService;
@Autowired
private UserDetailsService userDetailsService;
private static final Long MINUTES_10 = 10 * 60 * 1000L;
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
@ -39,6 +43,7 @@ public class TokenFilter extends OncePerRequestFilter {
if (StringUtils.isNotBlank(token)) { if (StringUtils.isNotBlank(token)) {
LoginUser loginUser = tokenService.getLoginUser(token); LoginUser loginUser = tokenService.getLoginUser(token);
if (loginUser != null) { if (loginUser != null) {
loginUser = checkLoginTime(loginUser);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(loginUser, UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(loginUser,
null, loginUser.getAuthorities()); null, loginUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication); SecurityContextHolder.getContext().setAuthentication(authentication);
@ -48,6 +53,25 @@ public class TokenFilter extends OncePerRequestFilter {
filterChain.doFilter(request, response); filterChain.doFilter(request, response);
} }
/**
* <br>
* 10
*
* @param loginUser
* @return
*/
private LoginUser checkLoginTime(LoginUser loginUser) {
long expireTime = loginUser.getExpireTime();
long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MINUTES_10) {
String token = loginUser.getToken();
loginUser = (LoginUser) userDetailsService.loadUserByUsername(loginUser.getUsername());
loginUser.setToken(token);
tokenService.refresh(loginUser);
}
return loginUser;
}
/** /**
* headertoken * headertoken
* *

View File

@ -14,12 +14,10 @@ public interface TokenService {
Token saveToken(LoginUser loginUser); Token saveToken(LoginUser loginUser);
void updateLoginUser(LoginUser loginUser); void refresh(LoginUser loginUser);
LoginUser getLoginUser(String token); LoginUser getLoginUser(String token);
boolean deleteToken(String token); boolean deleteToken(String token);
String getTokenByUserId(Long userId);
} }

View File

@ -1,7 +1,5 @@
package com.boot.security.server.service; package com.boot.security.server.service;
import java.util.Set;
import com.boot.security.server.dto.UserDto; import com.boot.security.server.dto.UserDto;
import com.boot.security.server.model.SysUser; import com.boot.security.server.model.SysUser;
@ -15,5 +13,4 @@ public interface UserService {
void changePassword(String username, String oldPassword, String newPassword); void changePassword(String username, String oldPassword, String newPassword);
void updateLoginUserCache(Set<Long> userIds);
} }

View File

@ -1,7 +1,5 @@
package com.boot.security.server.service.impl; package com.boot.security.server.service.impl;
import java.util.Set;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -11,7 +9,6 @@ import org.springframework.transaction.annotation.Transactional;
import com.boot.security.server.dao.PermissionDao; import com.boot.security.server.dao.PermissionDao;
import com.boot.security.server.model.Permission; import com.boot.security.server.model.Permission;
import com.boot.security.server.service.PermissionService; import com.boot.security.server.service.PermissionService;
import com.boot.security.server.service.UserService;
@Service @Service
public class PermissionServiceImpl implements PermissionService { public class PermissionServiceImpl implements PermissionService {
@ -20,8 +17,6 @@ public class PermissionServiceImpl implements PermissionService {
@Autowired @Autowired
private PermissionDao permissionDao; private PermissionDao permissionDao;
@Autowired
private UserService userService;
@Override @Override
public void save(Permission permission) { public void save(Permission permission) {
@ -32,25 +27,17 @@ public class PermissionServiceImpl implements PermissionService {
@Override @Override
public void update(Permission permission) { public void update(Permission permission) {
Set<Long> userIds = listUserIds(permission.getId());
permissionDao.update(permission); permissionDao.update(permission);
userService.updateLoginUserCache(userIds);
} }
@Override @Override
@Transactional @Transactional
public void delete(Long id) { public void delete(Long id) {
Set<Long> userIds = listUserIds(id);
permissionDao.deleteRolePermission(id); permissionDao.deleteRolePermission(id);
permissionDao.delete(id); permissionDao.delete(id);
permissionDao.deleteByParentId(id); permissionDao.deleteByParentId(id);
log.debug("删除菜单id:{}", id); log.debug("删除菜单id:{}", id);
userService.updateLoginUserCache(userIds);
}
private Set<Long> listUserIds(Long permissionId) {
return permissionDao.listUserIds(permissionId);
} }
} }

View File

@ -1,7 +1,6 @@
package com.boot.security.server.service.impl; package com.boot.security.server.service.impl;
import java.util.List; import java.util.List;
import java.util.Set;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -14,7 +13,6 @@ import com.boot.security.server.dao.RoleDao;
import com.boot.security.server.dto.RoleDto; import com.boot.security.server.dto.RoleDto;
import com.boot.security.server.model.Role; import com.boot.security.server.model.Role;
import com.boot.security.server.service.RoleService; import com.boot.security.server.service.RoleService;
import com.boot.security.server.service.UserService;
@Service @Service
public class RoleServiceImpl implements RoleService { public class RoleServiceImpl implements RoleService {
@ -23,8 +21,6 @@ public class RoleServiceImpl implements RoleService {
@Autowired @Autowired
private RoleDao roleDao; private RoleDao roleDao;
@Autowired
private UserService userService;
@Override @Override
@Transactional @Transactional
@ -60,31 +56,22 @@ public class RoleServiceImpl implements RoleService {
} }
roleDao.update(role); roleDao.update(role);
Set<Long> userIds = listUserIds(role.getId());
roleDao.deleteRolePermission(role.getId()); roleDao.deleteRolePermission(role.getId());
if (!CollectionUtils.isEmpty(permissionIds)) { if (!CollectionUtils.isEmpty(permissionIds)) {
roleDao.saveRolePermission(role.getId(), permissionIds); roleDao.saveRolePermission(role.getId(), permissionIds);
} }
log.debug("修改角色{}", role.getName()); log.debug("修改角色{}", role.getName());
userService.updateLoginUserCache(userIds);
} }
@Override @Override
@Transactional @Transactional
public void deleteRole(Long id) { public void deleteRole(Long id) {
Set<Long> userIds = listUserIds(id);
roleDao.deleteRolePermission(id); roleDao.deleteRolePermission(id);
roleDao.deleteRoleUser(id); roleDao.deleteRoleUser(id);
roleDao.delete(id); roleDao.delete(id);
log.debug("删除角色id:{}", id); log.debug("删除角色id:{}", id);
userService.updateLoginUserCache(userIds);
}
private Set<Long> listUserIds(Long roleId) {
return roleDao.listUserIds(roleId);
} }
} }

View File

@ -7,7 +7,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.boot.security.server.dto.LoginUser; import com.boot.security.server.dto.LoginUser;
import com.boot.security.server.dto.Token; import com.boot.security.server.dto.Token;
@ -25,32 +24,33 @@ public class TokenServiceImpl implements TokenService {
@Autowired @Autowired
private RedisTemplate<String, LoginUser> redisTemplate; private RedisTemplate<String, LoginUser> redisTemplate;
@Autowired @Autowired
private RedisTemplate<String, String> idTokenRedisTemplate;
@Autowired
private SysLogService logService; private SysLogService logService;
@Override @Override
public Token saveToken(LoginUser loginUser) { public Token saveToken(LoginUser loginUser) {
String token = getTokenByUserId(loginUser.getId()); String token = UUID.randomUUID().toString();
if (StringUtils.isEmpty(token)) {
token = UUID.randomUUID().toString();
}
loginUser.setToken(token); loginUser.setToken(token);
updateLoginUser(loginUser); cacheLoginUser(loginUser);
// 登陆日志
logService.save(loginUser.getId(), "登陆", true, null); logService.save(loginUser.getId(), "登陆", true, null);
return new Token(token); return new Token(token, loginUser.getLoginTime());
}
private void cacheLoginUser(LoginUser loginUser) {
loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireSeconds * 1000);
// 缓存
redisTemplate.boundValueOps(getTokenKey(loginUser.getToken())).set(loginUser, expireSeconds, TimeUnit.SECONDS);
} }
/** /**
* *
*/ */
@Override @Override
public void updateLoginUser(LoginUser loginUser) { public void refresh(LoginUser loginUser) {
redisTemplate.boundValueOps(getTokenKey(loginUser.getToken())).set(loginUser, expireSeconds, TimeUnit.SECONDS); cacheLoginUser(loginUser);
idTokenRedisTemplate.boundValueOps(getUserIdKey(loginUser.getId())).set(loginUser.getToken(), expireSeconds,
TimeUnit.SECONDS);
} }
@Override @Override
@ -64,7 +64,7 @@ public class TokenServiceImpl implements TokenService {
LoginUser loginUser = redisTemplate.opsForValue().get(key); LoginUser loginUser = redisTemplate.opsForValue().get(key);
if (loginUser != null) { if (loginUser != null) {
redisTemplate.delete(key); redisTemplate.delete(key);
redisTemplate.delete(getUserIdKey(loginUser.getId())); // 退出日志
logService.save(loginUser.getId(), "退出", true, null); logService.save(loginUser.getId(), "退出", true, null);
return true; return true;
@ -77,16 +77,4 @@ public class TokenServiceImpl implements TokenService {
return "tokens:" + token; return "tokens:" + token;
} }
private String getUserIdKey(Long userId) {
return "users:id:" + userId;
}
/**
* userIdtoken
*/
@Override
public String getTokenByUserId(Long userId) {
return idTokenRedisTemplate.opsForValue().get(getUserIdKey(userId));
}
} }

View File

@ -1,28 +1,20 @@
package com.boot.security.server.service.impl; package com.boot.security.server.service.impl;
import java.util.List; import java.util.List;
import java.util.Set;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import com.boot.security.server.dao.PermissionDao;
import com.boot.security.server.dao.UserDao; import com.boot.security.server.dao.UserDao;
import com.boot.security.server.dto.LoginUser;
import com.boot.security.server.dto.UserDto; import com.boot.security.server.dto.UserDto;
import com.boot.security.server.model.Permission;
import com.boot.security.server.model.SysUser; import com.boot.security.server.model.SysUser;
import com.boot.security.server.model.SysUser.Status; import com.boot.security.server.model.SysUser.Status;
import com.boot.security.server.service.TokenService;
import com.boot.security.server.service.UserService; import com.boot.security.server.service.UserService;
import com.google.common.collect.Sets;
@Service @Service
public class UserServiceImpl implements UserService { public class UserServiceImpl implements UserService {
@ -33,10 +25,6 @@ public class UserServiceImpl implements UserService {
private UserDao userDao; private UserDao userDao;
@Autowired @Autowired
private BCryptPasswordEncoder passwordEncoder; private BCryptPasswordEncoder passwordEncoder;
@Autowired
private PermissionDao permissionDao;
@Autowired
private TokenService tokenService;
@Override @Override
@Transactional @Transactional
@ -86,34 +74,8 @@ public class UserServiceImpl implements UserService {
public SysUser updateUser(UserDto userDto) { public SysUser updateUser(UserDto userDto) {
userDao.update(userDto); userDao.update(userDto);
saveUserRoles(userDto.getId(), userDto.getRoleIds()); saveUserRoles(userDto.getId(), userDto.getRoleIds());
updateLoginUserCache(Sets.newHashSet(userDto.getId()));
return userDto; return userDto;
} }
/**
*
*/
@Override
public void updateLoginUserCache(Set<Long> userIds) {
if (CollectionUtils.isEmpty(userIds)) {
return;
}
userIds.parallelStream().forEach(userId -> {
String token = tokenService.getTokenByUserId(userId);
if (!StringUtils.isEmpty(token)) {
SysUser sysUser = userDao.getById(userId);
LoginUser loginUser = new LoginUser();
loginUser.setToken(token);
BeanUtils.copyProperties(sysUser, loginUser);
List<Permission> permissions = permissionDao.listByUserId(sysUser.getId());
loginUser.setPermissions(permissions);
tokenService.updateLoginUser(loginUser);
}
});
}
} }

View File

@ -56,6 +56,6 @@ log:
maxsize: 30MB maxsize: 30MB
token: token:
expire: expire:
seconds: 86400 seconds: 7200
server: server:
port: 8080 port: 8080