【问题标题】:Autowired Service is Null in ResponseBody method when using PreAuthorize使用 PreAuthorize 时,ResponseBody 方法中的 Autowired Service 为 Null
【发布时间】:2017-05-26 14:08:20
【问题描述】:

我有一个自动装配“Foo”服务的“Foo”控制器。

现在,当我向控制器添加 PreAuthorize 注释时,视图方法工作正常,PreAuthorize 标记仅授予具有 ADMIN 权限的用户访问权限,但 ResponseBody 方法 (getFoo) 无法按预期工作。

使用 PreAuthorize 注解时,getFoo 方法无法正确自动装配/实例化 fooService 对象,该对象的值为 null 会导致 NPE(空指针异常)。

问题概述: 当 AJAX GET 请求调用 getFoo 方法时,fooService 为 null(导致 NPE)。

但是,当注释掉@PreAuthorize 时,调用getFoo 时fooService 不再为null。

...

代码如下:

Foo 控制器

@Controller
@RequestMapping("/foo")
@PreAuthorize("hasAuthority(T(com.foo.security.Authorities).ADMIN)")
public class FooController {

    @Autowired
    private FooService fooService;

    @RequestMapping(value = "/view") 
    public String view(@AuthenticationPrincipal Principal principal) {
        return "view";
    }

    @RequestMapping(value = "/getFoo")
    @ResponseBody
    public Foo getFoo() {
        fooService.getFoo(); <- NPE happens here
    }
}

美食服务

@Service("fooService")
public class FooServiceImpl implements FooService {

    @Autowired
    FooRepository fooDao;

    @Override
    public Foo getFoo() {
        return fooDao.getFoo();
    }
}

安全配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter { ... }

【问题讨论】:

  • 我也面临同样的问题。你最后能解决问题吗?
  • 控制器方法之一可能是私有的
  • 我怀疑这是您拥有的确切代码。我怀疑实际方法getFooprivate 而不是public 或者甚至所有方法都是private 而不是public

标签: java spring spring-mvc spring-security


【解决方案1】:

似乎调用服务的线程没有正确的安全角色。

尝试移动 @PreAuthorize 注释以仅保护 view 方法。

另外,根据您的 cmets,我发现您的问题可能是您使用了两个不同的 bean 实例。检查您是否没有在上下文文件中重复定义。

【讨论】:

  • 我将 @PreAuthorize 注释移动到仅视图方法。当我调用视图方法时,只允许某些具有ADMIN权限的用户加载视图,这是正确的。但是,当我以具有 ADMIN 权限的用户身份加载到视图中,然后在前端对 getFoo 方法进行 ajax 调用时,AJAX get 请求返回 500 状态,因为由于 fooService 引发了 NPE在该方法中为空。这很奇怪,因为从视图方法中删除 PreAuthorize 标记然后允许 getFoo 方法工作。
  • 调试它并检查bean是否已经在视图方法中初始化
  • 在view方法中调试的时候,看到fooService的值为FooServiceImpl。但是在 getFoo 方法中调试时, fooService 的值为 null。
  • 这很奇怪,因为 fooService 自动装配正确,但是一旦我在任何方法或 FooController 类本身上引入 @PreAuthorize 注释,我就会遇到 fooService 在getFoo 方法。如果我删除 PreAuthorize 标记,那么 getFoo 会使用 FooServiceImpl 的值正确初始化 fooService。
  • 查看我的编辑。也许你应该调试 bean 实例化。我打赌你有两个豆子
【解决方案2】:

确保所有使用@RequestMapping 注释的控制器方法都没有声明为私有

【讨论】:

  • 非常感谢你,你解决了我的问题 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-04
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多