Springboot get username from Authentication via Controller

46,233

Solution 1

I think you can use authentication.getName and principal.getName in the injected controller argument of type Authentication and Principal:

@Controller
@RequestMapping("/info")
public class GetNameController {

    @RequestMapping(value = "/name", method = RequestMethod.GET)
    public String getName(Authentication authentication, Principal principal) {
        System.out.println(authentication.getName());
        System.out.println("-----------------");
        System.out.println(principal.getName());
        return "";
    }
}

could produce

admin
-----------------
admin

Solution 2

It doesn't matter whether you are using token or basic spring security authentication as far as Authentication/Principal object is concerned.

In case of spring security, you can get your current logged in user by
1. Object user = Authentication authentication (as you are already doing)
2.

Object user = SecurityContextHolder.getContext().getAuthentication()
                    .getPrincipal();

In both cases, user will contains the user object you returning from UserDetailsService.loadUserByUsername(...). So using default UserDetailsService you will get spring security's User object which contains basic user information like username, password etc.

So in case if you are using default spring's UserDetailsService, then you can get your current logged in user simply by

UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication()
                        .getPrincipal();
String username = userDetails.getUsername();

Solution 3

You can use

import org.springframework.security.core.Authentication;

import org.springframework.security.core.context.SecurityContextHolder;

Authentication auth = SecurityContextHolder.getContext().getAuthentication();



   System.out.println("--------------------------------------------------------------");
    JwtUser jwtUser = (JwtUser) auth.getPrincipal();
    
    //Get the username of the logged in user: getPrincipal()
    System.out.println("auth.getPrincipal()=>"+jwtUser.getUsername() );
    //Get the password of the authenticated user: getCredentials()
    System.out.println("auth.getCredentials()=>"+auth.getCredentials());
    //Get the assigned roles of the authenticated user: getAuthorities()
    System.out.println("auth.getAuthorities()=>"+auth.getAuthorities());
    //Get further details of the authenticated user: getDetails()
    System.out.println("auth.getDetails()=>"+auth.getDetails());
    System.out.println("--------------------------------------------------------------");
Share:
46,233
Borgy Manotoy
Author by

Borgy Manotoy

Updated on May 09, 2020

Comments

  • Borgy Manotoy
    Borgy Manotoy almost 4 years

    Problem: I would like to get/extract the username/email only from authenticate.getName()... if possible, not by using parsing the string.

    authentication.getName() or principal.getName() values:

    [username]: org.springframework.security.core.userdetails.User@21463e7a: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities
    

    In this example, I would like to get only the value of Username which is [email protected]

    Solution:

    Since I only want to get the username/email ([email protected]), and it is returning the whole principal content/text (above), I replaced the value I set in the subject from the pricipal value... to the email value.. and it works now.

    @Override
    protected void successfulAuthentication(HttpServletRequest req,
                                            HttpServletResponse res,
                                            FilterChain chain,
                                            Authentication auth) throws IOException, ServletException {
        String email = auth.getName();
        String principal = auth.getPrincipal().toString();
        Date expiration = new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME);
        String token = Jwts.builder()
                .setSubject(email) //from principal to email
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS512, SecurityConstants.SECRET.getBytes())
                .compact();
        AuthenticatedUser loginUser = new AuthenticatedUser(email);
        loginUser.setToken(token);
        String jsonUser = Util.objectToJsonResponseAsString(loginUser, "user");
        res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
        res.setContentType("application/json");
        res.setCharacterEncoding(ConstantUtil.DEFAULT_ENCODING);
        res.getWriter().write(jsonUser);
    }
    

    I can now get the username/email value using different ways like the one you guys are suggesting... even the one I am currently using. I do not need any special parsing now just to get the email value from the Authentication object.

    On my previous non RESTful application using Spring... I can easily get the username using Authentication class injected in the controller method parameter.

    Controller:

    ...  
    public Ticket getBySwertresNo(Authentication authentication, @PathVariable String swertresNo) {  
        logger.debug("Inside getBySwertresNo: " + swertresNo);  
        System.out.println("\n[username]: " + authentication.getName() + "\n");  
        return m_sugalService.getSwertresInfoBySwertresNo(swertresNo);  
    }  
    ...  
    

    Console:

    [username]: [email protected]
    

    Now, on my current project... I used a RESTful approach and after successful authentication, I am returning a token which will be used/injected in the request header. I can login using the token... but when I get the value of authentication.getName()... the return is not just the email address but it contains some other information.

    Console (REST + JWT):

    [username]: org.springframework.security.core.userdetails.User@21463e7a: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities
    

    I would like to get only the username value which is "[email protected]".

    JWT Authentication Filter:

    public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    
        private AuthenticationManager authenticationManager;
    
        public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
            this.authenticationManager = authenticationManager;
        }
    
        @Override
        public Authentication attemptAuthentication(HttpServletRequest req,
                                                    HttpServletResponse res) throws AuthenticationException {
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
            Authentication authentication = authenticationManager.authenticate(authenticationToken);
            return authentication;
        }
    
        @Override
        protected void successfulAuthentication(HttpServletRequest req,
                                                HttpServletResponse res,
                                                FilterChain chain,
                                                Authentication auth) throws IOException, ServletException {
            String email = auth.getName();
            String principal = auth.getPrincipal().toString();
            Date expiration = new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME);
            String token = Jwts.builder()
                    .setSubject(principal)
                    .setExpiration(expiration)
                    .signWith(SignatureAlgorithm.HS512, SecurityConstants.SECRET.getBytes())
                    .compact();
            AuthenticatedUser loginUser = new AuthenticatedUser(email);
            loginUser.setToken(token);
            String jsonUser = Util.objectToJsonResponseAsString(loginUser, "user");
            res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
            res.setContentType("application/json");
            res.setCharacterEncoding(ConstantUtil.DEFAULT_ENCODING);
            res.getWriter().write(jsonUser);
        }
    
    }
    

    JWT Authorization Filter:

    public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
    
        public JWTAuthorizationFilter(AuthenticationManager authManager) {
            super(authManager);
        }
    
        @Override
        protected void doFilterInternal(HttpServletRequest req,
                                        HttpServletResponse res,
                                        FilterChain chain) throws IOException, ServletException {
            String header = req.getHeader(SecurityConstants.HEADER_STRING);
    
            if (header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX)) {
                chain.doFilter(req, res);
                return;
            }
    
            UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
    
    SecurityContextHolder.getContext().setAuthentication(authentication);
            chain.doFilter(req, res);
        }
    
        private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
            String token = request.getHeader(SecurityConstants.HEADER_STRING);
            if (token != null) {
                // parse the token.
                String user = Jwts.parser()
                        .setSigningKey(SecurityConstants.SECRET.getBytes())
                        .parseClaimsJws(token.replace(SecurityConstants.TOKEN_PREFIX, ""))
                        .getBody()
                        .getSubject();
    
                if (user != null) {
                    return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
                }
                return null;
            }
            return null;
        }
    
    }
    
  • Borgy Manotoy
    Borgy Manotoy about 6 years
    Cannot cast to User
  • Borgy Manotoy
    Borgy Manotoy about 6 years
    Same results: org.springframework.security.core.userdetails.User@21463e7a: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities