Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Persist org.springframework.security.core.userdetails.User or UserDetails

Spring security has a base class which represents authenticated User(org.springframework.security.core.userdetails.User):

Models core user information retrieved by a UserDetailsService.

Developers may use this class directly, subclass it, or write their own UserDetails implementation from scratch.

In most examples over the internet, for example here people usually create separate class for persistence, i.e com.mkyong.users.model.User in the example. This class doesn't extend the spring security one, so now we have two Users, one is for persistence and one represents the authenticated User in the system, everything we do is:

  1. Retrieve persistence User by username and password
  2. Copy fields to spring User and return it

So, my question is, what's the point of having one more User object? Wouldn't it better to extend spring security User and persist it instead? It may not be possible with hibernate/jpa annotations because we obviously can't put annotations in the spring security code, however it is doable through mapping files. Another concern here is that we shouldn't return hibernate entity from the service to avoid all kind of hibernate related issues on outside the service layer, so if I extend spring User and make it an Entity I will anyway need some kind of a POJO to return from UserDetailsService. Is that's the case why we need two User objects?

P.s. reference to documentation is appreciated

like image 347
Vadim Kirilchuk Avatar asked Oct 29 '22 11:10

Vadim Kirilchuk


1 Answers

The main reasons are:

  • Seperation of Concerns
  • Single Responsibility Principle

UserDetails is meant to expose specific information about the authenticated user as it relates to Spring Security. It's a class that can be changed based on that project's needs at any release.

By extending that class and allowing your persistence model to be based upon it, you now force your persistence model to be held hostage by those changes at any point. You've inevitability violated both principles.

The benefit to using a a separate persistence class is that you are now free to store your security attributes in any data model that suits your application's needs and goals. Furthermore, your database schema is no longer bound by external changes which you have no control over.

This is precisely why Spring Security exposes the UserDetailsService. That service interface is meant to allow Spring Security to call into a specific repository implementation(s) and transform your persistence model into the necessary UserDetails implementation their framework needs without violating the above two principles.

like image 165
Naros Avatar answered Nov 15 '22 04:11

Naros