Getting the Spring Security Principal in a Spring MVC Controller method

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>
Advertisements
This entry was posted in Spring, Spring MVC, Spring Security and tagged , , , , , . Bookmark the permalink.

16 Responses to Getting the Spring Security Principal in a Spring MVC Controller method

  1. Pingback: When the Spring Security Principal isn’t enough in a Spring MVC Controller | Java Ninja Chronicles By Norris Shelton, Jr

  2. Dan Ertman says:

    Thank you! Saved me some time.

  3. Daniel says:

    Hi, thanks for the post. How would the xml configuration be if I don’t want to use the @EnableWebMvcSecurity annotation? My whole project is using xml config and I’d prefer not to switch for the moment…

  4. Fantastic goods from you, man. I have understand your stuff previous
    to and you’re just extremely excellent. I really like what you’ve acquired here,
    certainly like what you’re stating and the way in which you say it.
    You make it enjoyable and you still take care of to keep it
    wise. I can’t wait to read much more from you. This is actually a
    great web site.

  5. Gaurav says:

    Thanks for the post helped in solving a problem just now đŸ˜€ !

  6. joe says:

    Thanks for the article. I keep on getting:

    WARNING: Your mvc.xml isn’t set up! You need org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver in mvc:annotation-driven

    even though it is set up as you said. Any ideas on this?

    • If you are thinking that the mvc.xml contains the spring mvc configuration, then it isn’t required to be named that. The spring context is necessary, but there is no requirement on the name. The convention is that the name of the dispatcher server is combined with “-servlet.xml” to find the name. You can specify an alternate name if you want.

      • joe says:

        Thanks Norris. Here is what’s interesting: I’m using Spring Social for oauth login. When I login with Facebook, it works (it finds the principal). When I login using the Google plugin, it fails with that error! I can’t even find where in the Spring source that warning is being generated. Very strange and frustrating. I suppose I could remove all my use of that annotation, but I would prefer to figure out how to fix this. I’ll post here if I get some ideas.

      • I’m sorry, I have not used Spring Social. Maybe try the Spring Forums. The developers there are usually very helpful.

    • joe says:

      Hi Norris, it was an unrelated bug in my code, and that error message was from somewhere in my code! This bug had nothing to do with Spring.

      I think I actually don’t need that bit of XML because I have a configuration class with @EnableWebMvcSecurity, and I think that automatically installs both the authentication principal resolver, and also the CSRF prevention bean.

  7. vahapt says:

    Great, the post made the configuration a piece of cake

  8. Mr. Burns says:

    I am developing my first Spring+Hibernate project. I am using XML configuration and run into this post. I followed every step but I’ve got an exception when executing the method (within @Controller) which includes “@AuthenticationPrincipal User userDetails” as method argument. It says this:

    Could not instantiate bean class [org.springframework.security.core.userdetails.User]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.security.core.userdetails.User.() […]

    I understand what’s going on: User (Spring’s implementation of UserDetails) does not have default constructor. The problem is that I don’t know how to fix this.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s