Spring Method Security 导致自动装配对象的 Null 值

Rai*_*lin 5 spring spring-security spring-aop

我玩过弹簧证券方法安全性并得到了一个非常奇怪的行为。我有几个控制器类,这些方法用 @PreAuthorize 进行注释以限制某些用户角色的访问。

有一个控制器类在添加方法安全性后注入的对象为空。我调试到我的代码中,发现以下内容:

在此处输入图片说明

serviceuserService是注入的对象

@Controller
public class OrderController {

    @Autowired
    private OrderService service;

    @Autowired
    private UserService userService;
Run Code Online (Sandbox Code Playgroud)

什么觉得奇怪,我是值描述:OrderController $$ EnhancerBySpringCGLIB $$ 1a7122f6。通过删除所有 MethodSecurity 注释,该类按预期工作。

当我查看其他也使用方法安全性的控制器类时,它们工作得很好,调试器中的变量列表看起来也不错:

在此处输入图片说明

@Controller
public class UserController {

    @Autowired
    private UserService service;
Run Code Online (Sandbox Code Playgroud)

我还搜索了我可能对注释产生的错误,但 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";
    }
}
Run Code Online (Sandbox Code Playgroud)

这是另一个按预期工作的控制器类的示例:

@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";
    }
}
Run Code Online (Sandbox Code Playgroud)

那么这里可能出了什么问题呢?我不明白为什么这个类的行为与其他类不同。

Mic*_*iel 6

Spring Security 使用 AOP(面向方面​​的编程)来“包装”带有 AOP 建议的带注释的方法。一旦调用了带有前/后安全注释的方法,建议就会检查用户是否经过身份验证和授权。如果成功验证,则调用该方法,否则将遍历一些未经授权/未经身份验证的流。

Spring AOP 只能对公共方法执行运行时编织。的和都是私有的,这可能与安全建议干扰。showDispoPageshowCreateOrder

我会将前/后授权注释移动到服务层。它不仅在控制器注释和安全注释之间提供了更好的分离,还可以防止任何未来的错误。例如,在您当前的设置中,UserService如果通过忘记安全注释的不同控制器调用该方法,则不会验证对该方法的任何调用。

此外,您还可以选择与当前设置一起使用web security(保护对 URI 的访问,例如 secure /some/pathmethod level security