📜  Spring – 在 Spring Security 中添加角色(1)

📅  最后修改于: 2023-12-03 15:05:16.596000             🧑  作者: Mango

Spring – 在 Spring Security 中添加角色

在一个大型的应用程序中,往往需要进行权限控制,使得只有授权用户可以访问特定的资源。Spring Security 提供了一个良好的解决方案,可以轻松添加基于角色的访问控制。

添加角色

首先,在 Spring Security 中添加角色非常简单。只需在 WebSecurityConfigurerAdapterconfigure(HttpSecurity http) 方法中进行配置即可。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        // ...
        .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
        // ...
}

在上述示例中,我们添加了两个角色:ADMINUSER。这意味着任何希望访问 adminuser 目录下的资源的用户,都必须至少拥有相应的角色。

注意,这里的 hasRole 方法是基于前缀 ROLE_ 的,所以实际使用的角色名称应该是 ROLE_ADMINROLE_USER

配置用户角色

接下来,我们需要为用户分配角色。可以使用 Spring Security 提供的 UserDetailsService 接口,从数据库或其他数据源中获取用户详细信息,包括其角色。

@Service
public class UserDetailsServiceImp implements UserDetailsService {

    private final UserRepository userRepository;

    @Autowired
    public UserDetailsServiceImp(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<User> userOptional = userRepository.findByUsername(username);
        if (userOptional.isEmpty()) {
            throw new UsernameNotFoundException("User not found");
        }
        User user = userOptional.get();
        Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
        for (Role role : user.getRoles()){
            grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return new org.springframework.security.core.userdetails.User(
            user.getUsername(),
            user.getPassword(),
            grantedAuthorities
        );
    }
}

在上述示例中,我们创建了一个名为 UserDetailsServiceImp 的类,它实现了 UserDetailsService 接口。在 loadUserByUsername 方法中,我们从 UserRepository 中获取用户详细信息,并为用户分配角色。最后,我们将这些信息以 UserDetails 对象的形式返回,以便 Spring Security 可以使用它们进行身份验证和授权。

配置角色访问

现在,我们已经完成了角色的添加和用户角色的配置,我们需要进行访问控制的配置,使得只有授权用户可以访问特定的资源。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
                .and()
            .formLogin().and()
            .httpBasic();
    }

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

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

在上述示例中,我们配置了 HttpSecurity,使得只有授权用户可以访问 /admin/user 目录下的资源。如果用户没有相应的角色,他们将会被重定向到默认的登录页面。在 configure(AuthenticationManagerBuilder auth) 方法中,我们将 UserDetailsServiceImp 注入到 Spring Security 中,以便它可以使用它来查找用户详细信息。最后,我们配置了一个密码编码器,用于加密用户密码。

结论

Spring Security 提供了强大的基于角色的访问控制机制,可以轻松为应用程序添加安全性。通过如上的配置,我们可以实现授权用户只能访问特定的资源。