🔥 修改不用的内容

This commit is contained in:
Bunny 2025-07-18 17:15:00 +08:00
parent 863464f948
commit 1bb9a251a7
13 changed files with 356 additions and 174 deletions

View File

@ -12,6 +12,7 @@ import com.spring.step3.service.roles.PermissionService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.PermitAll;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -34,6 +35,7 @@ public class PermissionController {
private final PermissionService permissionService; private final PermissionService permissionService;
@PermitAll
@Operation(summary = "分页查询系统权限表", description = "分页系统权限表") @Operation(summary = "分页查询系统权限表", description = "分页系统权限表")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<PermissionVo>> getPermissionPage( public Result<PageResult<PermissionVo>> getPermissionPage(
@ -47,6 +49,7 @@ public class PermissionController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@PermitAll
@Operation(summary = "所有的权限列表", description = "获取所有的权限列表") @Operation(summary = "所有的权限列表", description = "获取所有的权限列表")
@GetMapping("all") @GetMapping("all")
public Result<List<PermissionVo>> getAllPermission() { public Result<List<PermissionVo>> getAllPermission() {
@ -54,6 +57,7 @@ public class PermissionController {
return Result.success(voList); return Result.success(voList);
} }
@PermitAll
@Operation(summary = "添加系统权限表", description = "添加系统权限表") @Operation(summary = "添加系统权限表", description = "添加系统权限表")
@PostMapping() @PostMapping()
public Result<String> addPermission(@Valid @RequestBody PermissionDto dto) { public Result<String> addPermission(@Valid @RequestBody PermissionDto dto) {
@ -61,6 +65,7 @@ public class PermissionController {
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@PermitAll
@Operation(summary = "更新系统权限表", description = "更新系统权限表") @Operation(summary = "更新系统权限表", description = "更新系统权限表")
@PutMapping() @PutMapping()
public Result<String> updatePermission(@Valid @RequestBody PermissionDto dto) { public Result<String> updatePermission(@Valid @RequestBody PermissionDto dto) {
@ -68,6 +73,7 @@ public class PermissionController {
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@PermitAll
@Operation(summary = "删除系统权限表", description = "删除系统权限表") @Operation(summary = "删除系统权限表", description = "删除系统权限表")
@DeleteMapping() @DeleteMapping()
public Result<String> deletePermission(@RequestBody List<Long> ids) { public Result<String> deletePermission(@RequestBody List<Long> ids) {

View File

@ -35,6 +35,7 @@ public class RoleController {
private final RoleService roleService; private final RoleService roleService;
@PermitAll
@Operation(summary = "分页查询系统角色表", description = "分页系统角色表") @Operation(summary = "分页查询系统角色表", description = "分页系统角色表")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<RoleVo>> getRolePage( public Result<PageResult<RoleVo>> getRolePage(
@ -56,6 +57,7 @@ public class RoleController {
return Result.success(roleVoList); return Result.success(roleVoList);
} }
@PermitAll
@Operation(summary = "添加系统角色表", description = "添加系统角色表") @Operation(summary = "添加系统角色表", description = "添加系统角色表")
@PostMapping() @PostMapping()
public Result<String> addRole(@Valid @RequestBody RoleDto dto) { public Result<String> addRole(@Valid @RequestBody RoleDto dto) {
@ -63,6 +65,7 @@ public class RoleController {
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@PermitAll
@Operation(summary = "更新系统角色表", description = "更新系统角色表") @Operation(summary = "更新系统角色表", description = "更新系统角色表")
@PutMapping() @PutMapping()
public Result<String> updateRole(@Valid @RequestBody RoleDto dto) { public Result<String> updateRole(@Valid @RequestBody RoleDto dto) {
@ -70,6 +73,7 @@ public class RoleController {
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@PermitAll
@Operation(summary = "删除系统角色表", description = "删除系统角色表") @Operation(summary = "删除系统角色表", description = "删除系统角色表")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteRole(@RequestBody List<Long> ids) { public Result<String> deleteRole(@RequestBody List<Long> ids) {

View File

@ -13,6 +13,7 @@ import com.spring.step3.service.roles.RolePermissionService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.PermitAll;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -35,6 +36,7 @@ public class RolePermissionController {
private final RolePermissionService rolePermissionService; private final RolePermissionService rolePermissionService;
@PermitAll
@Operation(summary = "分页查询角色权限关联表", description = "分页角色权限关联表") @Operation(summary = "分页查询角色权限关联表", description = "分页角色权限关联表")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<RolePermissionVo>> getRolePermissionPage( public Result<PageResult<RolePermissionVo>> getRolePermissionPage(
@ -49,12 +51,14 @@ public class RolePermissionController {
} }
@GetMapping("permissions") @GetMapping("permissions")
@PermitAll
@Operation(summary = "根据角色id获取权限内容", description = "根据角色id获取权限内容") @Operation(summary = "根据角色id获取权限内容", description = "根据角色id获取权限内容")
public Result<List<RolePermissionVo>> getRolePermissionById(Long permissionId) { public Result<List<RolePermissionVo>> getRolePermissionById(Long permissionId) {
List<RolePermissionVo> voList = rolePermissionService.getRolePermissionById(permissionId); List<RolePermissionVo> voList = rolePermissionService.getRolePermissionById(permissionId);
return Result.success(voList); return Result.success(voList);
} }
@PermitAll
@Operation(summary = "添加角色权限关联表", description = "添加角色权限关联表") @Operation(summary = "添加角色权限关联表", description = "添加角色权限关联表")
@PostMapping() @PostMapping()
public Result<String> addRolePermission(@Valid @RequestBody RolePermissionDto dto) { public Result<String> addRolePermission(@Valid @RequestBody RolePermissionDto dto) {
@ -62,6 +66,7 @@ public class RolePermissionController {
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@PermitAll
@Operation(summary = "为角色分配权限", description = "根据角色id分配权限") @Operation(summary = "为角色分配权限", description = "根据角色id分配权限")
@PostMapping("assign-permission") @PostMapping("assign-permission")
public Result<String> assignRolePermission(@Valid @RequestBody AssignRolePermissionDto dto) { public Result<String> assignRolePermission(@Valid @RequestBody AssignRolePermissionDto dto) {
@ -69,6 +74,7 @@ public class RolePermissionController {
return Result.success(); return Result.success();
} }
@PermitAll
@Operation(summary = "更新角色权限关联表", description = "更新角色权限关联表") @Operation(summary = "更新角色权限关联表", description = "更新角色权限关联表")
@PutMapping() @PutMapping()
public Result<String> updateRolePermission(@Valid @RequestBody RolePermissionDto dto) { public Result<String> updateRolePermission(@Valid @RequestBody RolePermissionDto dto) {
@ -76,6 +82,7 @@ public class RolePermissionController {
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@PermitAll
@Operation(summary = "删除角色权限关联表", description = "删除角色权限关联表") @Operation(summary = "删除角色权限关联表", description = "删除角色权限关联表")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteRolePermission(@RequestBody List<Long> ids) { public Result<String> deleteRolePermission(@RequestBody List<Long> ids) {

View File

@ -11,6 +11,7 @@ import com.spring.step3.service.user.UserService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.PermitAll;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -33,6 +34,7 @@ public class UserController {
private final UserService userService; private final UserService userService;
@PermitAll
@Operation(summary = "分页查询用户基本信息表", description = "分页用户基本信息表") @Operation(summary = "分页查询用户基本信息表", description = "分页用户基本信息表")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<UserVo>> getUserPage( public Result<PageResult<UserVo>> getUserPage(
@ -46,6 +48,7 @@ public class UserController {
return Result.success(pageResult, ResultCodeEnum.LOAD_FINISHED); return Result.success(pageResult, ResultCodeEnum.LOAD_FINISHED);
} }
@PermitAll
@Operation(summary = "添加用户基本信息表", description = "添加用户基本信息表") @Operation(summary = "添加用户基本信息表", description = "添加用户基本信息表")
@PostMapping() @PostMapping()
public Result<String> addUser(@Valid @RequestBody UserDto dto) { public Result<String> addUser(@Valid @RequestBody UserDto dto) {
@ -53,6 +56,7 @@ public class UserController {
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@PermitAll
@Operation(summary = "更新用户基本信息表", description = "更新用户基本信息表") @Operation(summary = "更新用户基本信息表", description = "更新用户基本信息表")
@PutMapping() @PutMapping()
public Result<String> updateUser(@Valid @RequestBody UserDto dto) { public Result<String> updateUser(@Valid @RequestBody UserDto dto) {
@ -60,6 +64,7 @@ public class UserController {
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@PermitAll
@Operation(summary = "删除用户基本信息表", description = "删除用户基本信息表") @Operation(summary = "删除用户基本信息表", description = "删除用户基本信息表")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteUser(@RequestBody List<Long> ids) { public Result<String> deleteUser(@RequestBody List<Long> ids) {

View File

@ -12,6 +12,7 @@ import com.spring.step3.service.user.UserRoleService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.PermitAll;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -34,6 +35,7 @@ public class UserRoleController {
private final UserRoleService userRoleService; private final UserRoleService userRoleService;
@PermitAll
@Operation(summary = "分页查询用户角色关联表", description = "分页用户角色关联表") @Operation(summary = "分页查询用户角色关联表", description = "分页用户角色关联表")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<UserRoleVo>> getUserRolePage( public Result<PageResult<UserRoleVo>> getUserRolePage(
@ -47,6 +49,7 @@ public class UserRoleController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@PermitAll
@Operation(summary = "根据用户id获取当前用户角色列表", description = "根据用户id获取当前用户角色列表") @Operation(summary = "根据用户id获取当前用户角色列表", description = "根据用户id获取当前用户角色列表")
@GetMapping("roles") @GetMapping("roles")
public Result<List<UserRoleVo>> getRoleListByUserId(Long userId) { public Result<List<UserRoleVo>> getRoleListByUserId(Long userId) {
@ -54,6 +57,7 @@ public class UserRoleController {
return Result.success(voList); return Result.success(voList);
} }
@PermitAll
@Operation(summary = "添加用户角色关联表", description = "添加用户角色关联表") @Operation(summary = "添加用户角色关联表", description = "添加用户角色关联表")
@PostMapping() @PostMapping()
public Result<String> addUserRole(@Valid @RequestBody UserRoleDto dto) { public Result<String> addUserRole(@Valid @RequestBody UserRoleDto dto) {
@ -61,6 +65,7 @@ public class UserRoleController {
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@PermitAll
@Operation(summary = "为用户分配角色id", description = "根据用户id分配用户角色") @Operation(summary = "为用户分配角色id", description = "根据用户id分配用户角色")
@PostMapping("assign-role") @PostMapping("assign-role")
public Result<String> assignUserRole(@Valid @RequestBody AssignUserRoleDto dto) { public Result<String> assignUserRole(@Valid @RequestBody AssignUserRoleDto dto) {
@ -68,6 +73,7 @@ public class UserRoleController {
return Result.success(); return Result.success();
} }
@PermitAll
@Operation(summary = "更新用户角色关联表", description = "更新用户角色关联表") @Operation(summary = "更新用户角色关联表", description = "更新用户角色关联表")
@PutMapping() @PutMapping()
public Result<String> updateUserRole(@Valid @RequestBody UserRoleDto dto) { public Result<String> updateUserRole(@Valid @RequestBody UserRoleDto dto) {
@ -75,6 +81,7 @@ public class UserRoleController {
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@PermitAll
@Operation(summary = "删除用户角色关联表", description = "删除用户角色关联表") @Operation(summary = "删除用户角色关联表", description = "删除用户角色关联表")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteUserRole(@RequestBody List<Long> ids) { public Result<String> deleteUserRole(@RequestBody List<Long> ids) {

View File

@ -0,0 +1,58 @@
package com.spring.step3.controller.test;
import com.spring.step3.domain.vo.result.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "自定义方法前的校验", description = "自定义方法前的校验 SecurityPreAuthorization")
@Slf4j
@RestController
@RequestMapping("/api/security/pre")
public class SecurityPreAuthorizationController {
@PreAuthorize("hasAuthority('role::read')")
@Operation(summary = "拥有 role:read 的角色可以访问", description = "当前用户拥有 role:read 角色可以访问这个接口")
@GetMapping("role-user")
public Result<String> roleUser() {
return Result.success();
}
@PreAuthorize("hasAuthority('USER')")
@Operation(summary = "拥有 USER 的角色可以访问", description = "当前用户拥有 USER 角色可以访问这个接口")
@GetMapping("upper-user")
public Result<String> upperUser() {
String data = "是区分大小写的";
return Result.success(data);
}
@PreAuthorize("hasAuthority('admin')")
@Operation(summary = "拥有 admin 的角色可以访问", description = "当前用户拥有 admin 角色可以访问这个接口")
@GetMapping("lower-admin")
public Result<String> lowerAdmin() {
String data = "如果是大写,但是在这里是小写无法访问";
return Result.success(data);
}
@PreAuthorize("hasAuthority('ADMIN')")
@Operation(summary = "拥有 ADMIN 的角色可以访问", description = "当前用户拥有 ADMIN 角色可以访问这个接口")
@GetMapping("upper-admin")
public Result<String> upperAdmin() {
String data = "如果是大写,但是在这里是小写无法访问";
return Result.success(data);
}
// @PostAuthorize("returnObject.data == authentication.name")
// @Operation(summary = "测试使用返回参数判断权限", description = "测试使用返回参数判断权限 用户拥有 role::read 可以访问这个接口")
// @GetMapping("test-post-authorize")
// public Result<String> testPostAuthorize() {
// log.info("方法内容已经执行。。。");
// String data = "Bunny";
// return Result.success(data);
// }
}

View File

@ -1,21 +0,0 @@
package com.spring.step3.security.config;
import org.springframework.context.annotation.Configuration;
@Configuration
// @EnableMethodSecurity(prePostEnabled = false)
public class AuthorizationManagerConfiguration {
// @Bean
// @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// Advisor preAuthorize(PreAuthorizationManager manager) {
// return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager);
// }
//
// @Bean
// @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// Advisor postAuthorize(PostAuthorizationManager manager) {
// return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager);
// }
}

View File

@ -18,7 +18,7 @@ import java.util.List;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@EnableMethodSecurity(jsr250Enabled = true) @EnableMethodSecurity(jsr250Enabled = true, securedEnabled = true)
@RequiredArgsConstructor @RequiredArgsConstructor
public class SecurityWebConfiguration { public class SecurityWebConfiguration {
@ -56,7 +56,7 @@ public class SecurityWebConfiguration {
// 但是在 Spring过滤器中如果要放行不需要认证请求但是需要认证的接口必需要携带token // 但是在 Spring过滤器中如果要放行不需要认证请求但是需要认证的接口必需要携带token
// 做法是在这里定义要认证的接口如果要做成动态可以放到数据库 // 做法是在这里定义要认证的接口如果要做成动态可以放到数据库
// ======================================================================= // =======================================================================
.requestMatchers(securedPaths.toArray(String[]::new)).authenticated() // .requestMatchers(securedPaths.toArray(String[]::new)).authenticated()
// 其余请求都放行 // 其余请求都放行
.anyRequest().permitAll() .anyRequest().permitAll()
) )

View File

@ -39,84 +39,95 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override @Override
protected void doFilterInternal(@NotNull HttpServletRequest request, protected void doFilterInternal(@NotNull HttpServletRequest request,
@NotNull HttpServletResponse response, @NotNull HttpServletResponse response,
@NotNull FilterChain filterChain) throws ServletException, IOException, AuthenticSecurityException { @NotNull FilterChain filterChain)
// 先校验不需要认证的接口 throws ServletException, IOException {
RequestMatcher[] requestNoAuthMatchers = SecurityWebConfiguration.noAuthPaths.stream()
.map(AntPathRequestMatcher::new)
.toArray(RequestMatcher[]::new);
OrRequestMatcher noAuthRequestMatcher = new OrRequestMatcher(requestNoAuthMatchers);
if (noAuthRequestMatcher.matches(request)) {
filterChain.doFilter(request, response);
return;
}
// 获取需要认证的接口
RequestMatcher[] requestSecureMatchers = SecurityWebConfiguration.securedPaths.stream()
.map(AntPathRequestMatcher::new)
.toArray(RequestMatcher[]::new);
OrRequestMatcher secureRequestMatcher = new OrRequestMatcher(requestSecureMatchers);
// 公开接口直接放行
if (!secureRequestMatcher.matches(request)) {
filterChain.doFilter(request, response);
return;
}
final String authHeader = request.getHeader("Authorization");
// 如果当前请求不包含验证Token直接返回
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
throw new AuthenticSecurityException(ResultCodeEnum.LOGIN_AUTH);
}
// 当前请求的Token
final String jwtToken = authHeader.substring(7);
try { try {
// 检查当前Token是否过期 // 检查白名单路径
if (jwtTokenService.isExpired(jwtToken)) { if (isNoAuthPath(request)) {
// 💡如果过期不需要进行判断和验证需要直接放行可以像下面这样写 filterChain.doFilter(request, response);
// =================================================== return;
// filterChain.doFilter(request, response);
// return;
// ===================================================
throw new AuthenticSecurityException(ResultCodeEnum.AUTHENTICATION_EXPIRED);
} }
// 解析当前Token中的用户名 // 检查是否需要认证的路径
String username = jwtTokenService.getUsernameFromToken(jwtToken); if (!isSecurePath(request)) {
Long userId = jwtTokenService.getUserIdFromToken(jwtToken); filterChain.doFilter(request, response);
return;
// 当前用户名存在并且 Security上下文为空设置认证相关信息
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
// 调用用户信息进行登录
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// 设置认证用户信息
SecurityContextHolder.getContext().setAuthentication(authToken);
BaseContext.setUsername(username);
BaseContext.setUserId(userId);
} }
// 验证Token
validateAndSetAuthentication(request, response, filterChain);
filterChain.doFilter(request, response); filterChain.doFilter(request, response);
} } catch (AuthenticSecurityException e) {
// IMPORTANT: // 直接处理认证异常不再调用filterChain.doFilter()
// ==========================================================================
// catch 块中securityAuthenticationEntryPoint.commence() 已经处理了错误响应
// 所以应该 直接返回避免继续执行后续逻辑
// ==========================================================================
catch (RuntimeException exception) {
securityAuthenticationEntryPoint.commence( securityAuthenticationEntryPoint.commence(
request, request,
response, response,
new MyAuthenticationException(exception.getMessage(), exception) new MyAuthenticationException(e.getMessage(), e)
);
} catch (RuntimeException e) {
securityAuthenticationEntryPoint.commence(
request,
response,
new MyAuthenticationException("Authentication failed", e)
); );
} }
} }
}
/**
* 是否是不用验证的路径
*/
private boolean isNoAuthPath(HttpServletRequest request) {
RequestMatcher[] matchers = SecurityWebConfiguration.noAuthPaths.stream()
.map(AntPathRequestMatcher::new)
.toArray(RequestMatcher[]::new);
return new OrRequestMatcher(matchers).matches(request);
}
/**
* 是否是要验证的路径
*/
private boolean isSecurePath(HttpServletRequest request) {
RequestMatcher[] matchers = SecurityWebConfiguration.securedPaths.stream()
.map(AntPathRequestMatcher::new)
.toArray(RequestMatcher[]::new);
return new OrRequestMatcher(matchers).matches(request);
}
/**
* 验证并设置身份验证
*/
private void validateAndSetAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
// Token验证
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
// throw new AuthenticSecurityException(ResultCodeEnum.LOGIN_AUTH);
}
String jwtToken = authHeader.substring(7);
if (jwtTokenService.isExpired(jwtToken)) {
throw new AuthenticSecurityException(ResultCodeEnum.AUTHENTICATION_EXPIRED);
}
// 设置认证信息
String username = jwtTokenService.getUsernameFromToken(jwtToken);
Long userId = jwtTokenService.getUserIdFromToken(jwtToken);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
BaseContext.setUsername(username);
BaseContext.setUserId(userId);
}
}
}

View File

@ -0,0 +1,28 @@
package com.spring.step3.security.manger;
import org.springframework.aop.Advisor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.security.authorization.method.AuthorizationManagerAfterMethodInterceptor;
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
@Configuration
@EnableMethodSecurity(prePostEnabled = false)
public class AuthorizationManagerConfiguration {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Advisor preAuthorize(PreAuthorizationManager manager) {
return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager);
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Advisor postAuthorize(PostAuthorizationManager manager) {
return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager);
}
}

View File

@ -1,48 +1,91 @@
package com.spring.step3.security.manger; package com.spring.step3.security.manger;
import com.spring.step3.domain.vo.result.Result;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.authorization.method.MethodInvocationResult;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.function.Supplier;
/** /**
* 处理方法调用后的授权检查 * 处理方法调用后的授权检查
* check()方法接收的是MethodInvocationResult对象包含已执行方法的结果 * check()方法接收的是MethodInvocationResult对象包含已执行方法的结果
* 用于决定是否允许返回某个方法的结果(后置过滤) * 用于决定是否允许返回某个方法的结果(后置过滤)
* 这是Spring Security较新的"后置授权"功能 * 这是Spring Security较新的"后置授权"功能
*/ */
// @Component @Component
// public class PostAuthorizationManager implements AuthorizationManager<MethodInvocationResult> { public class PostAuthorizationManager implements AuthorizationManager<MethodInvocationResult> {
//
// /** /**
// * 这里两个实现方法按照Security官方要求进行实现 * 这里两个实现方法按照Security官方要求进行实现
// * <h4>类说明</h4> * <h4>类说明</h4>
// * 下面的实现是对方法执行前进行权限校验的判断 * 下面的实现是对方法执行前进行权限校验的判断
// * <pre> * <pre>
// * <code>AuthorizationManager &ltMethodInvocation></code> * <code>AuthorizationManager &ltMethodInvocation></code>
// * </pre> * </pre>
// * 下面的这个是对方法执行后对权限的判断 * 下面的这个是对方法执行后对权限的判断
// * <pre> * <pre>
// * <code>AuthorizationManager &ltMethodInvocationResult></code> * <code>AuthorizationManager &ltMethodInvocationResult></code>
// * </pre> * </pre>
// * *
// * <h4>注意事项</h4> * <h4>注意事项</h4>
// * 将上述两个方法按照自定义的方式进行实现后还需要禁用默认的 * 将上述两个方法按照自定义的方式进行实现后还需要禁用默认的
// * <pre> * <pre>
// * &#064;Configuration * &#064;Configuration
// * &#064;EnableMethodSecurity(prePostEnabled = false) * &#064;EnableMethodSecurity(prePostEnabled = false)
// * class MethodSecurityConfig { * class MethodSecurityConfig {
// * &#064;Bean * &#064;Bean
// * &#064;Role(BeanDefinition.ROLE_INFRASTRUCTURE) * &#064;Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// * Advisor preAuthorize(MyAuthorizationManager manager) { * Advisor preAuthorize(MyAuthorizationManager manager) {
// * return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager); * return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager);
// * } * }
// * *
// * &#064;Bean * &#064;Bean
// * &#064;Role(BeanDefinition.ROLE_INFRASTRUCTURE) * &#064;Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// * Advisor postAuthorize(MyAuthorizationManager manager) { * Advisor postAuthorize(MyAuthorizationManager manager) {
// * return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager); * return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager);
// * } * }
// * } * }
// * </pre> * </pre>
// */ */
// @Override @Override
// public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocationResult invocation) { public AuthorizationDecision check(Supplier<Authentication> authenticationSupplier, MethodInvocationResult methodInvocationResult) {
// return new AuthorizationDecision(true); Authentication authentication = authenticationSupplier.get();
// }
// } // 如果方法有 @PreAuthorize 注解会先到这里
if (authentication == null || !authentication.isAuthenticated()) {
return new AuthorizationDecision(false);
}
// 检查权限
boolean granted = hasPermission(authentication, methodInvocationResult);
return new AuthorizationDecision(granted);
}
private boolean hasPermission(Authentication authentication, MethodInvocationResult methodInvocationResult) {
// 1. 获取当前校验方法的返回值
if (methodInvocationResult.getResult() instanceof Result<?> result) {
// 拿到当前返回值中权限内容
List<String> auths = result.getAuths();
// 判断返回值中返回方法全新啊是否和用户权限匹配
return authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority)
.anyMatch(auth ->
// 这里是忽略了大小写匹配的 admin 权限如果包含 admin 无论大小写都可以放行
auth.equalsIgnoreCase("admin")
|| auths.contains(auth)
);
}
// 这里可以设置自己的返回状态
// ======================================
// 默认返回 TRUE 是因为有可能当前方法不需要验证
// 所以才设置默认返回为 TURE
// ======================================
return true;
}
}

View File

@ -1,49 +1,83 @@
package com.spring.step3.security.manger; package com.spring.step3.security.manger;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.function.Supplier;
/** /**
* 处理方法调用前的授权检查 * 处理方法调用前的授权检查
* check()方法接收的是MethodInvocation对象包含即将执行的方法调用信息 * check()方法接收的是MethodInvocation对象包含即将执行的方法调用信息
* 用于决定是否允许执行某个方法 * 用于决定是否允许执行某个方法
* 这是传统的"前置授权"模式 * 这是传统的"前置授权"模式
*/ */
// @Component @Component
// public class PreAuthorizationManager implements AuthorizationManager<MethodInvocation> { public class PreAuthorizationManager implements AuthorizationManager<MethodInvocation> {
//
// /** /**
// * 这里两个实现方法按照Security官方要求进行实现 * 这里两个实现方法按照Security官方要求进行实现
// * <h4>类说明</h4> * <h4>类说明</h4>
// * 下面的实现是对方法执行前进行权限校验的判断 * 下面的实现是对方法执行前进行权限校验的判断
// * <pre> * <pre>
// * <code>AuthorizationManager &ltMethodInvocation></code> * <code>AuthorizationManager &ltMethodInvocation></code>
// * </pre> * </pre>
// * 下面的这个是对方法执行后对权限的判断 * 下面的这个是对方法执行后对权限的判断
// * <pre> * <pre>
// * <code>AuthorizationManager &ltMethodInvocationResult></code> * <code>AuthorizationManager &ltMethodInvocationResult></code>
// * </pre> * </pre>
// * *
// * <h4>注意事项</h4> * <h4>注意事项</h4>
// * 将上述两个方法按照自定义的方式进行实现后还需要禁用默认的 * 将上述两个方法按照自定义的方式进行实现后还需要禁用默认的
// * <pre> * <pre>
// * &#064;Configuration * &#064;Configuration
// * &#064;EnableMethodSecurity(prePostEnabled = false) * &#064;EnableMethodSecurity(prePostEnabled = false)
// * class MethodSecurityConfig { * class MethodSecurityConfig {
// * &#064;Bean * &#064;Bean
// * &#064;Role(BeanDefinition.ROLE_INFRASTRUCTURE) * &#064;Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// * Advisor preAuthorize(MyAuthorizationManager manager) { * Advisor preAuthorize(MyAuthorizationManager manager) {
// * return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager); * return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager);
// * } * }
// * *
// * &#064;Bean * &#064;Bean
// * &#064;Role(BeanDefinition.ROLE_INFRASTRUCTURE) * &#064;Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// * Advisor postAuthorize(MyAuthorizationManager manager) { * Advisor postAuthorize(MyAuthorizationManager manager) {
// * return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager); * return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager);
// * } * }
// * } * }
// * </pre> * </pre>
// */ */
// @Override @Override
// public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocation invocation) { public AuthorizationDecision check(Supplier<Authentication> authenticationSupplier, MethodInvocation methodInvocation) {
// return new AuthorizationDecision(true); Authentication authentication = authenticationSupplier.get();
// }
// // 如果方法有 @PreAuthorize 注解会先到这里
// } if (authentication == null || !authentication.isAuthenticated()) {
return new AuthorizationDecision(false);
}
// 检查权限
boolean granted = hasPermission(authentication, methodInvocation);
return new AuthorizationDecision(granted);
}
private boolean hasPermission(Authentication authentication, MethodInvocation methodInvocation) {
// 1. 获取方法上的权限注解如果有
// 例如@PreAuthorize("hasRole('ADMIN')") 或其他自定义注解
// 2. 获取用户权限
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
// 3. 实现你的权限逻辑
// 这里简单示例检查方法名是否包含在权限中
String methodName = methodInvocation.getMethod().getName();
return authorities.stream()
.map(GrantedAuthority::getAuthority)
// 这里是忽略了大小写匹配的 admin 权限如果包含 admin 无论大小写都可以放行
.anyMatch(auth -> auth.equalsIgnoreCase("admin") || auth.equals(methodName));
}
}

View File

@ -1,6 +1,6 @@
// axios 配置 // axios 配置
const axiosInstance = axios.create({ const axiosInstance = axios.create({
baseURL: 'http://localhost:8772/api', baseURL: 'http://localhost:8773/api',
timeout: 16000, timeout: 16000,
headers: {'Content-Type': 'application/json;charset=utf-8'}, headers: {'Content-Type': 'application/json;charset=utf-8'},
}); });