使用 MockMvc 测试 spring 安全性时未调用自定义身份验证提供程序

mme*_*etu 7 java spring spring-boot

我正在尝试使用 spring 的 MockMvc 类在我的 spring 启动应用程序中测试我的 spring OAuth2 授权和身份验证。我面临的基本问题是,即使我将自定义身份验证提供程序注册为 Spring Security 使用的身份验证提供程序之一,也永远不会调用它。我遵循了此处此处找到的 spring 安全教程。

代码片段: 安全配置器类 - 这是添加自定义身份验证提供程序的地方。

@Configuration
@EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationProvider authenticationProvider;


    @Override
    public void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .httpBasic();
    }
}
Run Code Online (Sandbox Code Playgroud)

自定义身份验证提供程序 - 这应该进行实际的身份验证

@Component
public class UsernamePasswordAuthProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials()
                .toString();

        if ("test".equals(username) && "test".equals(password)) {
            Collection<? extends GrantedAuthority> grantedAuthorityList = authentication
                    .getAuthorities();
            return new UsernamePasswordAuthenticationToken
                    (username, password, grantedAuthorityList);
        } else {
            throw new
                    BadCredentialsException("External system authentication failed");
        }
    }

    @Override
    public boolean supports(Class<?> auth) {
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

Spring boot 集成测试 - 这是使用 Web 应用程序上下文实例化 MockMvc 的地方

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConfigurationServiceApplication.class)
public class SettingsAPITest {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext wac;

    @Autowired
    private FilterChainProxy springSecurityFilterChain;


    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
                .addFilter(springSecurityFilterChain).build();
    }


    @Test 
    public void testGetStatus() throws Exception {
        //execute test
        mockMvc.perform(get("/status")
                .with(httpBasic("test","test")))
                .andDo(print())
                .andExpect(status().isOk());
    }
}
Run Code Online (Sandbox Code Playgroud)

这是控制器

@RestController
public class StatusController{

    @RequestMapping(method = RequestMethod.GET)
    public ResponseEntity<String> getStatus(){

        return new ResponseEntity<>("I'm Ok", HttpStatus.OK);

    }
}
Run Code Online (Sandbox Code Playgroud)

运行测试返回 401 并设置断点并通过它进行调试显示从未使用自定义身份验证提供程序。

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /status
       Parameters = {}
          Headers = {Authorization=[Basic dGVzdDp0ZXN0]}

Handler:
             Type = null

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 401
    Error message = null
          Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate, no-store], Pragma=[no-cache, no-cache], Expires=[0], X-Frame-Options=[DENY], WWW-Authenticate=[Bearer realm="oauth2-resource", error="unauthorized", error_description="Full authentication is required to access this resource"], Content-Type=[application/json;charset=UTF-8]}
     Content type = application/json;charset=UTF-8
             Body = {"error":"unauthorized","error_description":"Full authentication is required to access this resource"}
    Forwarded URL = null    Redirected URL = null
          Cookies = []

java.lang.AssertionError: Status  Expected :200 Actual   :401
Run Code Online (Sandbox Code Playgroud)

我有一种感觉,我的 webapp 上下文配置在某处被 spring boot 覆盖(因为这里的大部分内容都是由 spring boot 自动配置的),但我无法证明这一点。任何帮助真的很感激!!谢谢

仅供参考,我看过相关帖子

小智 0

您可以尝试更改您的mockmvc初始化吗

@Before
public void setup() {
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
            .addFilter(springSecurityFilterChain).build();
}
Run Code Online (Sandbox Code Playgroud)

@Before
public void setup() {
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
            .apply(springSecurity()).build();
}
Run Code Online (Sandbox Code Playgroud)