SoFunction
Updated on 2025-04-13

Several ways to obtain the information of the currently logged-in user

In Spring Security, the information of the currently logged-in user is actually stored in the SecurityContext bound to the current thread, and an Authentication object is saved. The writing methods you show are actually different ways to obtain this Authentication object or extract user information from it. The following details the principles and applicable scenarios of each method:

1. Inject Principal directly

@GetMapping("/welcome")
@ResponseBody
public Object toLoginInfo(Principal principal){
    return principal;
}

illustrate:

When you declare a directly in the Controller methodPrincipalWhen the parameter of type,Spring Security will automatically inject the corresponding corresponding to the current logged-in user.PrincipalObject. generally,PrincipalOnly the most basic user ID (such as username), but if more information is needed, you need to use itAuthentication

2. Direct injection of Authentication

@GetMapping("/welcome2")
@ResponseBody
public Object toLoginInfo2(Authentication authentication) {
    return authentication;
}

illustrate:AuthenticationThe interface is inherited fromPrincipal, in addition to the user name, it also contains the user's permission information (Authorities), authentication credentials, authentication status, etc. Direct injectionAuthenticationIt is one of the commonly used methods in actual development that can obtain richer information.

3. Inject UsernamePasswordAuthenticationToken

@GetMapping("/welcome3")
@ResponseBody
public Object toLoginInfo3(UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) {
    return usernamePasswordAuthenticationToken;
}
  • illustrate:UsernamePasswordAuthenticationTokenyesAuthenticationA common implementation of  , usually used when logging in based on form. In addition to saving username and password, it also saves user permissions and other information. Directly inject this type of parameters, and direct injectionAuthenticationSimilar, but the type is more specific.

4. Get it through SecurityContextHolder

@GetMapping("/welcome4")
@ResponseBody
public Object toLoginInfo4() {
    return ().getAuthentication();
}

illustrate:This method is from staticSecurityContextHolderGet the current thread boundSecurityContext, take it out againAuthenticationObject. This way, you can get information about the currently logged-in user in non-controller places (such as in business logic or tool classes).

5. Use custom tool methods

@GetMapping("/welcome5")
@ResponseBody
public Object toLoginInfo5() {
    return ();
}

illustrate:This is a package of the above methods, usually encapsulating a tool class in the project (such asLoginInfoUtil), internal encapsulation pairSecurityContextHolderCalls or other logical processing, return a more friendly user information object. This will help centrally manage and unify the logic of obtaining user information.

LoginInfoUtil:

public class LoginInfoUtil {

    /**
      * Get the current logged-in user information
      * @return
      */
    public static TUser getCurrentLoginUser() {
        return  (TUser) ().getAuthentication().getPrincipal();
    }
}

Summarize

  • Unified storage:Spring Security saves the current authentication information inSecurityContext, bySecurityContextHolderImplement thread-level binding.

  • Various ways:You can directly use method parameters (such asPrincipalAuthenticationor more specific authentication class) to obtain it, or you can pass it at any location().getAuthentication()Get it. These methods are essentially all about obtaining the same object, but using it differently.

  • Extensions and Encapsulation:If you often need to obtain current user information in a project, you can encapsulate a tool class to facilitate calls and subsequent extensions.

AuthenticationInherited fromPrincipal, which means it not only contains basic identity information, but also expands on additional authentication details.

UsernamePasswordAuthenticationTokenyesAuthenticationA specific implementation of the interface, specifically used in scenarios of username and password authentication.

In the actual authentication process, it usually passesUsernamePasswordAuthenticationTokenTo encapsulate the authentication information submitted by the user and return a complete authentication object after the authentication is successful.

How to get more user information

The entity class implements the UserDetails interface, implements the 7 interfaces of UserDetails. In this way, you can retain the seven methods required by Spring Security, and extend other business attributes in the entity class.

Custom user entity class

Extended business attributes:In your user entity class, you can add additional attributes such as real name, email, phone number, etc.

Seven ways to implement the UserDetails interface:

  • getAuthorities():Returns the permissions (or roles) owned by the user, usually a collection containing the GrantedAuthority object.

  • getPassword():Returns the user's password for authentication.

  • getUsername():Returns the username.

  • isAccountNonExpired():Indicates whether the user account has not expired. Return true means that the account is valid and has not expired.

  • isAccountNonLocked():Indicates whether the user account is not locked. Return true means that the account is not locked.

  • isCredentialsNonExpired():Indicates whether the user's credentials (password) have not expired.

  • isEnabled():Indicates whether the user account is available (enabled).

After that, since we returned the implementation class User that returned UserDetails, we can return directly because we have a custom implementation class TUser, so we don't need to use the framework User class.

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // Query the database by username     TUser user =  (username);
     if (user == null){
         throw new UsernameNotFoundException("The user does not exist");
     }
     return user; // Implements the UserDetails interface, including all fields
// // Return the framework User (the implementation class of UserDetails) but receive using UserDetails//      return  ()
//                .username(())
//                .password(())
// .authorities(AuthorityUtils.NO_AUTHORITIES) // No permissions (Permission Management part)// .build(); // After returning UserDetails(User) to the framework, the framework will use a password encryptor to compare passwords    }

How to ignore certain fields (not return to the front end) and canonical date format

use

@JsonIgnore // Indicates that the field is not returned to the front end

If there are many date classes in the entity class, it will be troublesome to add specifications for each field, so Jackson's conversion method is generally configured:

spring:
  application:
    name: Security-04-login-info

# jackson configuration time format (using the specified time zone and format)  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss

Processing after successful login:

 @Bean// Security filter chain Bean    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception { //httpSecurity method parameter injection Bean        return httpSecurity
                // Configure your own login page                .formLogin( (formLogin) ->{
                    ("/login") // Which address to submit your password to your login account                            .loginPage("/toLogin")// Customize login page                            .successForwardUrl("/welcome"); // Which page to jump to after login is successful? By default, it is to jump to the previous page                })
                .authorizeHttpRequests((authorizeHttpRequests)->{
                    authorizeHttpRequests
                            .requestMatchers("/toLogin","/common/captcha").permitAll() // In special cases, toLogin can be accessed without logging in, and the verification code can be accessed without logging in.                            .anyRequest().authenticated(); // Except for the above special circumstances, any other request needs to be authenticated before accessing                })
                .addFilterBefore(captchaFilter, )
                .build();
    }

When using .successForwardUrl("/welcome"), Spring Security will not initiate a new HTTP request after the user logs in successfully, but will forward the current request to the specified URL (i.e. "/welcome") through internal request forwarding (forward). This means:

  • Internal forwarding:Requests are forwarded within the server and will not change the URL displayed in the browser address bar.
  • The request method remains the same:During the forwarding process,The original HTTP request method (such as POST) is preserved. Therefore, if the login request is POST, the forwarded "/welcome" interface is also a POST request.
  • Commonly used for processing after successful login:This method is suitable for scenarios where the original request data needs to be processed or the request context is maintained after the login is successful.

In summary, .successForwardUrl("/welcome") is used to forward the request internally to the "/welcome" interface after the authentication is successful, so as to execute the corresponding processing logic instead of initiating a new request to the browser.

This is the article about SpringSecurity getting information about the current logged-in user. For more information about SpringSecurity getting information about the current logged-in user, please search for my previous article or continue browsing the related articles below. I hope everyone will support me in the future!