通过Autowired注入SecurityContextHolder

时间:2017-06-30 12:18:35

标签: spring spring-boot spring-security spring-aop

我想使用Spring-AOP记录我的请求信息。之后我想通过测试来介绍这个场景。通常我会简单地使用SecurityContextHolder,但由于我在单元测试中没有弹簧上下文,我需要以某种方式模拟这个元素。因为我想避免模仿私有方法,所以我通过SecurityContextHolder通过Autowired注释,我不管怎么说,我已经把它变成了一个Singleton。

@PrepareForTest(SecurityContextHolder.class)
public class AuditLoggerTest extends PowerMockTestCase {

  @Mock
  AuditLogPersistenceService persistenceService;

  @Mock
  SecurityContextHolder securityContextHolder;

  @Mock
  SecurityContext securityContext;

  @Mock
  Authentication authentication;

  AuditLogger auditLogger;

  @BeforeClass
  public void setUp() {
    MockitoAnnotations.initMocks(this);
  }

  @BeforeMethod
  public void setUpBeforeEachTest(){
    auditLogger = new AuditLogger(persistenceService, securityContextHolder);
    Object principal = new String("123");
    PowerMockito.mockStatic(SecurityContextHolder.class);
    when(securityContextHolder.getContext()).thenReturn(securityContext);
    when(securityContext.getAuthentication()).thenReturn(authentication);
    when(authentication.getPrincipal()).thenReturn(principal);
  }

现在我的课程的启动就像这样

@Aspect
@Component
public class AuditLogger {

  private final AuditLogPersistenceService auditLogPersistenceService;

  private final SecurityContextHolder securityContextHolder;

  /**
   * Common constructor raising its beans
   * @param auditLogPersistenceService
   */
  @Autowired
  public AuditLogger(
      final AuditLogPersistenceService auditLogPersistenceService,
      final SecurityContextHolder securityContextHolder) {
    this.securityContextHolder = securityContextHolder;
    this.auditLogPersistenceService = auditLogPersistenceService;
  }

它在单元测试中工作正常,但是一旦我在功能测试中打开Spring上下文,它实际上通过restassured执行REST请求。我收到此错误消息。

Parameter 1 of constructor in com.service.audit.logging.AuditLogger required a bean of type 'org.springframework.security.core.context.SecurityContextHolder' that could not be found.

Consider defining a bean of type 'org.springframework.security.core.context.SecurityContextHolder' in your configuration.

我可以自动安装SecurityContextHolder还是必须使用Static实现?

1 个答案:

答案 0 :(得分:0)

总之,最简单的方法是将模拟的Context注入SecurityContextHolder,就像这样。然后SecurityContextHolder不再在构造函数中

public class AuditLoggerTest extends PowerMockTestCase {

      @Mock
      AuditLogPersistenceService persistenceService;

      @Mock
      SecurityContext securityContext;

      @Mock
      Authentication authentication;


      AuditLogger auditLogger;


      @BeforeClass
      public void setUp() {
        MockitoAnnotations.initMocks(this);
      }

      @BeforeMethod
      public void setUpBeforeTest(){
        auditLogger = new AuditLogger(persistenceService);
        SecurityContextHolder.setContext(securityContext);
        Object principal = new String("123");
        when(securityContext.getAuthentication()).thenReturn(authentication);
        when(authentication.getPrincipal()).thenReturn(principal);
      }
相关问题