67

I'm using Spring Security 3 and Spring MVC 3.05.

I would like to print username of currently logged in user,how can I fetch UserDetails in my Controller?

@RequestMapping(value="/index.html", method=RequestMethod.GET)
    public ModelAndView indexView(){
         UserDetails user = ?
                mv.addObject("username", user.getUsername());
        ModelAndView mv = new ModelAndView("index");
        return mv;
    }   
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
danny.lesnik
  • 18,479
  • 29
  • 135
  • 200

6 Answers6

123

If you already know for sure that the user is logged in (in your example if /index.html is protected):

UserDetails userDetails =
 (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

To first check if the user is logged in, check that the current Authentication is not a AnonymousAuthenticationToken.

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (!(auth instanceof AnonymousAuthenticationToken)) {
        // userDetails = auth.getPrincipal()
}
sourcedelica
  • 23,940
  • 7
  • 66
  • 74
  • 14
    this gives me an exception: `java.lang.ClassCastException: java.lang.String cannot be cast to org.springframework.security.core.userdetails.UserDetails` – fresh_dev Oct 26 '11 at 16:45
  • 1
    I use UsernamePasswordAuthenticationToken for my authentication, and that returns a String even for a logged in user. The object returned may vary depending on the type of Authentication used; cast your class as appropriate, for me it is String. – Erica Kane Jan 18 '15 at 21:44
  • I believe this is not the best method due to SecurityContextHolder using ThreadLocal underneath (see this question http://stackoverflow.com/questions/609826/performance-of-threadlocal-variable ). Unless someone could provide some actual benchmark for this method (because there are also other strategies than simple ThreadLocal, but I have not tested them) I'd advise going with Farm's answer instead. – Michal M Feb 12 '15 at 16:26
  • If principal is String, you can use SecurityContextHolder.getContext().getAuthentication().getDetails(). It works at least for Spring Security Saml this way. – csviri Apr 06 '17 at 12:58
34

Let Spring 3 injection take care of this.

Thanks to tsunade21 the easiest way is:

 @RequestMapping(method = RequestMethod.GET)   
 public ModelAndView anyMethodNameGoesHere(Principal principal) {
        final String loggedInUserName = principal.getName();

 }
Community
  • 1
  • 1
Farm
  • 3,356
  • 2
  • 31
  • 32
  • Amazing. Makes testing much easier than when using static methods on SecurityContextHolder. – Planky Jul 15 '16 at 20:41
4

If you just want to print user name on the pages, maybe you'll like this solution. It's free from object castings and works without Spring Security too:

@RequestMapping(value = "/index.html", method = RequestMethod.GET)
public ModelAndView indexView(HttpServletRequest request) {

    ModelAndView mv = new ModelAndView("index");

    String userName = "not logged in"; // Any default user  name
    Principal principal = request.getUserPrincipal();
    if (principal != null) {
        userName = principal.getName();
    }

    mv.addObject("username", userName);

    // By adding a little code (same way) you can check if user has any
    // roles you need, for example:

    boolean fAdmin = request.isUserInRole("ROLE_ADMIN");
    mv.addObject("isAdmin", fAdmin);

    return mv;
}

Note "HttpServletRequest request" parameter added.

Works fine because Spring injects it's own objects (wrappers) for HttpServletRequest, Principal etc., so you can use standard java methods to retrieve user information.

L'sync
  • 149
  • 3
  • 10
1

if you are using spring security then you can get the current logged in user by

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
     String name = auth.getName(); //get logged in username
Kerem Baydoğan
  • 10,475
  • 1
  • 43
  • 50
amit
  • 89
  • 1
  • 13
1

That's another solution (Spring Security 3):

public String getLoggedUser() throws Exception {
    String name = SecurityContextHolder.getContext().getAuthentication().getName();
    return (!name.equals("anonymousUser")) ? name : null;
}
Alexey Nikitenko
  • 2,047
  • 2
  • 20
  • 30
0

You can use below code to find out principal (user email who logged in)

  org.opensaml.saml2.core.impl.NameIDImpl principal =  
  (NameIDImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

  String email = principal.getValue();

This code is written on top of SAML.