【问题标题】:How to inject Authentication in mvcmock unit testing如何在 mvc 模拟单元测试中注入身份验证
【发布时间】:2016-08-15 07:31:42
【问题描述】:

概述

我有一个带有注入身份验证的 REST 服务,我想使用 mockmvc 为它创建一个单元测试。我的 RestController 类如下:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.blss.security.securityCommon.entities.SecureOperatorDetails;
import com.blss.security.securityGateway.providers.AccAuthenticationProvider;

import lombok.Data;

@RestController
@RequestMapping("/gateway")
public class AuthenticationDetailsRestController {

    @RequestMapping(value = "/userdetails", method = RequestMethod.GET)
    public UserDetailsResource currentUserName(Authentication authentication) {

        ArrayList<String> rolesList = new ArrayList<>();
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        authorities
            .forEach(a -> {
                if (!a.getAuthority().startsWith(
                    AccAuthenticationProvider.CAD_TOKEN_AUTHORITY_PREFIX)) {
                    rolesList.add(a.getAuthority());
                }
            });

        SecureOperatorDetails operator = ((SecureOperatorDetails) authentication.getDetails());

        return new UserDetailsResource(
                authentication.getName(),
                operator.getOperator().getName(),
                operator.getOperator().getPermittedRetailerIds(),
                operator.getOperator().getStores(),
                operator.getOperator().getRetailerId(),
                operator.getDefaultStoreId(),
                operator.getDeviceId(),
                rolesList);
    }

    @Data
    static class UserDetailsResource {
        private final String username;
        private final String name;
        private final Set<String> retailerIds;
        private final Set<String> stores;
        private final String retailerId;
        private final String storeId;
        private final String deviceId;
        private final ArrayList<String> roles;
    }
}

问题

我不知道如何模拟身份验证并将其注入我的测试类以避免 401 http 异常完全身份验证需要访问此资源

如果有人能帮我解决这个问题,我将不胜感激

【问题讨论】:

  • 绕过认证?听起来很可疑。

标签: java spring unit-testing authentication mockmvc


【解决方案1】:

您可以使用org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers 配置身份验证模拟

然后你应该像下一步一样初始化它:

private MockMvc mockMvc;

@Override
protected void before() {
    this.mockMvc = webAppContextSetup(context).apply(SecurityMockMvcConfigurers.springSecurity()).build();
}

【讨论】:

    【解决方案2】:

    我将以下代码 sn-ps 添加到我的测试类中,然后正确注入了身份验证:

    1. 添加此项以获得自定义身份验证:

      private MockMvc mockMvc;
      
      @Autowired
      private Authentication authentication;   
      @Bean
      public Authentication authentication() {
          Collection<GrantedAuthority> authorities = new ArrayList<>();
          authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
          UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("customUsername", "customPassword", authorities); return authentication; }
      
      • 在设置方法中添加以下内容:

        @之前
        public void setUp() 抛出异常 {
        SecurityContextHolder.getContext().setAuthentication(authentication); mockMvc = MockMvcBuilders.webAppContextSetup(context) .addFilter(新的 ShallowEtagHeaderFilter()) .apply(documentationConfiguration(restDocumentation)) .apply(springSecurity()) 。建造(); }


    注意事项:

    • springSecurity() 用于启用身份验证注入;否则,主类中的身份验证对象将为空(您为其编写的测试类)。

    • SecurityContextHolder.getContext().setAuthentication(authentication);用于注入定制的身份验证;否则,默认的将由 springSecurity() 注入

    【讨论】:

      猜你喜欢
      • 2016-04-04
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 2016-08-12
      • 2011-08-08
      • 2017-06-19
      • 2018-02-14
      • 2019-03-27
      相关资源
      最近更新 更多