Spring Security实现身份认证和授权的示例代码

 更新时间:2023年06月16日 16:07:04   作者:2013crazy  
在 Spring Boot 应用中使用 Spring Security 可以非常方便地实现用户身份认证和授权,本文主要介绍了Spring Security实现身份认证和授权的示例代码,感兴趣的可以了解一下

Spring Security 是一个开源的安全框架,提供了基于权限的访问控制、身份认证、安全性事件发布等功能。在 Spring Boot 应用中使用 Spring Security 可以非常方便地实现用户身份认证和授权。

Spring Security 实现身份认证的主要方式是使用认证过滤器链,该过滤器链包含多个过滤器,用于对用户进行身份验证和授权。在 Spring Security 中,认证和授权处理是通过过滤器链中的过滤器来实现的,最终返回一个认证成功的用户对象。本文将介绍 Spring Security 如何实现身份认证和授权,并提供示例代码。

1. Spring Security 的身份认证

Spring Security 的身份认证是通过 AuthenticationManager 接口实现的。AuthenticationManager 接口是一个认证管理器,用于对用户进行身份验证。在 Spring Security 中,AuthenticationManager 接口的默认实现是 ProviderManager。

ProviderManager 是一个认证管理器,它包含一个或多个 AuthenticationProvider 实现,用于对用户进行身份验证。AuthenticationProvider 接口是一个认证提供者,用于验证用户身份。在 Spring Security 中,AuthenticationProvider 的默认实现是 DaoAuthenticationProvider。

DaoAuthenticationProvider 是一个认证提供者,用于对用户进行身份验证。它需要一个 UserDetailsService 实现来获取用户信息和密码,然后使用 PasswordEncoder 进行密码校验。UserDetailsService 接口是一个用户详细信息服务接口,用于获取用户信息和密码。PasswordEncoder 接口是一个密码编码器接口,用于对密码进行编码和解码。

下面是一个基本的 Spring Security 配置示例,用于实现身份认证:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .logout()
            .and()
            .csrf().disable();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder);
    }
  }

在上面的代码中,使用 @EnableWebSecurity 注解启用 Spring Security。configure(HttpSecurity http) 方法用于配置访问控制,指定哪些 URL 需要哪些角色才能访问,以及任何请求都需要经过身份验证。formLogin() 方法启用基于表单的身份验证,logout() 方法启用注销支持,csrf().disable() 方法禁用 CSRF 保护。

configure(AuthenticationManagerBuilder auth) 方法用于配置身份验证,指定使用哪个 UserDetailsService 实现来获取用户信息和密码,以及使用哪个 PasswordEncoder 实现进行密码校验。

2. Spring Security 的授权

Spring Security 的授权是通过 AccessDecisionManager 接口实现的。AccessDecisionManager 接口是一个访问决策管理器,用于决定用户是否有权限访问某个资源。在 Spring Security 中,AccessDecisionManager 接口的默认实现是 AffirmativeBased。

AffirmativeBased 是一个访问决策管理器,它包含一个或多个 AccessDecisionVoter 实现,用于决定用户是否有权限访问某个资源。AccessDecisionVoter 接口是一个投票者,用于决定用户是否有权限访问某个资源。在 Spring Security 中,AccessDecisionVoter 的默认实现是 RoleVoter。

RoleVoter 是一个投票者,用于根据用户的角色决定用户是否有权限访问某个资源。在 Spring Security 中,我们可以通过实现 AccessDecisionVoter 接口来自定义投票者,根据自己的需求来决定用户是否有权限访问某个资源。

下面是一个基本的 Spring Security 配置示例,用于实现授权:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .logout()
            .and()
            .csrf().disable();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder);
    }

@Bean在上面的代码中,使用 @Bean 注解创建了一个自定义的 AccessDecisionVoter 实例,用于自定义投票逻辑。在 configure(HttpSecurity http) 方法中,通过 accessDecisionManager() 方法将自定义的 AccessDecisionVoter 实例添加到访问决策管理器中。

3. 完整的示例代码

下面是一个完整的 Spring Security 配置示例代码,用于实现身份认证和授权:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .logout()
            .and()
            .csrf().disable()
            .exceptionHandling()
            .accessDeniedPage("/403");
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder);
    }
    @Bean
    public AccessDecisionVoter<Object> accessDecisionVoter(){
        RoleHierarchyVoter roleHierarchyVoter = new RoleHierarchyVoter(roleHierarchy());
        return roleHierarchyVoter;
    }
    @Bean
    public RoleHierarchyImpl roleHierarchy() {
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
        return roleHierarchy;
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

在上面的代码中,使用 @EnableWebSecurity 注解启用 Spring Security。configure(HttpSecurity http) 方法用于配置访问控制,指定哪些 URL 需要哪些角色才能访问,以及任何请求都需要经过身份验证。formLogin() 方法启用基于表单的身份验证,logout() 方法启用注销支持,csrf().disable() 方法禁用 CSRF 保护,并且使用 accessDeniedPage() 方法指定访问被拒绝时跳转的页面。

configure(AuthenticationManagerBuilder auth) 方法用于配置身份验证,指定使用哪个 UserDetailsService 实现来获取用户信息和密码,以及使用哪个 PasswordEncoder 实现进行密码校验。

accessDecisionVoter() 方法创建了一个自定义的 AccessDecisionVoter 实例,用于自定义投票逻辑。在这个例子中,我们使用了 RoleHierarchyVoter 类实现了一个基于角色继承关系的投票逻辑。RoleHierarchyImpl 类用于定义角色继承关系。

passwordEncoder() 方法用于创建一个密码编码器实例,这里我们使用了 BCryptPasswordEncoder 类实现密码编码。

最后,我们需要实现 UserDetailsService 接口,用于获取用户信息和密码。下面是一个简单的实现示例:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username));
        return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                user.getRoles().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
    }
}

在上面的代码中,我们使用 UserRepository 类获取用户信息和密码,并将其包装成一个 UserDetails 实例返回。在这个例子中,我们使用了 org.springframework.security.core.userdetails.User 类实现了 UserDetails 接口。

结语

Spring Security 是一个非常强大的安全框架,可以为 Spring Boot 应用提供完整的身份认证和授权功能。本文介绍了 Spring Security 如何实现身份认证和授权,并提供了示例代码。使用 Spring Security 可以非常方便地保护应用程序,防止恶意攻击和数据泄露。

到此这篇关于Spring Security实现身份认证和授权的示例代码的文章就介绍到这了,更多相关Spring Security身份认证和授权内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java数据结构-HashMap详解

    Java数据结构-HashMap详解

    这篇文章主要介绍了Java数据结构-HashMap,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • Java使用ByteBuffer进行多文件合并和拆分的代码实现

    Java使用ByteBuffer进行多文件合并和拆分的代码实现

    因为验证证书的需要,需要把证书文件和公钥给到客户,考虑到多个文件交互的不便性,所以决定将2个文件合并成一个文件交互给客户,但是由于是加密文件,采用字符串形式合并后,拆分后文件不可用,本文给大家介绍了Java使用ByteBuffer进行多文件合并和拆分,需要的朋友可以参考下
    2024-09-09
  • Java Web检查用户登录状态(防止用户访问到非法页面)

    Java Web检查用户登录状态(防止用户访问到非法页面)

    一般javaweb网站都有用户登录,而有一些操作必须用户登录才能进行,本文主要介绍了Java Web检查用户登录状态,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • SpringBoot整合WxJava开启消息推送的实现

    SpringBoot整合WxJava开启消息推送的实现

    本文主要介绍了SpringBoot整合WxJava开启消息推送,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-03-03
  • Java的MyBatis+Spring框架中使用数据访问对象DAO模式的方法

    Java的MyBatis+Spring框架中使用数据访问对象DAO模式的方法

    Data Access Object数据访问对象模式在Java操作数据库部分的程序设计中经常被使用到,这里我们就来看一下Java的MyBatis+Spring框架中使用数据访问对象DAO模式的方法:
    2016-06-06
  • springboot @PostConstruct无效的解决

    springboot @PostConstruct无效的解决

    这篇文章主要介绍了springboot @PostConstruct无效的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • java并发锁的实现

    java并发锁的实现

    Java中的锁主要是为了解决多个线程访问共享数据时的竞争问题,确保线程能够安全地访问和修改共享数据,本文主要介绍了java并发锁的实现,感兴趣的可以了解一下
    2024-04-04
  • SpringBoot依赖管理的源码解析

    SpringBoot依赖管理的源码解析

    这篇文章主要介绍了SpringBoot依赖管理的源码解析,maven提供了一套依赖管理机制,通过在pom.xml定义坐标,通过坐标从互联网的中央仓库下载依赖的构件(jar包),规范去管理依赖所有构件,这就叫依赖管理,需要的朋友可以参考下
    2023-04-04
  • 一文带你深入认识JAVA中的异常

    一文带你深入认识JAVA中的异常

    Java异常处理成为社区中讨论最多的话题之一,下面这篇文章主要给大家介绍了关于JAVA中异常的相关资料,文中通过代码介绍的非常详细,对大家学习或者使用java具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-06-06
  • 深入了解MyBatis分页机制

    深入了解MyBatis分页机制

    在企业项目的数据库操作中,分页查询是一个常见需求,尤其当数据量庞大时,MyBatis作为我们Java开发者的持久层框架,为分页提供了灵活的支持,本篇文章我们将深入探讨MyBatis的分页机制,使我们在实际开发项目中运用自如,需要的朋友可以参考下
    2023-12-12

最新评论