如何在Spring Boot中实现简单的身份验证?


Spring Boot因其简单性和提高生产率的声誉而被广泛认为是用于开发Java应用程序的框架。许多应用程序中一个重要的考虑因素是身份验证的实现,这保证只有授权人员才能访问特定资源。

在Spring Boot中,通过利用其内置的安全功能和库,集成身份验证既高效又方便。此功能使开发人员能够专注于核心业务逻辑,而无需重新创建现有解决方案。

开发人员可以通过几个简单的步骤来确保其Spring Boot应用程序的安全并保护敏感数据。这些步骤包括在Spring Boot中实现身份验证,为应用程序开发建立安全的基础。通过这样做,用户将需要在访问受保护的资源之前进行身份验证。本文探讨了在Spring Boot中实现简单身份验证的过程,提供了有效保护应用程序的宝贵见解。

Spring Boot

Spring Boot是一个基于Java的开源框架,它是一个可靠且用户友好的解决方案,可以轻松开发和部署强大的独立应用程序。

Spring Boot旨在最大限度地减少配置和样板代码,使开发人员能够快速构建强大且可扩展的应用程序。凭借其明确的理念和自动设置功能,Spring Boot无需手动配置,并为开发基于Spring的应用程序提供了和谐的环境。

这句话展示了广泛的功能。它包括嵌入式服务器、依赖项管理和强大的安全选项。凭借这些功能,它已成为希望构建微服务、Web应用程序和RESTful API 的人士的热门选择。

方法

在Spring Boot中,可以找到几种实现简单身份验证的方法。让我们探索三种常见的方法

  • 使用内存身份验证

  • 使用数据库身份验证

  • 使用LDAP身份验证

使用内存身份验证

在这种方法中,应用程序将其用户凭据存储在其内存中。为了定义用户名、密码和角色等用户详细信息,需要实现UserDetailsService接口。在身份验证过程中,Spring Security将提供的凭据与保存在内存中的凭据进行比较。根据匹配情况,它要么授予用户访问权限,要么拒绝用户访问权限。

算法

  • 创建一个实现UserDetailsService接口的配置类。

  • 在配置类中定义用户详细信息(用户名、密码、角色)。

  • 在身份验证过程中,Spring Security将提供的凭据与内存中的用户详细信息进行比较。

  • 根据匹配情况授予或拒绝访问权限。

示例

//pom.xml
<dependencies>
   <!-- Other dependencies -->
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
   </dependency>
</dependencies>
// WebSecurityConfigurerAdapter.java
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.
builde
rs.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.
HttpSecu
rity;
import org.springframework.security.config.annotation.web.configuration.
Ena
bleWebSecurity;
import org.springframework.security.config.annotation.web.configuration.
Web
SecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(AuthenticationManagerBuilder auth) 
throws Exception {
      auth.inMemoryAuthentication()
            
.withUser("admin").password("{noop}password").roles("ADMIN")
            .and()
            
.withUser("user").password("{noop}password").roles("USER");
   }

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

输出

使用数据库身份验证

通过这种方法,用户凭据存储在数据库中。创建用户实体以及与数据库交互的存储库。在身份验证过程中,Spring Security利用UserDetailsService接口从数据库加载用户详细信息,并将它们与提供的凭据进行比较以授予或拒绝访问权限。

算法

  • 创建一个用户实体并定义一个与数据库交互的存储库。

  • 实现UserDetailsService接口以从数据库加载用户详细信息。

  • 在身份验证过程中,Spring Security根据提供的凭据从数据库检索用户详细信息。

  • 将检索到的凭据与提供的凭据进行比较,并相应地授予或拒绝访问权限。

示例

//pom.xml
<dependencies>
   <!-- Other dependencies -->
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
   </dependency>
   <!-- Add your database driver dependency -->
</dependencies>

// application.properties
spring.datasource.url=jdbc:<localhost:8080/hello>
spring.datasource.username=<user>
spring.datasource.password=<password>
spring.jpa.show-sql=true

//User.java
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
   private String username;
   private String password;
   private boolean enabled;

   // Getters and setters
   // Constructors
}

// UserDetailsService.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.
UsernameNotFoundExcept
ion;
import org.springframework.stereotype.Service;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

   private UserRepository userRepository;

   @Autowired
   public UserDetailsServiceImpl(UserRepository userRepository) {
      this.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.isEnabled(),
            true,
            true,
            true,
            Collections.emptyList()
      );
   }
}

// UserRepository.java
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
   Optional<User> findByUsername(String username);
}

// WebSecurityConfigurerAdapter.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.
builde
rs.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.
HttpSecu
rity;
import org.springframework.security.config.annotation.web.configuration.
Ena
bleWebSecurity;
import org.springframework.security.config.annotation.web.configuration.
Web
SecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   private UserDetailsServiceImpl userDetailsService;
   private PasswordEncoder passwordEncoder;

   @Autowired
   public SecurityConfig(UserDetailsServiceImpl userDetailsService, PasswordEncoder passwordEncoder) {
      this.userDetailsService = userDetailsService;
      this.passwordEncoder = passwordEncoder;
   }

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

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

输出

使用LDAP身份验证

当使用LDAP服务器进行用户管理时,LDAP身份验证非常适用。Spring Security与LDAP服务器集成,允许针对LDAP服务器进行身份验证。配置包括指定LDAP服务器连接详细信息,包括主机、端口和凭据。此外,还定义搜索基础和过滤器以在LDAP目录中查找用户条目。然后,Spring Security将提供的凭据与LDAP服务器进行验证以进行身份验证。

算法

  • 配置LDAP服务器的连接详细信息,包括主机、端口和凭据。

  • 定义搜索基础和过滤器以在LDAP目录中查找用户条目。

  • 在身份验证过程中,Spring Security将提供的凭据与LDAP服务器进行验证。

  • 根据身份验证结果授予或拒绝访问权限。

示例

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.ldapAuthentication()
         .userDnPatterns("uid={0},ou=users")
         .groupSearchBase("ou=groups")
         .contextSource()
            .url("ldap://:389/dc=mycompany,dc=com")
            .managerDn("cn=admin,dc=mycompany,dc=com")
            .managerPassword("admin");
   }

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

   public static void main(String[] args) {
      SpringApplication.run(SecurityConfig.class, args);
   }
}

输出

结论

在本教程中,在Spring Boot中实现简单的身份验证对于保护应用程序并确保只有授权用户才能访问受保护的资源至关重要。无论使用内存身份验证、数据库身份验证还是LDAP身份验证,Spring Boot都通过Spring Security提供方便的功能来简化身份验证过程。通过选择最合适的方法并配置必要的组件,开发人员可以建立一个强大的身份验证系统来保护其应用程序并保护敏感数据免遭未经授权的访问。

更新于:2023年7月27日

880 次浏览

启动你的职业生涯

通过完成课程获得认证

开始
广告
© . All rights reserved.