Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User class for Spring Security application

I am currently developing a multi user Spring Boot application with JPA/Hibernate and an Angular 2 frontend. I envision two basic types of users: Vendors and customers.

Before starting to code I crafted a UML class diagram with the class User and two subclasses Customer and Vendor. The reason for the subclasses is that they have different attributes: e.g. a vendor should be able to write a general description about himself whereas a customer should be able to save favorites.

The following picture is an excerpt of my class diagram:

UML class diagram snippet

As it's my first app with Login/Registration feature I started reading tutorials about how to implement a Login and Registration feature with Spring Security. Over time, I had to realize that basically all the samples contain only one User class, whose privileges are determined upon his Roles, which is typically a recommended/needed class to achieve the above mentioned functionality.

It appears to me that the User class is not meant to have subclasses, but naturally the tutorials and samples mostly cover the basic setup and not the representation of a complex business model with completely different users.

My question is the following: is it feasible and advisable to create subclasses of the User class which I want to use for the authorization with a custom UserDetailsService class? If not, do you recommend merging the attributes from the Customer and Vendor class into the User class and consequently determine upon the User's roles if he should be able to have a certain attribute and otherwise it will just be null?

Thanks a lot in advance!

like image 217
Times Avatar asked Jul 06 '18 22:07

Times


1 Answers

Spring security work with UserDetailsService interface for authentication and authorize features. You should implement loadUserByUsername function for load User from database or in memory or any where.

Spring security work with UserDetails interface as model. Therefore your User entity need to implement UserDetails interface that spring security can work with that.

Now, you have User entity that can inherited like other entities and you can annotate it with @Inheritance like below:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Length(min=5)
    private String password;
    private String username;

    @Email
    private String email;
    private String phoneNumber;
    private boolean enabled;
    private boolean verified;

    @ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    private Set<Authority> roles= new HashSet<>();

    //...
}

@Entity
public class Vendor extends User{
        private String name;
        private String description;
        private Date openingTime;
        private Date closingTime;
        @ManyToOne
        private List<File> images;
        //...
}

@Entity
public class Customer extends User{
        private String forename;
        private String surname;
        @ManyToOne
        private List<PaymentDetails> paymentDetailsList;
        //...
}
like image 121
Javad Kargar Avatar answered Nov 01 '22 20:11

Javad Kargar