Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

How do you mock a Springframework security principal for testing spring MVC controllers?

  1. Create a spring security principal
  2. Create a spring authentication
  3. Add the spring security authentication to the security context

The last step should not be needed because MockMVC has a method to set the principal (line 16). However, we had an annotation that used the security principal to retrieve the username that was then used to retrieve another object. We couldn’t find the value there. We set the spring security authentication manually via the spring security context (line 19).

public class TestActivityController {
    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

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

    @Test
    public void testInitialDisplay() throws Exception {
        User user = new User("screen011","", AuthorityUtils.createAuthorityList("ROLE_PATRON"));
        TestingAuthenticationToken testingAuthenticationToken = new TestingAuthenticationToken(user,null);
        SecurityContextHolder.getContext().setAuthentication(testingAuthenticationToken);

        mockMvc.perform(post("/activity/initial")
                //.principal(testingAuthenticationToken))
                .andExpect(status().isOk())
                .andDo(print());
    }
}

February 27th, 2014

Posted In: Java, MockMVC, Spring, Spring MVC, Spring Security

Tags: , , , , , , , , , , , , , ,

2 Comments

There will be sometimes in your code that you need access to the Springframework security principal object. Here is how you get it. You will need to create a Spring configuration class and annotate it with @EnableWebMvcSecurity

package com.cdi.igs.hub.spring;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;

/**
 * Spring Security configuration.
 * @author norris.shelton
 */
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // nothing needed here
}

The documentation then says to add a method parameter to a Spring MVC controller method with @AuthenticationPrincipal and you are done, like the following:

    @RequestMapping(value = "/{personId}", method = RequestMethod.GET)
    public ModelAndView getPersonAccount(@PathVariable int personId, @AuthenticationPrincipal User user) {
        ModelAndView modelAndView =  new ModelAndView("dashboard/account");
        modelAndView.addObject("person", personRepository.findOne(personId));
        return modelAndView;
    }

What they don’t tell you is that you need to configure a AuthenticationPrincipalArgumentResolver. Nor they tell you how to do it. This is the missing piece.

    <mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver"/>
        </mvc:argument-resolvers>
    </mvc:annotation-driven>

January 14th, 2014

Posted In: Spring, Spring MVC, Spring Security

Tags: , , , , ,

17 Comments

LinkedIn Auto Publish Powered By : XYZScripts.com