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 methodPrincipal
When the parameter of type,Spring Security will automatically inject the corresponding corresponding to the current logged-in user.Principal
Object. generally,Principal
Only 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:Authentication
The 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 injectionAuthentication
It 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:
UsernamePasswordAuthenticationToken
yesAuthentication
A 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 injectionAuthentication
Similar, but the type is more specific.
4. Get it through SecurityContextHolder
@GetMapping("/welcome4") @ResponseBody public Object toLoginInfo4() { return ().getAuthentication(); }
illustrate:This method is from staticSecurityContextHolder
Get the current thread boundSecurityContext
, take it out againAuthentication
Object. 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 pairSecurityContextHolder
Calls 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 in
SecurityContext
, bySecurityContextHolder
Implement thread-level binding.Various ways:You can directly use method parameters (such as
Principal
、Authentication
or 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.
Authentication
Inherited fromPrincipal
, which means it not only contains basic identity information, but also expands on additional authentication details.
UsernamePasswordAuthenticationToken
yesAuthentication
A specific implementation of the interface, specifically used in scenarios of username and password authentication.
In the actual authentication process, it usually passesUsernamePasswordAuthenticationToken
To 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!