栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

基于 Spring Security 数据库的身份验证

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于 Spring Security 数据库的身份验证

在上一篇文章中,我们学习了 Spring Security 的实现,使用 In-Memory 配置对用户进行身份验证。在此示例中,我们将学习根据数据库表对用户和角色进行身份验证。

如果您是 Spring Security 的新手,我强烈建议您阅读 Spring Security 的基础知识。

执行

为了实现 Spring Security,我们将借助WebSecurityConfigurerAdapter. 要启用 Spring 安全性,我们需要使用@EnableSpringSecurity和注释我们的配置类@Configuration。

在此示例中,我们将使用H2 内存数据库来存储我们的用户凭据并获取这些凭据以进行身份​​验证。我们将在应用程序启动期间使用@PostConstruct注释将我们的用户凭据添加到数据库中。

复制 复制 COPY COPY
@PostConstruct
    public void setup() {
        userRepositoty.save(new UserEntity(1, "shail@mail.com", passwordEncoder.encode("shail@123"), "ROLE_ADMIN"));
        userRepositoty.save(new UserEntity(2, "john@mail.com", passwordEncoder.encode("john@123"), "ROLE_USER"));
    }

为了根据数据库表对我们的用户进行身份验证,我们将使用DaoAuthenticationProvider类和UserDetailsService接口。

DaoAuthenticationProvider是其中一种实现,AuthenticationProvider它借助UserDetailsService检索用户名和密码来对用户进行身份验证。

UserDetailsService接口有一个只读方法 loadUserByUsername()。我们重写这个方法来编写我们的逻辑来从数据库中获取数据。

复制 复制 COPY COPY
@Component
public class UserDetailsServiceImpl implements UserDetailsService {
  @Autowired
  private UserRepository userRepository;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
      UserEntity user = userRepository
                                      .findByUsername(username)
                                      .orElseThrow(() -> new UsernameNotFoundException("INVALID USERNAME"));

      UserDetails userDetails = new User(username, user.getPassword(), AuthorityUtils.createAuthorityList(user.getRole()));

      return userDetails;
  }
}

我们需要重写作为参数的configure()方法。有一个将 AuthenticationProvider 作为参数的方法;我们将把我们的对象作为参数传递给这个方法。我们还需要告诉我们的 ``DaoAuthenticationProvider我们将使用的密码编码器。WebSecurityConfigurerAdapterAuthenticationManagerBuilderAuthenticationManagerBuilder`authenticationProvider()DaoAuthenticationProviderUserDetailsServiceImpl

复制 复制 COPY COPY
@Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {

        DaoAuthenticationProvider daoAuthProvider = new DaoAuthenticationProvider();
        daoAuthProvider.setPasswordEncoder(passwordEncoder());
        daoAuthProvider.setUserDetailsService(userDetailsServiceImpl);

        auth.authenticationProvider(daoAuthProvider);

    }

我们还需要覆盖另一个作为参数的configure()方法。在这里,我们将为不同的 URI 模式和这些 URI 模式上允许的角色配置我们的基本安全参数。WebSecurityConfigurerAdapterHttpSecurity

复制 复制 COPY COPY
@Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off

        http
            .httpBasic().and()
            .authorizeRequests()
            .antMatchers("/h2-console/**").permitAll()
            .antMatchers("/api/admin/**").hasRole("ADMIN")
            .antMatchers("/api/user/**").hasRole("USER")
            .antMatchers("/api/any/**").hasAnyRole("ADMIN", "USER")
            .anyRequest()
            .authenticated()
            .and().formLogin().disable();

        http.csrf().ignoringAntMatchers("/h2-console/**");

        http.headers().frameOptions().sameOrigin();

        // @formatter:on

    }

测试

为了测试我们的实现,让我们创建一个简单的控制器,其中包含一些返回不同消息的 GetMapping。

复制 复制 COPY COPY
@RestController
@RequestMapping(value = "api")
public class MessageController {

    @GetMapping(value = "/admin/message")
    public String adminMessage(Authentication auth) {
        String role = "";
        for (GrantedAuthority gauth: auth.getAuthorities()) {
                role = gauth.getAuthority();
        }
        return "Hello, "+ auth.getName()+ " you are "+ role+"";
    }

    @GetMapping(value = "/user/message")
    public String userMessage(Authentication auth) {
        String role = "";
        for (GrantedAuthority gauth: auth.getAuthorities()) {
                role = gauth.getAuthority();
        }
        return "Hello, "+ auth.getName()+ " you are "+ role+"";
    }

    @GetMapping(value = "/any/message")
    public String anyMessage(Authentication auth) {
        String role = "";
        for (GrantedAuthority gauth: auth.getAuthorities()) {
                role = gauth.getAuthority();
        }
        return "Hello, "+ auth.getName()+ " you are "+ role+"";
    }
}

现在让我们尝试使用 Postman 来使用这些 API。

输入请求 URL 作为localhost:8080/api/admin/message并在 Authorization 选项卡下,选择 Basic Auth 并提供用户名和密码,然后单击发送。

身份验证成功后,您将能够访问 URL 并将获得输出为 -

如果您尝试通过上述 URL 上的john@mail.com凭据登录,您将收到一条错误消息Forbidden ,因为这仅适用于 ADMIN 角色。

我建议您尝试将其他组合凭据与 URL 资源一起使用,请参阅输出。

概括

在本文中,我们学习了如何实现 Spring Security 并针对数据库对用户进行身份验证,以及如何根据用户角色限制 URL 或资源。

在该系列的后续文章中,我们将继续学习 Spring Security 并查看使用 JWT 和 Spring Security 的身份验证。

最后但并非最不重要的一点是,您总能找到实现的完整源代码 @Github

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/726553.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号