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

时间:2019-05-21 11:30:40

标签: spring spring-security spring-aop

我玩了一些春季证券方法安全性,并且表现得很奇怪。我有几个控制器类,并且使用@PreAuthorize注释方法,以限制对某些用户角色的访问。

在添加方法安全性之后,有一个Controller类的注入对象为null。我调试了代码,发现以下内容:

enter image description here

service userService 是注入的对象

@Controller
public class OrderController {

    @Autowired
    private OrderService service;

    @Autowired
    private UserService userService;

对我来说,奇怪的是 this 的值描述:OrderController $$ EnhancerBySpringCGLIB $$ 1a7122f6。通过删除所有MethodSecurity批注,该类将按预期工作。

当我查看其他同样使用方法安全性的Controller类时,它们也可以正常工作,并且调试器中的变量列表看起来还可以:

enter image description here

@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";
    }
}

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

2 个答案:

答案 0 :(得分:3)

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

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

我将前/后授权注释移到Service层。它不仅可以更好地分隔控制器注释和安全注释,还可以防止将来出现任何错误。例如,在您当前的设置中,如果UserService方法的任何调用是通过另一个忘记了安全注释的Controller调用的,则将不进行验证。

此外,您还可以选择使用web security(确保对URI的访问,例如保护/some/path)和当前的method level security设置。

答案 1 :(得分:0)

对于Kotlin用户,请确保方法不是最终的

浪费了两天。