Spring Security实现用户名密码登录详解
简介
Spring Security是Spring框架的一个模块,用于提供应用程序安全性。Spring Security基于servlet过滤器和Spring IoC,为web请求和方法注释提供安全性。
在本文中,我们将详细介绍Spring Security如何实现用户名密码登录功能,包括安全配置、用户信息存储和登录页面的设置。
安全配置
在Spring Security中,安全配置是通过Java配置或XML配置的方式来进行的。下面我们给出一个Java配置安全配置的例子。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1").password("{noop}password1").roles("USER")
.and().withUser("user2").password("{noop}password2").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.failureUrl("/login?error=true")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login");
}
}
在上面的例子中,我们使用了Spring Security提供的默认的登录页面,并且在内存中存储了两个用户的用户名、密码和角色信息。configureGlobal
方法用于配置用户信息的存储,我们在这里使用了内存存储方式,实际应用中可以使用JDBC或LDAP等其他方式实现用户信息的存储。
在configure
方法中,我们做了以下几点配置:
- 配置
/login
路径可以被所有人访问。 - 配置除
/login
路径之外的所有路径都需要认证后才能访问。 - 配置登录页面的地址为
/login
。 - 配置登录成功后的跳转地址为
/home
。 - 配置登录失败后的跳转地址为
/login?error=true
。 - 配置用户名和密码的输入参数名为
username
和password
。 - 配置注销的URL为
/logout
,注销成功后的跳转地址为/login
。
用户信息存储
Spring Security允许我们在不同的存储介质中存储用户信息,如内存、JDBC和LDAP等。在本节中,我们将使用JDBC存储用户信息。
假设我们已经创建了一个名为users
的数据库表,其中存储了用户的用户名、密码和角色信息。我们需要创建一个实现UserDetailsService
接口的类来从数据库中获取用户信息。
@Service
public class UserDetailServiceImpl implements UserDetailsService {
@Autowired
private DataSource dataSource;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
jdbcUserDetailsManager.setUsersByUsernameQuery("select username,password,enabled from users where username = ?");
jdbcUserDetailsManager.setAuthoritiesByUsernameQuery("select username,authority from authorities where username = ?");
return jdbcUserDetailsManager.loadUserByUsername(username);
}
}
在上述代码中,我们注入了DataSource
,并使用JdbcUserDetailsManager
从数据库中获取用户信息。setUsersByUsernameQuery
方法用于设置UserDetailsService
从数据库中获取用户信息的SQL语句,setAuthoritiesByUsernameQuery
方法用于设置从数据库中获取用户角色信息的SQL语句。
登录页面设置
Spring Security可以自定义登录页面,我们可以在配置文件中配置登录页面的地址,也可以在Java代码中进行配置。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 省略其他配置
http.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
}
在上述代码中,我们在configure
方法中配置了自定义的登录页面地址为/login
,并开放此页面的访问权限。
下面我们给出一个使用Thymeleaf模板引擎的示例。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Login</title>
<link rel="stylesheet" th:href="@{/css/style.css}" />
</head>
<body>
<h1>Login</h1>
<div th:if="${param.error}">
<p style="color:red">用户名或密码错误</p>
</div>
<form th:action="@{/login}" method="post">
<label>用户名:<input type="text" name="username"/></label>
<label>密码:<input type="password" name="password"/></label>
<button type="submit">登录</button>
</form>
</body>
</html>
在上述代码中,我们使用了Thymeleaf模板引擎来渲染登录页面,同时通过Spring Security的EL表达式param.error
判断登录过程中是否发生了错误。
示例说明
示例1
假设我们有一个需要用户登录后才能访问的页面/secure
,下面是Java配置方式实现的安全配置。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 配置用户信息存储
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/secure").authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.failureUrl("/login?error=true")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login");
}
}
在上述代码中,我们配置了访问/login
路径不需要认证,/secure
路径需要认证,该路径的所有请求都需要用户登录后才能访问。
示例2
在下面这个示例中,我们使用了XML配置方式来实现安全配置。
<http auto-config="true">
<form-login login-page="/login" default-target-url="/home" authentication-failure-url="/login?error=true"
username-parameter="username" password-parameter="password" />
<intercept-url pattern="/login" access="permitAll"/>
<intercept-url pattern="/secure" access="hasRole('ROLE_USER')" />
<logout logout-url="/logout" logout-success-url="/login" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user1" password="{noop}password1" authorities="ROLE_USER" />
<user name="user2" password="{noop}password2" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
在上述代码中,我们配置了访问/login
路径不需要认证,/secure
路径需要认证,并且只有拥有ROLE_USER
角色的用户才能访问。我们在XML配置中定义了两个用户及其角色信息。
结论
本文介绍了Spring Security如何实现用户名密码登录功能,包括安全配置、用户信息存储和登录页面的设置。在实际应用中,我们可以根据需求使用不同的存储介质存储用户信息,同时也可以根据需求来定制化登录页面。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security实现用户名密码登录详解 - Python技术站