An article takes you to get the integration of SpringSecurity and SpringDataJpa

For learning about Spring Data Jpa, you can refer to: One article is enough to learn Spring Data JPA

One, create a project

Insert picture description here
Note that in addition to Spring Security dependencies, we also need data dependencies and Spring Data Jpa dependencies.

After the project is created, we then create an empty library in the database, called jpa, without doing anything in it, so that our preparatory work is completed.

Two, prepare the model

(1) Role entity class:

@Entity(name = "t_role")
public class Role {
    
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String nameZh;
    //省略 getter/setter
}

This entity class is used to describe user role information. It has role id and role name (English, Chinese), @Entityindicating that this is an entity class. After the project is started, a role table will be automatically created in the database based on the attributes of the entity class.
(2) User entity class

@Entity(name = "t_user")
public class User implements UserDetails {
    
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    private boolean accountNonExpired;
    private boolean accountNonLocked;
    private boolean credentialsNonExpired;
    private boolean enabled;
    @ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.PERSIST)
    private List<Role> roles;
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
    
    
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for (Role role : getRoles()) {
    
    
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return authorities;
    }
    @Override
    public String getPassword() {
    
    
        return password;
    }

    @Override
    public String getUsername() {
    
    
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
    
    
        return accountNonExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
    
    
        return accountNonLocked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
    
    
        return credentialsNonExpired;
    }

    @Override
    public boolean isEnabled() {
    
    
        return enabled;
    }
    //省略其他 get/set 方法
}

User entity principal need to implement UserDetailsthe interface, and implementation of the interface method.

The fields here are basically easy to understand, let me talk about a few special ones:

(1) accountNonExpired, accountNonLocked, credentialsNonExpired, enabledfour attributes are used to describe the state of the user, indicating whether the account has not expired, whether the account is not locked, whether the password has not expired, and the account is available.
(2) roles attribute represents the user's role, User, and Role-many relationship with an @ManyToManyannotation described.
(3) The getAuthorities method returns the user's role information. In this method, we can transform our Role a little bit.

Three, configuration

After the data model is ready, let's define a UserDao:

public interface UserDao extends JpaRepository<User,Long> {
    
    
    User findUserByUsername(String username);
}

Here's something very simple, we only need to inherit JpaRepositoryand to provide a method according to the user's query username.
Define UserService next, as follows:

@Service
public class UserService implements UserDetailsService {
    
    
    @Autowired
    UserDao userDao;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    
    
        User user = userDao.findUserByUsername(username);
        if (user == null) {
    
    
            throw new UsernameNotFoundException("用户不存在");
        }
        return user;
    }
}

Our own definition of UserServicethe need to achieve UserDetailsServiceinterface, this interface, the interface methods must achieve, that is, loadUserByUsernameafter the parameter of this method is that when users log incoming user name, user name to query user information (check out , The system will automatically compare the passwords).

After the configuration is complete, let's do a little configuration in Spring Security. I still use Spring Security and HelloController used for testing from the previous article, mainly listing the places that need to be modified.

In SecurityConfig, we configure users in the following ways:

@Autowired
UserService userService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
    
    auth.userDetailsService(userService);
}

Please note that we are still rewriting the configure method, but this time we are not based on memory, nor based on it JdbcUserDetailsManager, but using a custom one UserService, so the configuration is OK.

Finally, we configure the basic information of the database and JPA in application.properties, as follows:

spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

spring.jpa.database=mysql
spring.jpa.database-platform=mysql
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

Four, test

First, let's add test data, add the following method to the unit test:

    @Test
    void contextLoads() {
    
    
        User user = new User();
        user.setUsername("yolo");
        user.setPassword("123");
        user.setAccountNonExpired(true);
        user.setAccountNonLocked(true);
        user.setCredentialsNonExpired(true);
        user.setEnabled(true);
        List<Role> list = new ArrayList<>();
        Role role = new Role();
        role.setName("ROLE_admin");
        role.setNameZh("管理员");
        list.add(role);
        user.setRoles(list);
        userDao.save(user);
    }

Insert picture description here
After a successful login, access respectively /hello,/admin/helloand /user/hellothree interfaces, including:

(1) /helloBecause you can access after logging in, this interface is successfully accessed.
(2) The /admin/helloadmin identity is required, so the access fails.
(3) The /user/hellouser identity is required, so the access is successful.

Guess you like

Origin blog.csdn.net/nanhuaibeian/article/details/108607430