关于使用 Spring Security测试的documentation编写针对 Spring Security 后面的spring MVC应用程序的测试。
这是采用典型弹簧安全布线的香草弹簧靴应用。这是主要的Application.java
@SpringBootApplication
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
这里是弹簧安全的接线:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("customUserDetailsService")
UserDetailsService userDetailsService;
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/","/sign_up").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.csrf()
.and()
.exceptionHandling()
.accessDeniedPage("/access_denied")
.and()
.logout()
.permitAll();
}
}
正如您所看到的,除了" /"之外,所有请求都需要进行身份验证。和" / sign_up"。我已通过部署应用程序验证了身份验证方案正常工作。
现在出现了一个有趣的部分:编写spring mvc测试。我提供的link提供了一些很好的方法来编写这样的测试,其中 spring-security-test 框架允许插入模拟用户/安全上下文。我采取了
的方法1.的代码如下:
@WithSecurityContext(factory=WithMockUserDetailsSecurityContextFactory.class)
public @interface WithMockUserDetails {
String firstName() default "apil";
String lastName() default "tamang";
String password() default "test";
long id() default 999;
String email() default "apil@test.com";
}
2.的代码如下:
final class WithMockUserDetailsSecurityContextFactory
implements WithSecurityContextFactory<WithMockUserDetails>{
@Override
public SecurityContext createSecurityContext(WithMockUserDetails mockUserDetails) {
/*
* Use an anonymous implementation for 'UserDetails' to return a
* mock authentication object, which is then set to the SecurityContext
* for the test runs.
*/
UserDetails principal=new UserDetails() {
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
//another anonmyous interface implementation.
GrantedAuthority auth=new GrantedAuthority() {
@Override
public String getAuthority() {
return "ROLE_USER";
}
};
List<GrantedAuthority> authorities=new ArrayList<>();
authorities.add(auth);
return authorities;
}
@Override
public String getPassword() {
return mockUserDetails.password();
}
@Override
public String getUsername() {
return mockUserDetails.email();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
};
Authentication authentication=new
UsernamePasswordAuthenticationToken(principal,principal.getPassword(),principal.getAuthorities());
SecurityContext context= SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
return context;
}
}
最后,这是测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {Application.class})
@WebAppConfiguration
public class UserControllerTest {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup(){
mvc= MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build();
}
@Test
public void testRootIsOk() throws Exception {
mvc.perform(get("/"))
.andExpect(status().isOk());
}
@Test
public void expectRedirectToLogin() throws Exception {
mvc.perform(get("/testConnect"))
.andExpect(redirectedUrl("http://localhost/login"));
}
@Test
@WithMockUserDetails
public void testAuthenticationOkay() throws Exception {
mvc.perform(get("/testConnect"))
.andExpect(content().string("good request."));
}
}
测试运行的输出:
由于“安全上下文”&#39;很可能测试3失败了。从未适当填充。根据文档,它应该有效。不确定我错过了什么。非常感谢任何帮助。
答案 0 :(得分:2)
您需要添加
$account = new AdAccount('act_' . $account_id);
$fields = array(
CampaignFields::ID,
CampaignFields::NAME,
CampaignFields::START_TIME,
CampaignFields::STOP_TIME,
CampaignFields::SPEND_CAP,
'effective_status'
);
$params = array(
'effective_status' => array(
Campaign::STATUS_ACTIVE
),
);
$campaignSets = $account->getCampaigns($fields, $params);
到自定义注释,以便在运行时保留注释信息。否则WithSecurityContextTestExecutionListener
无法检测到您的注释。