我玩了一些春季证券方法安全性,并且表现得很奇怪。我有几个控制器类,并且使用@PreAuthorize注释方法,以限制对某些用户角色的访问。
在添加方法安全性之后,有一个Controller类的注入对象为null。我调试了代码,发现以下内容:
service 和 userService 是注入的对象
@Controller
public class OrderController {
@Autowired
private OrderService service;
@Autowired
private UserService userService;
对我来说,奇怪的是 this 的值描述:OrderController $$ EnhancerBySpringCGLIB $$ 1a7122f6。通过删除所有MethodSecurity批注,该类将按预期工作。
当我查看其他同样使用方法安全性的Controller类时,它们也可以正常工作,并且调试器中的变量列表看起来还可以:
@Controller
public class UserController {
@Autowired
private UserService service;
我还搜索了注释可能造成的错误,但OrderController中的注释看起来与其他Controller类中的注释相同。这里是OrderController类的示例:
@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";
}
}
这是另一个可以正常工作的Controller类的示例:
@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";
}
}
那么这里可能出了什么问题?我不明白为什么这个班级的行为不同于其他班级。
答案 0 :(得分:3)
Spring Security使用AOP(面向方面的编程)将带有AOP建议的带注释的方法“包装”起来。一旦调用带有安全前/后安全注释的方法,建议就会检查用户是否已通过身份验证和授权。如果该方法成功验证,则将调用该方法,否则将遍历一些未经授权/未经身份验证的流。
Spring AOP只能对 public 方法执行运行时编织。 showDispoPage
和showCreateOrder
都是私有的,可能会干扰安全建议。
我将前/后授权注释移到Service层。它不仅可以更好地分隔控制器注释和安全注释,还可以防止将来出现任何错误。例如,在您当前的设置中,如果UserService
方法的任何调用是通过另一个忘记了安全注释的Controller调用的,则将不进行验证。
此外,您还可以选择使用web security
(确保对URI的访问,例如保护/some/path
)和当前的method level security
设置。
答案 1 :(得分:0)
对于Kotlin用户,请确保方法不是最终的!
浪费了两天。