| 技术名称 | 版本 |
| SpringBoot | 2.1.9.RELEASE |
| MyBatis-plus | 3.3.1 |
| MySQL | 8.0.11 |
| SpringSecurity | 5.1.6.RELEASE |
| jjwt | 0.9.0 |
| lombok | 1.18.10 |
| guava | 30.1.1-jre |
| hutool-all | 5.5.2 |
| druid | 1.2.3 |
| swagger3 | 3.0 |
| aop | 1.9.4 |
| fastjson | 1.2.47 |
3、初始化脚本4.0.0 com.zzg meta0.0.1-SNAPSHOT org.springframework.boot spring-boot-starter-parent2.1.9.RELEASE 1.8 3.1.1 org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-testtest com.baomidou mybatis-plus-boot-starter3.3.1 mysql mysql-connector-java8.0.11 org.springframework.boot spring-boot-starter-securityio.jsonwebtoken jjwt0.9.0 org.projectlombok lomboktrue com.google.guava guava30.1.1-jre cn.hutool hutool-all5.5.2 com.alibaba druid-spring-boot-starter1.2.3 io.springfox springfox-boot-starter3.0.0 org.springframework.plugin spring-plugin-coreorg.springframework.plugin spring-plugin-metadataorg.springframework.plugin spring-plugin-core2.0.0.RELEASE org.springframework.plugin spring-plugin-metadata2.0.0.RELEASE org.springframework.boot spring-boot-starter-aopcom.alibaba fastjson1.2.47 org.springframework.boot spring-boot-maven-pluginorg.projectlombok lombok
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- 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) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '权限名称',
`permission` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '权限标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统权限' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_sys_auth
-- ----------------------------
INSERT INTO `t_sys_auth` VALUES (1, '系统用户编辑权限', 'sys:user:edit');
INSERT INTO `t_sys_auth` VALUES (2, '系统用户查询权限', 'sys:user:view');
INSERT INTO `t_sys_auth` VALUES (3, '系统角色编辑权限', 'sys:role:edit');
INSERT INTO `t_sys_auth` VALUES (4, '系统角色查询权限', 'sys:role:view');
INSERT INTO `t_sys_auth` VALUES (5, '系统权限编辑权限', 'sys:auth:edit');
INSERT INTO `t_sys_auth` VALUES (6, '系统权限查询权限', 'sys:auth:view');
INSERT INTO `t_sys_auth` VALUES (7, '系统日志编辑权限', 'sys:log:edit');
INSERT INTO `t_sys_auth` VALUES (8, '系统日志查询权限', 'sys:log:view');
-- ----------------------------
-- Table structure for t_sys_log
-- ----------------------------
DROP TABLE IF EXISTS `t_sys_log`;
CREATE TABLE `t_sys_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '请求方法',
`uri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '请求地址',
`params` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '请求参数',
`time` bigint(10) NULL DEFAULT NULL COMMENT '请求时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_sys_log
-- ----------------------------
INSERT INTO `t_sys_log` VALUES (2, 'GET', '/log/listData', 'page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (3, 'GET', '/log/list', '', 0);
INSERT INTO `t_sys_log` VALUES (4, 'GET', '/log/listData', 'page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (5, 'GET', '/log/listData', 'page=1&limit=10&id=2', 0);
INSERT INTO `t_sys_log` VALUES (6, 'GET', '/log/listData', 'page=1&limit=10&id=', -1);
INSERT INTO `t_sys_log` VALUES (7, 'POST', '/log/delete', '[{"id":1}]', 0);
INSERT INTO `t_sys_log` VALUES (8, 'GET', '/log/listData', 'page=1&limit=10&id=', 0);
INSERT INTO `t_sys_log` VALUES (9, 'GET', '/log/list', '', 0);
INSERT INTO `t_sys_log` VALUES (10, 'GET', '/log/listData', 'page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (11, 'GET', '/log/list', '', 0);
INSERT INTO `t_sys_log` VALUES (12, 'GET', '/log/listData', 'page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (13, 'GET', '/log/list', '', 0);
INSERT INTO `t_sys_log` VALUES (14, 'GET', '/log/listData', 'page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (15, 'GET', '/log/listData', 'page=2&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (16, 'GET', '/auth/list', '', 0);
INSERT INTO `t_sys_log` VALUES (17, 'GET', '/auth/listData', 'page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (18, 'GET', '/auth/bind', 'id=1', 0);
INSERT INTO `t_sys_log` VALUES (19, 'GET', '/auth/roleListData', 'authId=1&page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (20, 'GET', '/auth/list', '', 0);
INSERT INTO `t_sys_log` VALUES (21, 'GET', '/auth/listData', 'page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (22, 'GET', '/log/list', '', 0);
INSERT INTO `t_sys_log` VALUES (23, 'GET', '/log/listData', 'page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (24, 'GET', '/log/listData', 'page=3&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (25, 'GET', '/log/listData', 'page=2&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (26, 'GET', '/auth/list', '', 0);
INSERT INTO `t_sys_log` VALUES (27, 'GET', '/auth/listData', 'page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (28, 'GET', '/log/list', '', 0);
INSERT INTO `t_sys_log` VALUES (29, 'GET', '/log/listData', 'page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (30, 'GET', '/auth/list', '', -1);
INSERT INTO `t_sys_log` VALUES (31, 'GET', '/auth/listData', 'page=1&limit=10', 0);
INSERT INTO `t_sys_log` VALUES (32, 'GET', '/log/list', '', 0);
INSERT INTO `t_sys_log` VALUES (33, 'GET', '/log/listData', 'page=1&limit=10', 0);
-- ----------------------------
-- 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) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '角色名称',
`role_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色编码',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统角色' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_sys_role
-- ----------------------------
INSERT INTO `t_sys_role` VALUES (1, '普通员工', 'USER');
INSERT INTO `t_sys_role` VALUES (2, '项目经理', 'PM');
-- ----------------------------
-- 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 AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色权限关系' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_sys_role_auth
-- ----------------------------
INSERT INTO `t_sys_role_auth` VALUES (1, 2, 1);
INSERT INTO `t_sys_role_auth` VALUES (2, 1, 2);
INSERT INTO `t_sys_role_auth` VALUES (3, 2, 2);
INSERT INTO `t_sys_role_auth` VALUES (4, 2, 3);
INSERT INTO `t_sys_role_auth` VALUES (5, 1, 4);
INSERT INTO `t_sys_role_auth` VALUES (6, 2, 4);
INSERT INTO `t_sys_role_auth` VALUES (7, 2, 5);
INSERT INTO `t_sys_role_auth` VALUES (8, 1, 6);
INSERT INTO `t_sys_role_auth` VALUES (9, 2, 6);
INSERT INTO `t_sys_role_auth` VALUES (10, 2, 7);
INSERT INTO `t_sys_role_auth` VALUES (11, 2, 8);
-- ----------------------------
-- Table structure for t_sys_user
-- ----------------------------
DROP TABLE IF EXISTS `t_sys_user`;
CREATE TABLE `t_sys_user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户名称',
`nickname` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户昵称',
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户密码',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_sys_user
-- ----------------------------
INSERT INTO `t_sys_user` VALUES (1, 'user', 'C3Stones', '$2a$10$RFjGxPxq8EZokh89z.DcIeSpBJHfeRozfXUZSHnfN14bb94JKVRia');
INSERT INTO `t_sys_user` VALUES (2, 'system', '管理员', '$2a$10$RFjGxPxq8EZokh89z.DcIeSpBJHfeRozfXUZSHnfN14bb94JKVRia');
-- ----------------------------
-- 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 AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户角色关系' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_sys_user_role
-- ----------------------------
INSERT INTO `t_sys_user_role` VALUES (1, 1, 1);
INSERT INTO `t_sys_user_role` VALUES (2, 2, 2);
SET FOREIGN_KEY_CHECKS = 1;
4、项目结构截图:
5、springsecurity handler 定义
package com.zzg.security.handler;
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;
import com.alibaba.fastjson.JSON;
import com.zzg.common.vo.Response;
import cn.hutool.http.HttpStatus;
@Component
public class UserAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException {
Response responseBody = Response.error(HttpStatus.HTTP_UNAUTHORIZED, "Unauthorized", "用户未认证");
response.getWriter().write(JSON.toJSonString(responseBody));
}
}
package com.zzg.security.handler;
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.alibaba.fastjson.JSON;
import com.zzg.common.vo.Response;
import cn.hutool.http.HttpStatus;
@Component
public class UserLoginFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException {
Response responseBody = Response.error(HttpStatus.HTTP_BAD_REQUEST, "Bad Request", "请求失败");
response.getWriter().write(JSON.toJSonString(responseBody));
}
}
package com.zzg.security.handler;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
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.alibaba.fastjson.JSON;
import com.zzg.common.vo.Response;
import com.zzg.security.entity.UserDetails;
import com.zzg.security.jwt.JwtTokenUtil;
import cn.hutool.http.HttpStatus;
@Component
public class UserLoginSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
Map paramter = new HashMap();
paramter.put("username", userDetails.getUsername());
String jwtToken = JwtTokenUtil.createToken(paramter);
Response responseBody = Response.error(HttpStatus.HTTP_OK, "Login Success", jwtToken);
response.getWriter().write(JSON.toJSonString(responseBody));
}
}
package com.zzg.security.handler;
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.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.zzg.common.vo.Response;
import cn.hutool.http.HttpStatus;
@Component
public class UserLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
Response responseBody = Response.error(HttpStatus.HTTP_OK, "Logout Success", "用户退出成功");
response.getWriter().write(JSON.toJSonString(responseBody));
}
}
package com.zzg.security.handler;
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;
import com.alibaba.fastjson.JSON;
import com.zzg.common.vo.Response;
import cn.hutool.http.HttpStatus;
@Component
public class UserNotLoginHandler implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
Response responseBody = Response.error(HttpStatus.HTTP_UNAUTHORIZED, "Unauthorized", "用户未认证");
response.getWriter().write(JSON.toJSonString(responseBody));
}
}
6、springsecurity UserDetails 定义
package com.zzg.security.entity;
import java.io.Serializable;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import com.zzg.sys.entity.User;
import lombok.Data;
import lombok.EqualsAndHashCode;
@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 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;
}
}
7、springsecurity UserDetailsService定义
package com.zzg.security.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.zzg.security.entity.UserDetails;
import com.zzg.sys.entity.Role;
import com.zzg.sys.entity.User;
import com.zzg.sys.service.RoleService;
import com.zzg.sys.service.UserService;
@Service
public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", username);
User user = userService.getOne(queryWrapper);
if (user != null) {
UserDetails userDetails = new UserDetails();
BeanUtils.copyProperties(user, userDetails);
// 用户角色
Set authorities = new HashSet<>();
// 查询用户角色
List roleList = roleService.findByUserId(userDetails.getId());
roleList.forEach(role -> {
authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleCode()));
});
userDetails.setAuthorities(authorities);
return userDetails;
}
return null;
}
}
8、springsecurity AuthenticationProvider定义
package com.zzg.security;
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.zzg.security.entity.UserDetails;
import com.zzg.security.service.UserDetailsService;
import cn.hutool.core.util.StrUtil;
@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;
}
}
9. jwt 工具类定义
package com.zzg.security.jwt;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
public class JwtTokenUtil {
private static String secret = "meta";
private static long expire = 7 * 24 * 60 * 60;
public static Claims parseToken(String token) {
Claims claims = null;
try {
claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
} catch (Exception e) {
return claims;
}
return claims;
}
public static String createToken(Map paramter) {
if (Objects.isNull(paramter)) {
paramter = new HashMap<>();
}
// 过期时间
Date expireDate = new Date(System.currentTimeMillis() + expire * 1000);
return Jwts.builder().setHeaderParam("typ", "JWT") // 设置头部信息
.setClaims(paramter) // 装入自定义的用户信息
.setExpiration(expireDate) // token过期时间
.signWith(SignatureAlgorithm.HS512, secret) // 密钥
.compact();
}
public static String referToken(Map paramter) {
if (Objects.isNull(paramter)) {
paramter = new HashMap<>();
}
// 过期时间
Date expireDate = new Date(System.currentTimeMillis() + expire * 1000);
return Jwts.builder().setHeaderParam("typ", "JWT") // 设置头部信息
.setClaims(paramter) // 装入自定义的用户信息
.setExpiration(expireDate) // token过期时间
.signWith(SignatureAlgorithm.HS512, secret) // 密钥
.compact();
}
}
10.jwt 凭证验证拦截器
package com.zzg.security.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import com.zzg.security.entity.UserDetails;
import com.zzg.security.jwt.JwtTokenUtil;
import com.zzg.security.service.UserDetailsService;
@Component
public class JwtAuthenticationTokenFilter extends oncePerRequestFilter {
@Autowired
UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer")) {
final String authToken = authHeader.substring("Bearer".length());
String username = (String) JwtTokenUtil.parseToken(authToken).get("username");
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (userDetails != null) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
}
chain.doFilter(request, response);
}
}
11、springsecurity 配置对象
package com.zzg.security.conf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.zzg.security.UserAuthenticationProvider;
import com.zzg.security.filter.JwtAuthenticationTokenFilter;
import com.zzg.security.handler.UserAccessDeniedHandler;
import com.zzg.security.handler.UserLoginFailureHandler;
import com.zzg.security.handler.UserLoginSuccessHandler;
import com.zzg.security.handler.UserLogoutSuccessHandler;
import com.zzg.security.handler.UserNotLoginHandler;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public static final Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class);
@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
JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(userAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 去掉 CSRF
http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 使用 JWT,关闭token
.and()
.httpBasic().authenticationEntryPoint(userNotLoginHandler)
.and()
.authorizeRequests()
// .anyRequest()
// .access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
.and()
.formLogin() //开启登录
.successHandler(userLoginSuccessHandler) // 登录成功
.failureHandler(userLoginFailureHandler) // 登录失败
.permitAll()
.and()
.logout()
.logoutSuccessHandler(userLogoutSuccessHandler)
.permitAll();
http.exceptionHandling().accessDeniedHandler(userAccessDeniedHandler); // 无权访问 JSON 格式的数据
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); // JWT Filter
}
}
12、PostMan模拟前后端分离效果截图
13、项目源码



