1. 簡介
Spring Security是一個功能強大且易於擴展的安全框架,主要用於為Java程序提供用戶認證(Authentication)和用戶授權(Authorization)功能。
本文將之前博客 SpringBoot2.x集成Quartz實現定時任務管理(持久化到數據庫) 改為使用Spring Security
進行統一的認證和授權。除了將登錄使用Spring Security
管理之外,還增加了角色管理、權限管理等菜單,並對系統的權限進行更加細顆粒度的管理和鑒權,使得系統更加安全,便於和其他系統單點集成。
2. Spring Security相關博客(推薦)
SpringBoot + SpringSecurity + Mybatis-Plus + JWT實現分布式系統認證和授權
SpringBoot + SpringSecurity + Mybatis-Plus + JWT + Redis 實現分布式系統認證和授權(刷新Token和Token黑名單)
3. 前期回顧(時間升序)
SpringBoot + Layui +Mybatis-plus實現簡單后台管理系統(內置安全過濾器)
SpringBoot基於JustAuth實現第三方授權登錄
SpringBoot + Layui + JustAuth +Mybatis-plus實現可第三方登錄的簡單后台管理系統
SpringBoot2.x集成Quartz實現定時任務管理(持久化到數據庫)
4. 初始化數據庫
在之前數據庫上增加四張表,分別為:
-- ----------------------------
-- Table structure for t_sys_auth
-- ----------------------------
DROP TABLE IF EXISTS `t_sys_auth`;
CREATE TABLE `t_sys_auth` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`auth_name` varchar(50) NOT NULL COMMENT '權限名稱',
`permission` varchar(200) NULL DEFAULT NULL COMMENT '權限標識',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB COMMENT = '系統權限';
-- ----------------------------
-- Table structure for t_sys_role
-- ----------------------------
DROP TABLE IF EXISTS `t_sys_role`;
CREATE TABLE `t_sys_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`role_name` varchar(50) NULL DEFAULT NULL COMMENT '角色名稱',
`role_code` varchar(50) NOT NULL COMMENT '角色編碼',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB COMMENT = '系統角色';
-- ----------------------------
-- Table structure for t_sys_role_auth
-- ----------------------------
DROP TABLE IF EXISTS `t_sys_role_auth`;
CREATE TABLE `t_sys_role_auth` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`role_id` bigint(20) NULL DEFAULT NULL COMMENT '角色ID',
`auth_id` bigint(20) NULL DEFAULT NULL COMMENT '權限ID',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB COMMENT = '角色權限關系';
-- ----------------------------
-- Table structure for t_sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `t_sys_user_role`;
CREATE TABLE `t_sys_user_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`user_id` bigint(20) NULL DEFAULT NULL COMMENT '用戶ID',
`role_id` bigint(20) NULL DEFAULT NULL COMMENT '角色ID',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB COMMENT = '用戶角色關系';
完整的初始化數據庫腳本在項目源碼的db文件夾
5. 代碼迭代
- 修改pom.xml,增加Spring Security依賴
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.c3stones</groupId>
<artifactId>spring-security-quartz-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-security-quartz-demo</name>
<description>Spring Security Quartz Demo</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.8.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 增加剛剛添加的四張表對應的實體、Mapper、Service及Service實現類
以表t_sys_role
為例,增加系統角色實體等類,其他請參考系統角色自行添加。
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 系統角色
*
* @author CL
*
*/
@Data
@TableName("t_sys_role")
@EqualsAndHashCode(callSuper = false)
public class Role extends Model<Role> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 角色名稱
*/
private String roleName;
/**
* 角色編碼
*/
private String roleCode;
}
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.c3stones.sys.entity.Role;
/**
* 系統角色Mapper
*
* @author CL
*
*/
@Mapper
public interface RoleMapper extends BaseMapper<Role> {
}
import java.util.List;
import javax.validation.constraints.NotNull;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.c3stones.sys.entity.Role;
import com.c3stones.sys.entity.User;
import com.c3stones.sys.entity.UserRole;
/**
* 系統角色Service
*
* @author CL
*
*/
public interface RoleService extends IService<Role> {
}
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.ListUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.c3stones.sys.entity.Role;
import com.c3stones.sys.entity.User;
import com.c3stones.sys.entity.UserRole;
import com.c3stones.sys.mapper.RoleMapper;
import com.c3stones.sys.mapper.UserMapper;
import com.c3stones.sys.mapper.UserRoleMapper;
import com.c3stones.sys.service.RoleService;
import cn.hutool.core.util.StrUtil;
/**
* 系統角色Service實現
*
* @author CL
*
*/
@Service
public class RoleSerivceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
}
- 增加用戶詳情實體,用於系統上下文之間傳遞用戶信息
import java.io.Serializable;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import com.c3stones.sys.entity.User;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 系統用戶詳情
*
* @author CL
*
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class UserDetails extends User
implements org.springframework.security.core.userdetails.UserDetails, Serializable {
private static final long serialVersionUID = 1L;
/**
* 用戶角色
*/
private Collection<GrantedAuthority> authorities;
/**
* 賬號是否過期
*/
private boolean isAccountNonExpired = false;
/**
* 賬號是否鎖定
*/
private boolean isAccountNonLocked = false;
/**
* 證書是否過期
*/
private boolean isCredentialsNonExpired = false;
/**
* 賬號是否有效
*/
private boolean isEnabled = true;
/**
* 獲得用戶權限
*/
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
/**
* 判斷賬號是否過期
*/
@Override
public boolean isAccountNonExpired() {
return isAccountNonExpired;
}
/**
* 判斷賬號是否鎖定
*/
@Override
public boolean isAccountNonLocked() {
return isAccountNonLocked;
}
/**
* 判斷證書是否過期
*/
@Override
public boolean isCredentialsNonExpired() {
return isCredentialsNonExpired;
}
/**
* 判斷賬號是否有效
*/
@Override
public boolean isEnabled() {
return isEnabled;
}
}
- 增加用戶詳情Service,用於系統登錄認證和獲取用戶角色等信息
需要添加的基礎的用戶、角色、權限等方法(如查詢用戶角色、角色權限等方法),請下載項目源碼查看。
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.c3stones.security.entity.UserDetails;
import com.c3stones.sys.entity.Role;
import com.c3stones.sys.entity.User;
import com.c3stones.sys.service.RoleService;
import com.c3stones.sys.service.UserService;
/**
* 用戶登錄Service
*
* @author CL
*
*/
@Service
public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
/**
* 根據用戶名查用戶信息
*
* @param username 用戶名稱
* @return 用戶詳細信息
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", username);
User user = userService.getOne(queryWrapper);
if (user != null) {
UserDetails userDetails = new UserDetails();
BeanUtils.copyProperties(user, userDetails);
// 用戶角色
Set<GrantedAuthority> authorities = new HashSet<>();
// 查詢用戶角色
List<Role> roleList = roleService.findByUserId(userDetails.getId());
roleList.forEach(role -> {
authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleCode()));
});
userDetails.setAuthorities(authorities);
return userDetails;
}
return null;
}
}
- 增加用戶登錄驗證處理類
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import com.c3stones.security.entity.UserDetails;
import com.c3stones.security.service.UserDetailsService;
import cn.hutool.core.util.StrUtil;
/**
* 用戶登錄驗證處理類
*
* @author CL
*
*/
@Component
public class UserAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserDetailsService userDetailsService;
/**
* 身份驗證
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// 獲取用戶名
String username = (String) authentication.getPrincipal();
// 獲取密碼
String password = (String) authentication.getCredentials();
UserDetails userDetails = (UserDetails) userDetailsService.loadUserByUsername(username);
if (userDetails == null) {
throw new UsernameNotFoundException("用戶名不存在");
}
if (!StrUtil.equals(username, userDetails.getUsername())
|| !new BCryptPasswordEncoder().matches(password, userDetails.getPassword())) {
throw new BadCredentialsException("用戶名或密碼錯誤");
}
return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
}
/**
* 支持指定的身份驗證
*/
@Override
public boolean supports(Class<?> authentication) {
return true;
}
}
- 增加用戶權限注解處理類
import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.c3stones.security.entity.UserDetails;
import com.c3stones.sys.entity.Auth;
import com.c3stones.sys.service.AuthService;
/**
* 用戶權限注解處理類
*
* @author CL
*
*/
@Component
public class UserPermissionEvaluator implements PermissionEvaluator {
@Autowired
private AuthService authService;
/**
* 判斷是否擁有權限
*
* @param authentication 用戶身份
* @param targetUrl 目標路徑
* @param permission 路徑權限
*
* @return 是否擁有權限
*/
@Override
public boolean hasPermission(Authentication authentication, Object targetUrl, Object permission) {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
// 用戶權限
Set<String> permissions = new HashSet<String>();
// 查詢用戶權限
List<Auth> authList = authService.findByUserId(userDetails.getId());
authList.forEach(auth -> {
permissions.add(auth.getPermission());
});
// 判斷是否擁有權限
if (permissions.stream().filter(p -> (permission.toString().startsWith(p))).count() > 0) {
return true;
}
return false;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
Object permission) {
return false;
}
}
- 增加無權限處理類
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
/**
* 無權限處理類
*
* @author CL
*
*/
@Component
public class UserAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException {
response.sendError(403);
}
}
- 增加登錄失敗處理類
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import com.c3stones.common.vo.Response;
/**
* 登錄失敗處理類
*
* @author CL
*
*/
@Component
public class UserLoginFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException {
Response.responseJson(response, Response.error(500, "登錄失敗", exception.getMessage()));
}
}
- 增加登錄成功處理類
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import com.c3stones.common.vo.Response;
/**
* 登錄成功處理類
*
* @author CL
*
*/
@Component
public class UserLoginSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException {
Response.responseJson(response, Response.success("登錄成功"));
}
}
- 增加登出成功處理類
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
/**
* 登出成功處理類
*
* @author CL
*
*/
@Component
public class UserLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
SecurityContextHolder.clearContext();
response.sendRedirect("login");
}
}
- 增加未登錄處理類
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
/**
* 未登錄處理類
*
* @author CL
*
*/
@Component
public class UserNotLoginHandler implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(403);
}
}
- 增加系統安全核心配置,取代之前的系統配置類、登錄攔截器和登錄相關認證邏輯
本系統不是前后端分離系統,因此還是通過Session進行管理。
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
import com.c3stones.security.UserAuthenticationProvider;
import com.c3stones.security.UserPermissionEvaluator;
import com.c3stones.security.handle.UserAccessDeniedHandler;
import com.c3stones.security.handle.UserLoginFailureHandler;
import com.c3stones.security.handle.UserLoginSuccessHandler;
import com.c3stones.security.handle.UserLogoutSuccessHandler;
import com.c3stones.security.handle.UserNotLoginHandler;
import lombok.Setter;
/**
* 系統安全核心配置
*
* @author CL
*
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ConfigurationProperties(prefix = "security.web")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 忽略的URL
*/
@Setter
private List<String> excludes;
/**
* 無權限處理類
*/
@Autowired
private UserAccessDeniedHandler userAccessDeniedHandler;
/**
* 用戶未登錄處理類
*/
@Autowired
private UserNotLoginHandler userNotLoginHandler;
/**
* 用戶登錄成功處理類
*/
@Autowired
private UserLoginSuccessHandler userLoginSuccessHandler;
/**
* 用戶登錄失敗處理類
*/
@Autowired
private UserLoginFailureHandler userLoginFailureHandler;
/**
* 用戶登出成功處理類
*/
@Autowired
private UserLogoutSuccessHandler userLogoutSuccessHandler;
/**
* 用戶登錄驗證
*/
@Autowired
private UserAuthenticationProvider userAuthenticationProvider;
/**
* 用戶權限注解
*/
@Autowired
private UserPermissionEvaluator userPermissionEvaluator;
/**
* 加密方式
*
* @return
*/
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 注入自定義PermissionEvaluator
*
* @return
*/
@Bean
public DefaultWebSecurityExpressionHandler userSecurityExpressionHandler() {
DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
handler.setPermissionEvaluator(userPermissionEvaluator);
return handler;
}
/**
* 用戶登錄驗證
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(userAuthenticationProvider);
}
/**
* 安全權限配置
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().sameOrigin() // 可以相同域名頁面的frame中展示
.and().authorizeRequests() // 權限配置
.antMatchers(excludes.toArray(new String[excludes.size()])).permitAll()// 獲取白名單(不進行權限驗證)
.anyRequest().authenticated() // 其他的需要登陸后才能訪問
.and().httpBasic().authenticationEntryPoint(userNotLoginHandler) // 配置未登錄處理類
.and().formLogin().loginPage("/login").loginProcessingUrl("/login") // 配置登錄URL
.successHandler(userLoginSuccessHandler) // 配置登錄成功處理類
.failureHandler(userLoginFailureHandler) // 配置登錄失敗處理類
.and().logout().logoutUrl("/logout")// 配置登出地址
.logoutSuccessHandler(userLogoutSuccessHandler) // 配置用戶登出處理類
.and().exceptionHandling().accessDeniedHandler(userAccessDeniedHandler)// 配置沒有權限處理類
.and().csrf().disable(); // 禁用跨站請求偽造防護
}
}
- 其他角色、權限添加、刪除、綁定等功能,請下載項目源碼,啟動項目查看
- 給系統Controller添加權限注解(以UserController為例)
import javax.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.c3stones.common.vo.Response;
import com.c3stones.sys.entity.User;
import com.c3stones.sys.service.UserService;
import cn.hutool.crypto.digest.BCrypt;
/**
* 系統用戶Controller
*
* @author CL
*
*/
@Controller
@RequestMapping(value = "user")
public class UserController {
@Autowired
private UserService userService;
/**
* 查詢列表
*
* @return
*/
@PreAuthorize(value = "hasPermission('/user/list', 'sys:user:view')")
@RequestMapping(value = "list")
public String list() {
return "pages/sys/userList";
}
/**
* 查詢列表數據
*
* @param user 系統用戶
* @param current 當前頁
* @param size 每頁顯示條數
* @return
*/
@PreAuthorize(value = "hasPermission('/user/listData', 'sys:user:view')")
@RequestMapping(value = "listData")
@ResponseBody
public Response<Page<User>> listData(User user, @RequestParam(name = "page") long current,
@RequestParam(name = "limit") long size) {
Page<User> page = userService.listData(user, current, size);
return Response.success(page);
}
/**
* 新增
*
* @return
*/
@PreAuthorize(value = "hasPermission('/user/add', 'sys:user:edit')")
@RequestMapping(value = "add")
public String add() {
return "pages/sys/userAdd";
}
/**
* 檢驗用戶名稱是否唯一
*
* @param userName 用戶名稱
* @return
*/
@PreAuthorize(value = "hasPermission('/user/check', 'sys:user:edit')")
@RequestMapping(value = "check")
@ResponseBody
public Response<Boolean> checkUserName(@NotNull String username) {
Boolean checkResult = userService.checkUserName(username);
return Response.success(checkResult);
}
/**
* 保存
*
* @param user 系統用戶
* @return
*/
@PreAuthorize(value = "hasPermission('/user/save', 'sys:user:edit')")
@RequestMapping(value = "save")
@ResponseBody
public Response<Boolean> save(User user) {
user.setPassword(BCrypt.hashpw(user.getPassword()));
boolean result = userService.save(user);
return Response.success(result);
}
/**
* 修改
*
* @param user 系統用戶
* @param model
* @return
*/
@PreAuthorize(value = "hasPermission('/user/edit', 'sys:user:edit')")
@RequestMapping(value = "edit")
public String edit(User user, Model model) {
Assert.notNull(user.getId(), "ID不能為空");
model.addAttribute("user", userService.getById(user.getId()));
return "pages/sys/userEdit";
}
/**
* 更新
*
* @param user 系統用戶
* @return
*/
@PreAuthorize(value = "hasPermission('/user/update', 'sys:user:edit')")
@RequestMapping(value = "update")
@ResponseBody
public Response<Boolean> update(User user) {
Assert.notNull(user.getId(), "ID不能為空");
boolean result = userService.updateById(user);
return Response.success(result);
}
/**
* 刪除
*
* @param user 系統用戶
* @return
*/
@PreAuthorize(value = "hasPermission('/user/delete', 'sys:user:edit')")
@RequestMapping(value = "delete")
@ResponseBody
public Response<Boolean> delete(User user) {
Assert.notNull(user.getId(), "ID不能為空");
boolean result = userService.removeById(user.getId());
return Response.success(result);
}
}
6. 測試
- 登錄(system/123456或user/123456)
用戶名或密碼錯誤
用戶名和密碼正確
- 系統管理員登錄(system/123456)
- 用戶管理
- 用戶角色
- 角色綁定用戶
- 角色權限
- 權限綁定角色
- 任務調度
- 普通用戶登錄(user/123456)
- 刪除用戶
- 給角色添加用戶
- 任務調度