首页 > 解决方案 > spring-boot 错误 org.springframework.security.core.userdetails.User 无法转换为 in.cad.security.model.MyUserPrincipal 类

问题描述

我对 Spring Boot 完全陌生,并尝试编写单元测试用例,但完全卡住了,无法理解身份验证的工作原理。

控制器类

@PostMapping (path = "/createConcept")
@ApiOperation(value = "Composite object with conceptCO with added roles",
        response = ConceptCO.class)
public ConceptCO createConcept(
        @RequestBody final ConceptFormVO conceptFormVO,
        @ApiIgnore Authentication authentication
) {
    ConceptDTO conceptDTO = new ConceptDTO();
    BeanUtils.copyProperties(conceptFormVO, conceptDTO,
            AppUtils.getNullPropertyNames(conceptFormVO));
    LOGGER.info("Input Config : ::{}", conceptFormVO);
    List<UserPrincipalAttributes> cadenzPrincipalAttributesList = PrincipalUtil.getRoles(authentication);
    String token = PrincipalUtil.getToken(authentication);
    return conceptDelegate.createConcept(conceptDTO,cadenzPrincipalAttributesList,token);
}

PrincipalUtil.java

public final class PrincipalUtil {

public static final String BEARER_TOKEN = "Bearer ";

public static List<UserPrincipalAttributes> getRoles(final Authentication authentication) {
    UserPrincipal user =
            (UserPrincipal) authentication.getPrincipal();
    return new ArrayList<>(user.getUserPrincipalAttributes());
}

public static String getToken(final Authentication authentication) {
    UserPrincipal user =
            (UserPrincipal) authentication.getPrincipal();
    String finalToken = BEARER_TOKEN + user.getToken();
    return finalToken;
  }
}

用户主体.java

public class UserPrincipal implements AuthenticatedPrincipal {
    private String name;
    private Set<UserPrincipalAttributes> userPrincipalAttributes;
    private String token;
    // getter & setters
    }

用户主体属性 .java

public class UserPrincipalAttributes {
    Set<String> columns;
    Set<String> concepts;
    String role;
    // getter & setters
}

下面是我的测试功能

private Authentication authentication = SecurityContextHolder.getContext()
            .getAuthentication();

private static final String BASE_URL = "/xyz";

    @Before
    public void setup() throws Exception {
        mvc = MockMvcBuilders
                .webAppContextSetup(this.wac)
                .apply(SecurityMockMvcConfigurers.springSecurity())
                .build();

    }

    @Test
    @WithMockUser(username = "test_user1")
    public void createConceptTest() throws Exception {

        ConceptFormVO conceptFormVO = new ConceptFormVO();
        conceptFormVO.setConceptExpression("payment_cat = ABC");
        conceptFormVO.setConceptName("all_subsc_test");

        RequestBuilder createConceptRequest = post(BASE_URL + "/createConcept",authentication)
                .header("Authorization",
                        String.format("Bearer %s", accessToken))
                .content(objectMapper.writeValueAsString(conceptFormVO))
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON);
        this.mvc
                .perform(createConceptRequest)
                .andExpect(status().isOk())
    }

在测试用例之上运行给了我错误

java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to in.at.security.model.UserPrincipal
    at in.at.security.util.PrincipalUtil.getRoles(PrincipalUtil.java)

为愚蠢的错误道歉。

标签: springspring-bootunit-testingjunitspring-security

解决方案


而不是通过Authentication你可以直接注入AuthenticatedPrincipal参考下面的代码让我知道它是否有效,

import java.util.Collection;
import java.util.Map;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;


public class SampleController {
@PostMapping (path = "/createConcept")
public SampleController createConcept(
        @RequestBody final ConceptFormVO conceptFormVO,
        @AuthenticationPrincipal OAuth2User principal 
) {
    Map<String, Object> principalDetails = principal.getAttributes();
    Collection<? extends GrantedAuthority> authorities = principal.getAuthorities();
    .....
}
}

推荐阅读