Commit f0b31a35 authored by dqjdda's avatar dqjdda
Browse files

security 优化,密码加密方式优化采用BCryptPasswordEncoder方式:SHA-256 +随机盐+密钥对密码进行加密

parent fe812f1c
package me.zhengjie.modules.security.service; package me.zhengjie.modules.security.service;
import me.zhengjie.modules.security.security.JwtUser; import me.zhengjie.modules.security.config.SecurityProperties;
import me.zhengjie.modules.security.security.OnlineUser; import me.zhengjie.modules.security.security.vo.JwtUser;
import me.zhengjie.modules.security.security.vo.OnlineUser;
import me.zhengjie.utils.EncryptUtils; import me.zhengjie.utils.EncryptUtils;
import me.zhengjie.utils.FileUtil; import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.PageUtil; import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.StringUtils; import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
...@@ -26,18 +26,20 @@ import java.util.concurrent.TimeUnit; ...@@ -26,18 +26,20 @@ import java.util.concurrent.TimeUnit;
@SuppressWarnings({"unchecked","all"}) @SuppressWarnings({"unchecked","all"})
public class OnlineUserService { public class OnlineUserService {
@Value("${jwt.expiration}") private final SecurityProperties properties;
private Long expiration;
@Value("${jwt.online}")
private String onlineKey;
private final RedisTemplate redisTemplate; private final RedisTemplate redisTemplate;
public OnlineUserService(RedisTemplate redisTemplate) { public OnlineUserService(SecurityProperties properties, RedisTemplate redisTemplate) {
this.properties = properties;
this.redisTemplate = redisTemplate; this.redisTemplate = redisTemplate;
} }
/**
* 保存在线用户信息
* @param jwtUser
* @param token
* @param request
*/
public void save(JwtUser jwtUser, String token, HttpServletRequest request){ public void save(JwtUser jwtUser, String token, HttpServletRequest request){
String job = jwtUser.getDept() + "/" + jwtUser.getJob(); String job = jwtUser.getDept() + "/" + jwtUser.getJob();
String ip = StringUtils.getIp(request); String ip = StringUtils.getIp(request);
...@@ -49,10 +51,16 @@ public class OnlineUserService { ...@@ -49,10 +51,16 @@ public class OnlineUserService {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
redisTemplate.opsForValue().set(onlineKey + token, onlineUser); redisTemplate.opsForValue().set(properties.getOnlineKey() + token, onlineUser);
redisTemplate.expire(onlineKey + token,expiration, TimeUnit.MILLISECONDS); redisTemplate.expire(properties.getOnlineKey() + token,properties.getTokenValidityInSeconds(), TimeUnit.MILLISECONDS);
} }
/**
* 查询全部数据
* @param filter
* @param pageable
* @return
*/
public Page<OnlineUser> getAll(String filter, Pageable pageable){ public Page<OnlineUser> getAll(String filter, Pageable pageable){
List<OnlineUser> onlineUsers = getAll(filter); List<OnlineUser> onlineUsers = getAll(filter);
return new PageImpl<OnlineUser>( return new PageImpl<OnlineUser>(
...@@ -61,8 +69,13 @@ public class OnlineUserService { ...@@ -61,8 +69,13 @@ public class OnlineUserService {
onlineUsers.size()); onlineUsers.size());
} }
/**
* 查询全部数据,不分页
* @param filter
* @return
*/
public List<OnlineUser> getAll(String filter){ public List<OnlineUser> getAll(String filter){
List<String> keys = new ArrayList<>(redisTemplate.keys(onlineKey + "*")); List<String> keys = new ArrayList<>(redisTemplate.keys(properties.getOnlineKey() + "*"));
Collections.reverse(keys); Collections.reverse(keys);
List<OnlineUser> onlineUsers = new ArrayList<>(); List<OnlineUser> onlineUsers = new ArrayList<>();
for (String key : keys) { for (String key : keys) {
...@@ -81,16 +94,31 @@ public class OnlineUserService { ...@@ -81,16 +94,31 @@ public class OnlineUserService {
return onlineUsers; return onlineUsers;
} }
/**
* 踢出用户
* @param val
* @throws Exception
*/
public void kickOut(String val) throws Exception { public void kickOut(String val) throws Exception {
String key = onlineKey + EncryptUtils.desDecrypt(val); String key = properties.getOnlineKey() + EncryptUtils.desDecrypt(val);
redisTemplate.delete(key); redisTemplate.delete(key);
} }
/**
* 退出登录
* @param token
*/
public void logout(String token) { public void logout(String token) {
String key = onlineKey + token; String key = properties.getOnlineKey() + token;
redisTemplate.delete(key); redisTemplate.delete(key);
} }
/**
* 导出
* @param all
* @param response
* @throws IOException
*/
public void download(List<OnlineUser> all, HttpServletResponse response) throws IOException { public void download(List<OnlineUser> all, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>(); List<Map<String, Object>> list = new ArrayList<>();
for (OnlineUser user : all) { for (OnlineUser user : all) {
...@@ -105,4 +133,13 @@ public class OnlineUserService { ...@@ -105,4 +133,13 @@ public class OnlineUserService {
} }
FileUtil.downloadExcel(list, response); FileUtil.downloadExcel(list, response);
} }
/**
* 查询用户
* @param key
* @return
*/
public OnlineUser getOne(String key) {
return (OnlineUser)redisTemplate.opsForValue().get(key);
}
} }
package me.zhengjie.modules.security.service; package me.zhengjie.modules.security.service;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.security.security.JwtUser; import me.zhengjie.modules.security.security.vo.JwtUser;
import me.zhengjie.modules.system.service.RoleService;
import me.zhengjie.modules.system.service.UserService; import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.*; import me.zhengjie.modules.system.service.dto.*;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
...@@ -15,31 +16,33 @@ import java.util.Optional; ...@@ -15,31 +16,33 @@ import java.util.Optional;
* @author Zheng Jie * @author Zheng Jie
* @date 2018-11-22 * @date 2018-11-22
*/ */
@Service @Service("userDetailsService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class JwtUserDetailsServiceImpl implements UserDetailsService { public class UserDetailsServiceImpl implements UserDetailsService {
private final UserService userService; private final UserService userService;
private final JwtPermissionServiceImpl permissionService; private final RoleService roleService;
public JwtUserDetailsServiceImpl(UserService userService, JwtPermissionServiceImpl permissionService) { public UserDetailsServiceImpl(UserService userService, RoleService roleService) {
this.userService = userService; this.userService = userService;
this.permissionService = permissionService; this.roleService = roleService;
} }
@Override @Override
public UserDetails loadUserByUsername(String username){ public UserDetails loadUserByUsername(String username){
UserDto user = userService.findByName(username); UserDto user = userService.findByName(username);
if (user == null) { if (user == null) {
throw new BadRequestException("账号不存在"); throw new BadRequestException("账号不存在");
} else { } else {
if (!user.getEnabled()) {
throw new BadRequestException("账号未激活");
}
return createJwtUser(user); return createJwtUser(user);
} }
} }
public UserDetails createJwtUser(UserDto user) { private UserDetails createJwtUser(UserDto user) {
return new JwtUser( return new JwtUser(
user.getId(), user.getId(),
user.getUsername(), user.getUsername(),
...@@ -49,7 +52,7 @@ public class JwtUserDetailsServiceImpl implements UserDetailsService { ...@@ -49,7 +52,7 @@ public class JwtUserDetailsServiceImpl implements UserDetailsService {
user.getPhone(), user.getPhone(),
Optional.ofNullable(user.getDept()).map(DeptSmallDto::getName).orElse(null), Optional.ofNullable(user.getDept()).map(DeptSmallDto::getName).orElse(null),
Optional.ofNullable(user.getJob()).map(JobSmallDto::getName).orElse(null), Optional.ofNullable(user.getJob()).map(JobSmallDto::getName).orElse(null),
permissionService.mapToGrantedAuthorities(user), roleService.mapToGrantedAuthorities(user),
user.getEnabled(), user.getEnabled(),
user.getCreateTime(), user.getCreateTime(),
user.getLastPasswordResetTime() user.getLastPasswordResetTime()
......
package me.zhengjie.modules.security.utils;
import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.DefaultClock;
import me.zhengjie.modules.security.security.JwtUser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
/**
* @author /
*/
@Component
public class JwtTokenUtil implements Serializable {
private static final long serialVersionUID = -3301605591108950415L;
private Clock clock = DefaultClock.INSTANCE;
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
@Value("${jwt.header}")
private String tokenHeader;
public String getUsernameFromToken(String token) {
return getClaimFromToken(token, Claims::getSubject);
}
private Date getIssuedAtDateFromToken(String token) {
return getClaimFromToken(token, Claims::getIssuedAt);
}
private Date getExpirationDateFromToken(String token) {
return getClaimFromToken(token, Claims::getExpiration);
}
private <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
final Claims claims = getAllClaimsFromToken(token);
return claimsResolver.apply(claims);
}
private Claims getAllClaimsFromToken(String token) {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}
private Boolean isTokenExpired(String token) {
final Date expiration = getExpirationDateFromToken(token);
return expiration.before(clock.now());
}
private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
return (lastPasswordReset != null && created.before(lastPasswordReset));
}
private Boolean ignoreTokenExpiration(String token) {
// here you specify tokens, for that the expiration is ignored
return false;
}
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>(16);
return doGenerateToken(claims, userDetails.getUsername());
}
private String doGenerateToken(Map<String, Object> claims, String subject) {
final Date createdDate = clock.now();
final Date expirationDate = calculateExpirationDate(createdDate);
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(createdDate)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) {
final Date created = getIssuedAtDateFromToken(token);
return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset)
&& (!isTokenExpired(token) || ignoreTokenExpiration(token));
}
public String refreshToken(String token) {
final Date createdDate = clock.now();
final Date expirationDate = calculateExpirationDate(createdDate);
final Claims claims = getAllClaimsFromToken(token);
claims.setIssuedAt(createdDate);
claims.setExpiration(expirationDate);
return Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public String getToken(HttpServletRequest request){
final String requestHeader = request.getHeader(tokenHeader);
String startsWith = "Bearer ";
if (requestHeader != null && requestHeader.startsWith(startsWith)) {
return requestHeader.substring(7);
}
return null;
}
public Boolean validateToken(String token, UserDetails userDetails) {
JwtUser user = (JwtUser) userDetails;
final Date created = getIssuedAtDateFromToken(token);
// final Date expiration = getExpirationDateFromToken(token);
// 如果token存在,且token创建日期 > 最后修改密码的日期 则代表token有效
return (!isTokenExpired(token)
&& !isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate())
);
}
private Date calculateExpirationDate(Date createdDate) {
return new Date(createdDate.getTime() + expiration);
}
}
...@@ -5,6 +5,7 @@ import org.springframework.data.jpa.repository.JpaRepository; ...@@ -5,6 +5,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* @author Zheng Jie * @author Zheng Jie
...@@ -36,9 +37,9 @@ public interface MenuRepository extends JpaRepository<Menu, Long>, JpaSpecificat ...@@ -36,9 +37,9 @@ public interface MenuRepository extends JpaRepository<Menu, Long>, JpaSpecificat
/** /**
* 根据角色ID与菜单类型查询菜单 * 根据角色ID与菜单类型查询菜单
* @param id roleID * @param roleIds roleIDs
* @param type 类型 * @param type 类型
* @return / * @return /
*/ */
LinkedHashSet<Menu> findByRoles_IdAndTypeIsNotInOrderBySortAsc(Long id, Integer type); LinkedHashSet<Menu> findByRoles_IdInAndTypeNotOrderBySortAsc(Set<Long> roleIds, int type);
} }
...@@ -7,8 +7,10 @@ import me.zhengjie.aop.log.Log; ...@@ -7,8 +7,10 @@ import me.zhengjie.aop.log.Log;
import me.zhengjie.modules.system.domain.Role; import me.zhengjie.modules.system.domain.Role;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.service.RoleService; import me.zhengjie.modules.system.service.RoleService;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.RoleQueryCriteria; import me.zhengjie.modules.system.service.dto.RoleQueryCriteria;
import me.zhengjie.modules.system.service.dto.RoleSmallDto; import me.zhengjie.modules.system.service.dto.RoleSmallDto;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.utils.SecurityUtils; import me.zhengjie.utils.SecurityUtils;
import me.zhengjie.utils.ThrowableUtil; import me.zhengjie.utils.ThrowableUtil;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
...@@ -36,11 +38,13 @@ import java.util.stream.Collectors; ...@@ -36,11 +38,13 @@ import java.util.stream.Collectors;
public class RoleController { public class RoleController {
private final RoleService roleService; private final RoleService roleService;
private final UserService userService;
private static final String ENTITY_NAME = "role"; private static final String ENTITY_NAME = "role";
public RoleController(RoleService roleService) { public RoleController(RoleService roleService, UserService userService) {
this.roleService = roleService; this.roleService = roleService;
this.userService = userService;
} }
@ApiOperation("获取单个role") @ApiOperation("获取单个role")
...@@ -76,7 +80,8 @@ public class RoleController { ...@@ -76,7 +80,8 @@ public class RoleController {
@ApiOperation("获取用户级别") @ApiOperation("获取用户级别")
@GetMapping(value = "/level") @GetMapping(value = "/level")
public ResponseEntity getLevel(){ public ResponseEntity getLevel(){
List<Integer> levels = roleService.findByUsersId(SecurityUtils.getUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()); UserDto user = userService.findByName(SecurityUtils.getUsername());
List<Integer> levels = roleService.findByUsersId(user.getId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList());
return new ResponseEntity<>(Dict.create().set("level", Collections.min(levels)),HttpStatus.OK); return new ResponseEntity<>(Dict.create().set("level", Collections.min(levels)),HttpStatus.OK);
} }
......
...@@ -11,6 +11,7 @@ import me.zhengjie.modules.system.domain.vo.UserPassVo; ...@@ -11,6 +11,7 @@ import me.zhengjie.modules.system.domain.vo.UserPassVo;
import me.zhengjie.modules.system.service.DeptService; import me.zhengjie.modules.system.service.DeptService;
import me.zhengjie.modules.system.service.RoleService; import me.zhengjie.modules.system.service.RoleService;
import me.zhengjie.modules.system.service.dto.RoleSmallDto; import me.zhengjie.modules.system.service.dto.RoleSmallDto;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.modules.system.service.dto.UserQueryCriteria; import me.zhengjie.modules.system.service.dto.UserQueryCriteria;
import me.zhengjie.service.VerificationCodeService; import me.zhengjie.service.VerificationCodeService;
import me.zhengjie.utils.*; import me.zhengjie.utils.*;
...@@ -20,6 +21,8 @@ import org.springframework.http.HttpStatus; ...@@ -20,6 +21,8 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
...@@ -39,17 +42,15 @@ import java.util.stream.Collectors; ...@@ -39,17 +42,15 @@ import java.util.stream.Collectors;
@RequestMapping("/api/users") @RequestMapping("/api/users")
public class UserController { public class UserController {
private final PasswordEncoder passwordEncoder;
private final UserService userService; private final UserService userService;
private final DataScope dataScope; private final DataScope dataScope;
private final DeptService deptService; private final DeptService deptService;
private final RoleService roleService; private final RoleService roleService;
private final VerificationCodeService verificationCodeService; private final VerificationCodeService verificationCodeService;
public UserController(UserService userService, DataScope dataScope, DeptService deptService, RoleService roleService, VerificationCodeService verificationCodeService) { public UserController(PasswordEncoder passwordEncoder, UserService userService, DataScope dataScope, DeptService deptService, RoleService roleService, VerificationCodeService verificationCodeService) {
this.passwordEncoder = passwordEncoder;
this.userService = userService; this.userService = userService;
this.dataScope = dataScope; this.dataScope = dataScope;
this.deptService = deptService; this.deptService = deptService;
...@@ -123,7 +124,8 @@ public class UserController { ...@@ -123,7 +124,8 @@ public class UserController {
@DeleteMapping(value = "/{id}") @DeleteMapping(value = "/{id}")
@PreAuthorize("@el.check('user:del')") @PreAuthorize("@el.check('user:del')")
public ResponseEntity delete(@PathVariable Long id){ public ResponseEntity delete(@PathVariable Long id){
Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); UserDto user = userService.findByName(SecurityUtils.getUsername());
Integer currentLevel = Collections.min(roleService.findByUsersId(user.getId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()));
Integer optLevel = Collections.min(roleService.findByUsersId(id).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); Integer optLevel = Collections.min(roleService.findByUsersId(id).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()));
if (currentLevel > optLevel) { if (currentLevel > optLevel) {
...@@ -135,15 +137,15 @@ public class UserController { ...@@ -135,15 +137,15 @@ public class UserController {
@ApiOperation("修改密码") @ApiOperation("修改密码")
@PostMapping(value = "/updatePass") @PostMapping(value = "/updatePass")
public ResponseEntity updatePass(@RequestBody UserPassVo user){ public ResponseEntity updatePass(@RequestBody UserPassVo passVo){
UserDetails userDetails = SecurityUtils.getUserDetails(); UserDto user = userService.findByName(SecurityUtils.getUsername());
if(!userDetails.getPassword().equals(EncryptUtils.encryptPassword(user.getOldPass()))){ if(!passwordEncoder.matches(passVo.getOldPass(), user.getPassword())){
throw new BadRequestException("修改失败,旧密码错误"); throw new BadRequestException("修改失败,旧密码错误");
} }
if(userDetails.getPassword().equals(EncryptUtils.encryptPassword(user.getNewPass()))){ if(passwordEncoder.matches(passVo.getNewPass(), user.getPassword())){
throw new BadRequestException("新密码不能与旧密码相同"); throw new BadRequestException("新密码不能与旧密码相同");
} }
userService.updatePass(userDetails.getUsername(),EncryptUtils.encryptPassword(user.getNewPass())); userService.updatePass(user.getUsername(),passwordEncoder.encode(passVo.getNewPass()));
return new ResponseEntity(HttpStatus.OK); return new ResponseEntity(HttpStatus.OK);
} }
...@@ -158,13 +160,13 @@ public class UserController { ...@@ -158,13 +160,13 @@ public class UserController {
@ApiOperation("修改邮箱") @ApiOperation("修改邮箱")
@PostMapping(value = "/updateEmail/{code}") @PostMapping(value = "/updateEmail/{code}")
public ResponseEntity updateEmail(@PathVariable String code,@RequestBody User user){ public ResponseEntity updateEmail(@PathVariable String code,@RequestBody User user){
UserDetails userDetails = SecurityUtils.getUserDetails(); UserDto userDto = userService.findByName(SecurityUtils.getUsername());
if(!userDetails.getPassword().equals(EncryptUtils.encryptPassword(user.getPassword()))){ if(!passwordEncoder.matches(user.getPassword(), userDto.getPassword())){
throw new BadRequestException("密码错误"); throw new BadRequestException("密码错误");
} }
VerificationCode verificationCode = new VerificationCode(code, ElAdminConstant.RESET_MAIL,"email",user.getEmail()); VerificationCode verificationCode = new VerificationCode(code, ElAdminConstant.RESET_MAIL,"email",user.getEmail());
verificationCodeService.validated(verificationCode); verificationCodeService.validated(verificationCode);
userService.updateEmail(userDetails.getUsername(),user.getEmail()); userService.updateEmail(userDto.getUsername(),user.getEmail());
return new ResponseEntity(HttpStatus.OK); return new ResponseEntity(HttpStatus.OK);
} }
...@@ -173,7 +175,8 @@ public class UserController { ...@@ -173,7 +175,8 @@ public class UserController {
* @param resources / * @param resources /
*/ */
private void checkLevel(User resources) { private void checkLevel(User resources) {
Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); UserDto user = userService.findByName(SecurityUtils.getUsername());
Integer currentLevel = Collections.min(roleService.findByUsersId(user.getId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()));
Integer optLevel = roleService.findByRoles(resources.getRoles()); Integer optLevel = roleService.findByRoles(resources.getRoles());
if (currentLevel > optLevel) { if (currentLevel > optLevel) {
throw new BadRequestException("角色权限不足"); throw new BadRequestException("角色权限不足");
......
...@@ -4,10 +4,14 @@ import me.zhengjie.modules.system.domain.Role; ...@@ -4,10 +4,14 @@ import me.zhengjie.modules.system.domain.Role;
import me.zhengjie.modules.system.service.dto.RoleDto; import me.zhengjie.modules.system.service.dto.RoleDto;
import me.zhengjie.modules.system.service.dto.RoleQueryCriteria; import me.zhengjie.modules.system.service.dto.RoleQueryCriteria;
import me.zhengjie.modules.system.service.dto.RoleSmallDto; import me.zhengjie.modules.system.service.dto.RoleSmallDto;
import me.zhengjie.modules.system.service.dto.UserDto;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.security.core.GrantedAuthority;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
...@@ -99,4 +103,11 @@ public interface RoleService { ...@@ -99,4 +103,11 @@ public interface RoleService {
* @throws IOException / * @throws IOException /
*/ */
void download(List<RoleDto> queryAll, HttpServletResponse response) throws IOException; void download(List<RoleDto> queryAll, HttpServletResponse response) throws IOException;
/**
* 获取用户权限信息
* @param user 用户信息
* @return 权限信息
*/
Collection<GrantedAuthority> mapToGrantedAuthorities(UserDto user);
} }
...@@ -66,11 +66,8 @@ public class MenuServiceImpl implements MenuService { ...@@ -66,11 +66,8 @@ public class MenuServiceImpl implements MenuService {
@Override @Override
public List<MenuDto> findByRoles(List<RoleSmallDto> roles) { public List<MenuDto> findByRoles(List<RoleSmallDto> roles) {
Set<Menu> menus = new LinkedHashSet<>(); Set<Long> roleIds = roles.stream().map(RoleSmallDto::getId).collect(Collectors.toSet());
for (RoleSmallDto role : roles) { LinkedHashSet<Menu> menus = menuRepository.findByRoles_IdInAndTypeNotOrderBySortAsc(roleIds, 2);
List<Menu> menus1 = new ArrayList<>(menuRepository.findByRoles_IdAndTypeIsNotInOrderBySortAsc(role.getId(), 2));
menus.addAll(menus1);
}
return menus.stream().map(menuMapper::toDto).collect(Collectors.toList()); return menus.stream().map(menuMapper::toDto).collect(Collectors.toList());
} }
......
package me.zhengjie.modules.system.service.impl; package me.zhengjie.modules.system.service.impl;
import me.zhengjie.modules.system.domain.Menu;
import me.zhengjie.modules.system.domain.Role; import me.zhengjie.modules.system.domain.Role;
import me.zhengjie.exception.EntityExistException; import me.zhengjie.exception.EntityExistException;
import me.zhengjie.modules.system.repository.RoleRepository; import me.zhengjie.modules.system.repository.RoleRepository;
...@@ -7,17 +8,17 @@ import me.zhengjie.modules.system.service.RoleService; ...@@ -7,17 +8,17 @@ import me.zhengjie.modules.system.service.RoleService;
import me.zhengjie.modules.system.service.dto.RoleDto; import me.zhengjie.modules.system.service.dto.RoleDto;
import me.zhengjie.modules.system.service.dto.RoleQueryCriteria; import me.zhengjie.modules.system.service.dto.RoleQueryCriteria;
import me.zhengjie.modules.system.service.dto.RoleSmallDto; import me.zhengjie.modules.system.service.dto.RoleSmallDto;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.modules.system.service.mapper.RoleMapper; import me.zhengjie.modules.system.service.mapper.RoleMapper;
import me.zhengjie.modules.system.service.mapper.RoleSmallMapper; import me.zhengjie.modules.system.service.mapper.RoleSmallMapper;
import me.zhengjie.utils.FileUtil; import me.zhengjie.utils.*;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;
import me.zhengjie.utils.ValidationUtil;
import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -144,6 +145,20 @@ public class RoleServiceImpl implements RoleService { ...@@ -144,6 +145,20 @@ public class RoleServiceImpl implements RoleService {
return Collections.min(roleDtos.stream().map(RoleDto::getLevel).collect(Collectors.toList())); return Collections.min(roleDtos.stream().map(RoleDto::getLevel).collect(Collectors.toList()));
} }
@Override
@Cacheable(key = "'loadPermissionByUser:' + #p0.username")
public Collection<GrantedAuthority> mapToGrantedAuthorities(UserDto user) {
Set<Role> roles = roleRepository.findByUsers_Id(user.getId());
Set<String> permissions = roles.stream().filter(role -> StringUtils.isNotBlank(role.getPermission())).map(Role::getPermission).collect(Collectors.toSet());
permissions.addAll(
roles.stream().flatMap(role -> role.getMenus().stream())
.filter(menu -> StringUtils.isNotBlank(menu.getPermission()))
.map(Menu::getPermission).collect(Collectors.toSet())
);
return permissions.stream().map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
@Override @Override
public void download(List<RoleDto> roles, HttpServletResponse response) throws IOException { public void download(List<RoleDto> roles, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>(); List<Map<String, Object>> list = new ArrayList<>();
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
spring: spring:
datasource: datasource:
druid: druid:
type: com.alibaba.druid.pool.DruidDataSource db-type: com.alibaba.druid.pool.DruidDataSource
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
url: jdbc:log4jdbc:mysql://localhost:3306/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false url: jdbc:log4jdbc:mysql://localhost:3306/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
username: root username: root
...@@ -44,13 +44,18 @@ spring: ...@@ -44,13 +44,18 @@ spring:
#jwt #jwt
jwt: jwt:
header: Authorization header: Authorization
secret: mySecret # 令牌前缀,主要最后留个空格
# token 过期时间/毫秒,6小时 1小时 = 3600000 毫秒 token-start-with: Bearer
expiration: 21600000 # 必须使用最少88位的Base64对该令牌进行编码
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
# 令牌过期时间 此处单位/秒 ,默认4小时
token-validity-in-seconds: 14400000
# 记住我模式下的令牌过期时间 此处单位/毫秒 ,默认1天
token-validity-in-seconds-for-remember-me: 86400000
# 在线用户key # 在线用户key
online: online-token online-key: online-token
# 验证码 # 验证码
codeKey: code-key code-key: code-key
#是否允许生成代码,生产环境设置为false #是否允许生成代码,生产环境设置为false
generator: generator:
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
spring: spring:
datasource: datasource:
druid: druid:
type: com.alibaba.druid.pool.DruidDataSource db-type: com.alibaba.druid.pool.DruidDataSource
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
url: jdbc:log4jdbc:mysql://localhost:3306/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false url: jdbc:log4jdbc:mysql://localhost:3306/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
username: root username: root
...@@ -46,13 +46,18 @@ spring: ...@@ -46,13 +46,18 @@ spring:
#jwt #jwt
jwt: jwt:
header: Authorization header: Authorization
secret: mySecret # 令牌前缀,主要最后留个空格
# token 过期时间 2个小时 token-start-with: Bearer
expiration: 7200000 # 必须使用最少88位的Base64对该令牌进行编码
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
# 令牌过期时间 此处单位/秒 ,默认4小时
token-validity-in-seconds: 14400000
# 记住我模式下的令牌过期时间 此处单位/毫秒 ,默认1天
token-validity-in-seconds-for-remember-me: 86400000
# 在线用户key # 在线用户key
online: online-token online-key: online-token
# 验证码 # 验证码
codeKey: code-key code-key: code-key
#是否允许生成代码,生产环境设置为false #是否允许生成代码,生产环境设置为false
generator: generator:
......
Supports Markdown
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