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

基于 Spring Security 数据库的身份验证,第1张

基于 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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5721893.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存