在 Spring Security 中,用户认证的方式有多种,包括基于内存、基于数据库、LDAP 认证等。
在实际开发中,我们可以根据自己的业务需要选择合适的用户认证方式。
- 基于内存认证(基于内存的认证方式适用于用户数量较少,且用户信息不经常变动的场景)
在Spring Security中,我们可以通过配置一个实现了UserDetailsService接口的类来实现基于内存的用户认证。UserDetailsService接口提供了一个方法loadUserByUsername(String username),该方法返回一个UserDetails对象,Spring Security会根据该对象中的用户名、密码和权限信息来完成认证。
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
.antMatchers("/").permitAll()
.and().formLogin();
}
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("{noop}admin").roles("ADMIN")
.and()
.withUser("user").password("{noop}user").roles("USER");
}
这段代码是一个实现了基于内存用户认证的方法,在 Spring Security 的配置类中重写了 configure(AuthenticationManagerBuilder auth) 方法。 在该方法中,通过 auth.inMemoryAuthentication() 方法创建了一个内存中的用户认证服务,并添加了两个用户,一个是 admin,另一个是 sang。其中,withUser() 方法指定了用户的用户名,password() 方法指定了用户的密码(密码已经被加密),roles() 方法指定了用户的角色。这里的角色只是一个字符串,可以自定义,可以根据自己的业务需要指定不同的角色。
另外,我们在密码前面加了{noop},表示不使用任何加密方式。
在configure(HttpSecurity http)方法中,通过authorizeRequests()方法来配置访问权限,其中antMatchers()方法用于指定访问路径,hasRole()和hasAnyRole()方法用于指定角色。另外,我们还通过formLogin()方法启用了表单登录功能。
-
基于数据库认证
在Spring Security中,我们可以通过配置一个实现了UserDetailsService接口的类来实现基于数据库的用户认证。
UserDetailsService接口提供了一个方法loadUserByUsername(String username),该方法返回一个UserDetails对象,Spring Security会根据该对象中的用户名、密码和权限信息来完成认证。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("select username, password, enabled from users where username=?")
.authoritiesByUsernameQuery("select username, authority from authorities where username=?")
.passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
.antMatchers("/").permitAll()
.and().formLogin();
}
}
上述代码中,我们通过注入一个DataSource对象来实现基于数据库的用户认证。
在configure(AuthenticationManagerBuilder auth)方法中,我们使用jdbcAuthentication()方法来启用基于数据库的认证,并通过usersByUsernameQuery()和authoritiesByUsernameQuery()方法来指定查询用户和权限的SQL语句。
另外,我们还指定了密码加密方式为BCryptPasswordEncoder。
在configure(HttpSecurity http)方法中,我们通过authorizeRequests()方法来配置访问权限,其中antMatchers()方法用于指定访问路径,hasRole()和hasAnyRole()方法用于指定角色。另外,我们还通过formLogin()方法启用了表单登录功能。
-
基于LDAP 认证
在Spring Security中,我们可以通过配置一个实现了UserDetailsService接口的类来实现基于LDAP的用户认证。UserDetailsService接口提供了一个方法loadUserByUsername(String username),该方法返回一个UserDetails对象,Spring Security会根据该对象中的用户名、密码和权限信息来完成认证。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${ldap.url}")
private String ldapUrl;
@Value("${ldap.baseDn}")
private String ldapBaseDn;
@Value("${ldap.userDnPattern}")
private String ldapUserDnPattern;
@Value("${ldap.groupSearchBase}")
private String ldapGroupSearchBase;
@Value("${ldap.groupRoleAttribute}")
private String ldapGroupRoleAttribute;
@Value("${ldap.managerDn}")
private String ldapManagerDn;
@Value("${ldap.managerPassword}")
private String ldapManagerPassword;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns(ldapUserDnPattern)
.groupSearchBase(ldapGroupSearchBase)
.groupRoleAttribute(ldapGroupRoleAttribute)
.contextSource()
.url(ldapUrl + ldapBaseDn)
.managerDn(ldapManagerDn)
.managerPassword(ldapManagerPassword);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
.antMatchers("/").permitAll()
.and().formLogin();
}
}
上述代码中,我们通过注入一些配置参数来实现基于LDAP的用户认证。
在configure(AuthenticationManagerBuilder auth)方法中,我们使用ldapAuthentication()方法来启用基于LDAP的认证,并通过userDnPatterns()方法来指定用户DN的格式,groupSearchBase()方法和groupRoleAttribute()方法用于指定LDAP中的组信息,contextSource()方法用于指定LDAP服务器的URL和管理员账号密码。
在configure(HttpSecurity http)方法中,我们和上面的示例代码一样,通过authorizeRequests()方法来配置访问权限,其中antMatchers()方法用于指定访问路径,hasRole()和hasAnyRole()方法用于指定角色。另外,我们还通过formLogin()方法启用了表单登录功能。