Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

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

  • […] I had previously made a blog entry to retrieve the spring security principal via @AuthenticationPrincipal in a controller method. Getting the Spring Security Principal in a Spring MVC Controller method. […]

  • Dan Ertman says:

    Thank you! Saved me some time.

  • 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…

  • 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.

  • Gaurav says:

    Thanks for the post helped in solving a problem just now 😀 !

  • 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.

    • 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.

  • vahapt says:

    Great, the post made the configuration a piece of cake

  • 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.

  • With Spring 4 the org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver is deprecated; use org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver instead.

Leave a Reply

Your email address will not be published. Required fields are marked *

LinkedIn Auto Publish Powered By : XYZScripts.com