具有JPre的@PreAuthorize的测试服务方法

时间:2019-01-29 15:55:06

标签: java spring spring-boot junit spring-security

在Spring Boot 1.4.1中,我想对使用@PreAuthorize进行限制访问的服务方法进行单元测试(而不是集成测试)。

问题是从Eclipse启动测试独奏时似乎未检查@PreAuthorize(尚未尝试使用mvn test)。

然后,如果我奇迹般地设法正确运行测试,我将尝试使用StudyService接口,而不是impl。

这是我的考试课:

@RunWith(MockitoJUnitRunner.class)
public class TestMethodSecurity {

    private static final Long STUDY_ID = 1L;

    @Mock
    private StudyRepository studyRepository;

    @InjectMocks
    private StudyServiceImpl studyService;


    @Before
    public void setup() {
        given(studyRepository.findOne(STUDY_ID)).willReturn(ModelsUtil.createStudy());
    }


    @Test
    public void findByIdWithoutAccessRightTest() {
        Study study = studyService.findById(STUDY_ID);
    }
}

这是服务:

@Service
public class StudyServiceImpl implements StudyService {


    @Autowired
    private StudyRepository studyRepository;


    @Override
    @PreAuthorize("hasAnyRole('DOES NOT EVENT CHECK SYNTAX")
    public Study findById(final Long id) {
        return studyRepository.findOne(id);
    }

}

测试成功,这是失败的。

3 个答案:

答案 0 :(得分:0)

如果要测试Spring Security批注,则需要使用SpringRunner来创建Spring Context并将Spring Security代码注入代理类。

如何测试Spring Security,您可以找到here

答案 1 :(得分:0)

注释测试类
@RunWith(SpringRunner.class)
@ContextConfiguration

您的方法应如下所示

@Test(expected = AccessDeniedException.class)
@WithAnonymousUser
@Test
    public void findByIdWithoutAccessRightTest() {
        Study study = studyService.findById(STUDY_ID);
    }

您必须至少加载安全上下文才能测试安全性。

您可能想看一下这个例子:

public ApplicationUser getApplicationUser() {
    ApplicationUser applicationUser = (ApplicationUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    return applicationUser;
}

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.mock;
import org.mockito.MockitoAnnotations;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import com.arpit.security.user.ApplicationUser;

public class BaseTest {

    @Before
    public void setupMock() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void mockApplicationUser() {
        ApplicationUser applicationUser = mock(ApplicationUser.class);
        Authentication authentication = mock(Authentication.class);
        SecurityContext securityContext = mock(SecurityContext.class);
        when(securityContext.getAuthentication()).thenReturn(authentication);
        SecurityContextHolder.setContext(securityContext);
        when(SecurityContextHolder.getContext().getAuthentication().getPrincipal()).thenReturn(applicationUser);
    }

}

来自:https://www.javacodegeeks.com/2017/05/mocking-spring-security-context-unit-testing.html

我想您的服务方法故意存在语法错误? (缺少括号和错误的引号?)

答案 2 :(得分:0)

这就是我的工作方式:

@RunWith(SpringRunner.class)
@SpringBootTest
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ActiveProfiles("test")
public class StudySecurityTest {

    @Autowired
    private StudyService service;

    @MockBean
    private StudyRepository repository;

    @Test
    @WithAnonymousUser
    public void testAsAnonymous() {
        ...
    }

    @Test
    @WithMockKeycloakUser(id = LOGGED_USER_ID, username = LOGGED_USER_USERNAME, authorities = { "ROLE_USER" })
    public void testAsUser() {
        ...
    }
}

如果您在@WithMockKeycloakUser中被打扰了,问我。