Abhishek Tiwari
Abhishek Tiwari

Reputation: 21

spring-boot error org.springframework.security.core.userdetails.User cannot be cast to in.cad.security.model.MyUserPrincipal class

I am completely new to spring boot and trying to write Unit test cases but stuck completely and not able to understand how Authentication works.

Controller class

@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;
  }
}

UserPrincipal.java

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

UserPrincipalAttributes .java

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

Below is my test function

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())
    }

Running above test case gives me error

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)

Apologies for silly mistakes.

Upvotes: 1

Views: 1481

Answers (1)

Amit Kumar Lal
Amit Kumar Lal

Reputation: 5789

instead of passing Authentication u can directly inject AuthenticatedPrincipal refer below code let me know if it works,

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();
    .....
}
}

Upvotes: 1

Related Questions