spring security 用JPA進行安全管理中使用自定義的UserDetails時,maximumSessions()無法限制Session數


這是我自定義的UserDetails,這個user對象會保存到數據庫。

//自定義的User
@Entity(name = "t_user")
public class User implements UserDetails, CredentialsContainer {
        @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    //...其他字段
}

而ConcurrentSessionControlAuthenticationStrategy#onAuthentication在執行sessionRegistry.getAllSessions方法時會到sessionRegistry的一個Map中去獲取當前用戶的所有session。Map.get的key是這個Principal,也就是User對象實例,之前我沒有重寫User的hascode和equals方法,(Map.get方法是根據hashcode獲取value的,而未重寫hascode,默認使用父類Object的hashcode方法,Object#hashcode相當於返回對象的內存地址),所以取出來的sessions是空集合,系統認為該用戶沒有在其他地方登錄過。

//ConcurrentSessionControlAuthenticationStrategy#onAuthentication
public void onAuthentication(Authentication authentication, HttpServletRequest request,
      HttpServletResponse response) {
   List<SessionInformation> sessions = this.sessionRegistry.getAllSessions(authentication.getPrincipal(), false);
   int sessionCount = sessions.size();
   int allowedSessions = getMaximumSessionsForThisUser(authentication);
   if (sessionCount < allowedSessions) {
      // They haven't got too many login sessions running at present
      return;
   }
}

另外要注意,重寫User的hascode和equals只需要判斷username字段即可,因為用戶密碼和id都可能變化,但在這些變化后我們仍認為它是同一個用戶。可以參考spring security自帶的org.springframework.security.core.userdetails.User的這兩個方法

//org.springframework.security.core.userdetails.User
public class User implements UserDetails, CredentialsContainer {
	/**
	 * Returns {@code true} if the supplied object is a {@code User} instance with the
	 * same {@code username} value.
	 * <p>
	 * In other words, the objects are equal if they have the same username, representing
	 * the same principal.
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof User) {
			return this.username.equals(((User) obj).username);
		}
		return false;
	}

	/**
	 * Returns the hashcode of the {@code username}.
	 */
	@Override
	public int hashCode() {
		return this.username.hashCode();
	}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM