Spring 方法安全导致自动装配对象的空值
Spring Method Security causes Null values for autowired objects
我玩过 spring 证券方法安全性,但出现了一个非常奇怪的行为。我有几个控制器 classes,方法用 @PreAuthorize 注释以限制某些用户角色的访问。
有一个控制器Class在添加方法安全性后注入的对象为空。我调试了我的代码并发现了以下内容:
service和userService是注入对象
@Controller
public class OrderController {
@Autowired
private OrderService service;
@Autowired
private UserService userService;
我觉得奇怪的是this的值描述:OrderController$$EnhancerBySpringCGLIB$$1a7122f6。通过删除所有 MethodSecurity 注释,class 按预期工作。
当我查看其他也使用方法安全性的控制器 Classes 时,它们工作正常并且调试器中的变量列表看起来正常:
@Controller
public class UserController {
@Autowired
private UserService service;
我还搜索了我可能用注释造成的错误,但 OrderController 中的注释看起来与其他控制器中的注释相同 classes。这里的 OrderController 示例 Class:
@Controller
public class OrderController {
.
.
.
@GetMapping("/dispo/dispo")
@PreAuthorize("hasAuthority('ADMIN') or hasAuthority('DISPATCH')")
private String showDispoPage() {
return "/dispo/dispo";
}
@GetMapping("/dispo/orderCreate")
@PreAuthorize("hasAuthority('ADMIN') or hasAuthority('AL_SYNC_ADMIN') or hasAuthority('CLIENT_USER') or hasAuthority('DISPATCH')")
private String showCreateOrder(Model model) {
List<MdUser> userList = service.getUsers();
model.addAttribute("userList", userList);
return "/dispo/orderCreate";
}
}
这里是另一个按预期工作的控制器 Class 的示例:
@Controller
public class UserController {
.
.
.
@GetMapping("/admin/user")
@PreAuthorize("hasAuthority('ADMIN') or hasAuthority('DISPATCH') or hasAuthority('WEBTOOL_USER')")
public String showInvalidUserPage(Model model) {
List<UserModel> invalidUserList = service.findInvalidUsers(service.getUsers());
model.addAttribute("userList", invalidUserList);
return "/admin/user";
}
@GetMapping("/admin/userCreate")
@PreAuthorize("hasAuthority('ADMIN')")
public String showNewUserPage(Model model) {
UserModel user = new UserModel();
model.addAttribute("user", user);
return "/admin/userCreate";
}
}
那么这里可能出了什么问题?我不明白为什么这个 class 与另一个 class 有不同的行为。
Spring 安全性使用 AOP(面向方面的编程)"wrap" 带有 AOP 建议的注释方法。一旦调用带有 pre/post 安全注释的方法,建议就会检查用户是否经过身份验证和授权。验证成功则调用该方法,否则遍历unauthorized/unauthenticed个流程
Spring AOP 只能在public 方法上执行runtime 织入。 showDispoPage
和 showCreateOrder
都是私有的,这可能会干扰安全建议。
我会将 pre/post 授权注释移动到服务层。它不仅在控制器注解和安全注解之间提供了更好的分离,而且还可以防止将来出现任何错误。例如,在您当前的设置中,如果通过已忘记安全注释的不同控制器调用对 UserService
方法的任何调用,则不会对其进行验证。
此外,您还可以选择使用 web security
(保护对 URI 的访问,例如保护 /some/path
)以及当前的 method level security
设置。
对于 Kotlin 用户,确保方法不是最终的!
浪费了两天。
我玩过 spring 证券方法安全性,但出现了一个非常奇怪的行为。我有几个控制器 classes,方法用 @PreAuthorize 注释以限制某些用户角色的访问。
有一个控制器Class在添加方法安全性后注入的对象为空。我调试了我的代码并发现了以下内容:
service和userService是注入对象
@Controller
public class OrderController {
@Autowired
private OrderService service;
@Autowired
private UserService userService;
我觉得奇怪的是this的值描述:OrderController$$EnhancerBySpringCGLIB$$1a7122f6。通过删除所有 MethodSecurity 注释,class 按预期工作。
当我查看其他也使用方法安全性的控制器 Classes 时,它们工作正常并且调试器中的变量列表看起来正常:
@Controller
public class UserController {
@Autowired
private UserService service;
我还搜索了我可能用注释造成的错误,但 OrderController 中的注释看起来与其他控制器中的注释相同 classes。这里的 OrderController 示例 Class:
@Controller
public class OrderController {
.
.
.
@GetMapping("/dispo/dispo")
@PreAuthorize("hasAuthority('ADMIN') or hasAuthority('DISPATCH')")
private String showDispoPage() {
return "/dispo/dispo";
}
@GetMapping("/dispo/orderCreate")
@PreAuthorize("hasAuthority('ADMIN') or hasAuthority('AL_SYNC_ADMIN') or hasAuthority('CLIENT_USER') or hasAuthority('DISPATCH')")
private String showCreateOrder(Model model) {
List<MdUser> userList = service.getUsers();
model.addAttribute("userList", userList);
return "/dispo/orderCreate";
}
}
这里是另一个按预期工作的控制器 Class 的示例:
@Controller
public class UserController {
.
.
.
@GetMapping("/admin/user")
@PreAuthorize("hasAuthority('ADMIN') or hasAuthority('DISPATCH') or hasAuthority('WEBTOOL_USER')")
public String showInvalidUserPage(Model model) {
List<UserModel> invalidUserList = service.findInvalidUsers(service.getUsers());
model.addAttribute("userList", invalidUserList);
return "/admin/user";
}
@GetMapping("/admin/userCreate")
@PreAuthorize("hasAuthority('ADMIN')")
public String showNewUserPage(Model model) {
UserModel user = new UserModel();
model.addAttribute("user", user);
return "/admin/userCreate";
}
}
那么这里可能出了什么问题?我不明白为什么这个 class 与另一个 class 有不同的行为。
Spring 安全性使用 AOP(面向方面的编程)"wrap" 带有 AOP 建议的注释方法。一旦调用带有 pre/post 安全注释的方法,建议就会检查用户是否经过身份验证和授权。验证成功则调用该方法,否则遍历unauthorized/unauthenticed个流程
Spring AOP 只能在public 方法上执行runtime 织入。 showDispoPage
和 showCreateOrder
都是私有的,这可能会干扰安全建议。
我会将 pre/post 授权注释移动到服务层。它不仅在控制器注解和安全注解之间提供了更好的分离,而且还可以防止将来出现任何错误。例如,在您当前的设置中,如果通过已忘记安全注释的不同控制器调用对 UserService
方法的任何调用,则不会对其进行验证。
此外,您还可以选择使用 web security
(保护对 URI 的访问,例如保护 /some/path
)以及当前的 method level security
设置。
对于 Kotlin 用户,确保方法不是最终的!
浪费了两天。