Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I am using Spring security version 3.1.4.RELEASE.
How can I access the current logged in user object?
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
returns user name, not user object. So how can I use the returned Username and get the UserDetails object?
I have tried the following code:
public UserDetails getLoggedInUser(){
final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated() && !(auth instanceof AnonymousAuthenticationToken))
if(auth.getDetails() !=null)
System.out.println(auth.getDetails().getClass());
if( auth.getDetails() instanceof UserDetails)
System.out.println("UserDetails");
System.out.println("!UserDetails");
return null;
Following is the result:
[2015-08-17 19:44:46.738] INFO http-bio-8443-exec-423 System.out class org.springframework.security.web.authentication.WebAuthenticationDetails
[2015-08-17 19:44:46.738] INFO http-bio-8443-exec-423 System.out !UserDetails
AuthenticationFilter class as follows:
public class CustomUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
private boolean postOnly = true;
public CustomUsernamePasswordAuthenticationFilter() {
super("/j_spring_security_check");
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
if (password == null) {
password = "";
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
if(this.getAuthenticationManager()==null){
logger.info("Authentication manager is null.");
} else {
logger.info("Authentication manager was "+this.getAuthenticationManager().getClass().getName());
return this.getAuthenticationManager().authenticate(authRequest);
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
public void setUsernameParameter(String usernameParameter) {
this.usernameParameter = usernameParameter;
public void setPasswordParameter(String passwordParameter) {
this.passwordParameter = passwordParameter;
public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
public final String getUsernameParameter() {
return usernameParameter;
public final String getPasswordParameter() {
return passwordParameter;
AuthenticationProvider as follows:
@Component
public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
private MyUserDetailsService userDetailsService;
public MyUserDetailsService getUserDetailsService() {
return userDetailsService;
public void setUserDetailsService(MyUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
@Override
protected void additionalAuthenticationChecks(UserDetails arg0,
UsernamePasswordAuthenticationToken arg1)
throws AuthenticationException {
@Override
protected UserDetails retrieveUser(String arg0,
UsernamePasswordAuthenticationToken arg1)
throws AuthenticationException {
return userDetailsService.loadUserByUsername(arg0);
UserDetails class as follows:
public class MyUserDetailsService implements UserDetailsService {
private final Map<String, UserDetails> usersList;
public MyUserDetailsService() {
Collection<GrantedAuthority> authorityList;
final SimpleGrantedAuthority supervisorAuthority = new SimpleGrantedAuthority("supervisor");
final SimpleGrantedAuthority userAuthority = new SimpleGrantedAuthority("user");
usersList = new TreeMap<String, UserDetails>();
authorityList = new ArrayList<GrantedAuthority>();
authorityList.add(supervisorAuthority);
authorityList.add(userAuthority);
usersList.put("admin", new User("admin", "admin", authorityList));
authorityList = new ArrayList<GrantedAuthority>();
authorityList.add(userAuthority);
usersList.put("peter", new User("peter", "password123", authorityList));
//probably don't use this in production
for(Map.Entry<String, UserDetails> user : usersList.entrySet()){
logger.info(user.getValue().toString());
@Override
public UserDetails loadUserByUsername(String username)throws UsernameNotFoundException {
UserDetails ud = usersList.get(username);
if (ud != null) {
logger.info("loadUserByUsername: found match, returning "
+ ud.getUsername() + ":" + ud.getPassword() + ":"
+ ud.getAuthorities().toString());
return new User(ud.getUsername(), ud.getPassword(),
ud.getAuthorities());
logger.info("loadUserByUsername: did not find match, throwing UsernameNotFoundException");
throw new UsernameNotFoundException(username);
–
–
–
–
Returns the current user object. This can be User
, UserDetails
or your custom user object.
You will need to cast the return object to UserDetails
or your own user object if it is a custom one.
OR you can inject Authentication
or Principal
directly in to your controllers.
Principle is your UserDetails
/custom user object.
Note: UserDetails
is an interface
–
you can use it like
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
String username = ((UserDetails)principal).getUsername();
} else {
String username = principal.toString();
it is in spring security reference http://docs.spring.io/spring-security/site/docs/4.0.2.RELEASE/reference/htmlsingle/#obtaining-information-about-the-current-user
–
You can simply inject the Authentication Interface to your Controller and get the username of the logged in user, like below:
@GetMapping(value = "/username")
@ResponseBody
public String currentUserName(Authentication authentication) {
if (authentication != null)
return authentication.getName();
return "";
You just went one step foo far. SecurityContextHolder.getContext().getAuthentication()
returns an Authentication
object. You should know how you authenticated the user, and what can the the concrete class implementing Authentication
. Assuming it is a subclass of AbstractAuthenticationToken
(all Spring provided implementation are), and getDetails()
returns a UserDetails
, you can just use:
AbstractAuthenticationToken auth = (AbstractAuthenticationToken)
SecurityContextHolder.getContext().getAuthentication();
UserDetails details = (UserDetails) auth.getDetails();
I solved this problem by using SecurityContextHolder
and Authentication.getName()
:
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String login = authentication.getName();
User user = usersService.getUserByLogin(login);
Since version 5.2 you can use CurrentSecurityContext annotation to get the current user authentication:
@GetMapping("/authentication")
public Object authentication(@CurrentSecurityContext(expression="authentication")
Authentication authentication) {
return authentication.getDetails();
or even:
@GetMapping("/hello")
public String hello(@CurrentSecurityContext(expression="authentication.name")
String username) {
return "Hello, " + username + "!";
If you want to get all the attributes of your current user , first go to the class that implements UserDetails
, more likely its called UserPrincipal
and write a get method for each attribute like : getAge()
, seconde go to you HTML file and write this
<span th:text="${#request.userPrincipal.principal.age}> </span>
And by the way you dont need to add any ModelAttribute in your controller
Hope it fix the problem , and you can ask me
–
–
–
–
you need to downcast principal to its implemented class, then you can extract context object which you set in securityContext.
AbstractAuthenticationToken a = (AbstractAuthenticationToken) request.getUserPrincipal();
UserContext context = (UserContext) a.getPrincipal();
This solution worked for me with spring boot 2.5
First, define a User
Principal
class
public class UserPrincipal implements UserDetails {
private static final long serialVersionUID = 1L;
private User user;
public User getUser() {
return user;
public void setUser(User user) {
this.user = user;
// other methods ....
Second, define a User
class:
public class User {
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String username;
String password;
//getters ans setters ...
Third, define a UserAuth
class:
public class UserAuth {
public String getUsername()
UserPrincipal principal
= (UserPrincipal)SecurityContextHolder
.getContext()
.getAuthentication()
.getPrincipal();
return principal.getUser().getUsername();
Finally, you can auto-wire the UserAuth
class as needed.
assuming you have a custom user implementing UserDetails class
@RestController
@RequestMapping("/api/user")
class UsersController {
@GetMapping
public User fetchUser(@AuthenticationPrincipal User user) {
return user;
So almost every answer seems correct and feasible, kudos to all contributors, but to remove boilerplate code, could be useful and easy:
make an Interface and its implementation that will contain all utility methods, and then simply @Autowire
that.
public interface AuthHelper {
Authentication getAuthentication();
public String getName();
public UserDetails getUserDetails()
@Component
public class AuthHelperImpl implements AuthHelper {
@Override
public Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
public String getName() {
return getAuthentication().getName();
public UserDetails getUserDetails() {
return (UserDetails) getAuthentication().getPrincipal();
//and more utilities you need
//you can also cast with UserPrincipal
now, at controllers:
@Controller
public class DemoController {
@Autowired
private AuthHelper authHelper;
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserNameSimple() {
return authHelper.getName;
This may be a good article to read.
The article shows how to get the user information in a Spring application, starting with the common static access mechanism, followed by several better ways to inject the principal.
https://www.baeldung.com/get-user-in-spring-security
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.