Un artículo lo lleva a obtener la integración de SpringSecurity y SpringDataJpa

Para obtener información sobre Spring Data Jpa, puede consultar: Un artículo es suficiente para aprender Spring Data JPA

Uno, crea un proyecto

在这里插入图片描述
Tenga en cuenta que además de las dependencias de Spring Security, también necesitamos dependencias de datos y dependencias de Spring Data Jpa.

Una vez creado el proyecto, creamos una biblioteca vacía en la base de datos, llamada jpa, sin hacer nada en ella, para que nuestro trabajo preparatorio esté completo.

Dos, prepara el modelo

(1) Clase de entidad de función:

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

Esta clase de entidad se utiliza para describir la información de la función del usuario. Tiene una identificación de función y un nombre de función (inglés, chino), @Entitylo que indica que se trata de una clase de entidad. Una vez iniciado el proyecto, se creará automáticamente una tabla de funciones en la base de datos en función de los atributos de la clase de entidad.
(2) Clase de entidad de usuario

@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 方法
}

El director de la entidad de usuario necesita implementar UserDetailsla interfaz y la implementación del método de interfaz.

Los campos aquí son básicamente fáciles de entender, permítanme hablar sobre algunos especiales:

(1) accountNonExpired, accountNonLocked, credentialsNonExpired, enabledcuatro atributos se utilizan para describir el estado del usuario, que indica si la cuenta no ha expirado, si la cuenta no está bloqueado, si la contraseña no ha expirado, y la cuenta está disponible.
(2) el atributo roles representa el rol del usuario, el usuario y la relación de rol-muchos con una @ManyToManyanotación descrita.
(3) El método getAuthorities devuelve la información del rol del usuario. En este método, podemos transformar un poco nuestro Rol.

Tres, configuración

Una vez que el modelo de datos esté listo, definamos un UserDao:

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

Aquí hay algo muy simple, solo necesitamos heredar JpaRepositoryy proporcionar un método de acuerdo con el nombre de usuario de la consulta del usuario.
Defina UserService a continuación, de la siguiente manera:

@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;
    }
}

我们自己定义的 UserService 需要实现 UserDetailsService 接口,实现该接口,就要实现接口中的方法,也就是 loadUserByUsername ,这个方法的参数就是用户在登录的时候传入的用户名,根据用户名去查询用户信息(查出来之后,系统会自动进行密码比对)。

配置完成后,接下来我们在 Spring Security 中稍作配置,Spring Security 和测试用的 HelloController 我还是沿用之前文章中的,主要列出来需要修改的地方。

在 SecurityConfig 中,我们通过如下方式来配置用户:

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

大家注意,还是重写 configure 方法,只不过这次我们不是基于内存,也不是基于 JdbcUserDetailsManager,而是使用自定义的 UserService,就这样配置就 OK 了。

最后,我们再在 application.properties 中配置一下数据库和 JPA 的基本信息,如下:

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

四、测试

首先我们来添加测试数据,在单元测试中添加如下方法:

    @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);
    }

在这里插入图片描述
登录成功后,分别访问 /hello,/admin/hello 以及 /user/hello 三个接口,其中:

(1)/hello 因为登录后就可以访问,这个接口访问成功。
(2)/admin/hello 需要 admin 身份,所以访问失败。
(3)/user/hello 需要 user 身份,所以访问成功。

Supongo que te gusta

Origin blog.csdn.net/nanhuaibeian/article/details/108607430
Recomendado
Clasificación