关于 Spring Security 安全认证示例代码的完整攻略,我将按照以下步骤来讲解:
- 系统需求
- Spring Security 简介
- Spring Security 安全认证的示例代码
- 示例代码的详细解释
- 示例的运行方式
- 附加示例
1. 系统需求
首先,你需要确保你的系统已经安装了以下环境:
- Java 1.8+;
- Maven;
- Eclipse 或者 IntelliJ IDEA(本例使用 IntelliJ IDEA);
- Tomcat。
2. Spring Security 简介
Spring Security 是 Spring 框架的一个子项目,提供一系列的安全认证和授权功能,支持多种认证方式,并能够基于角色来控制用户的访问权限。
3. Spring Security 安全认证的示例代码
示例代码可以在 Github 上找到,地址是:https://github.com/crossoverJie/springboot-security-learning。
4. 示例代码的详细解释
上面的示例代码包含两个示例:
- 基于内存的认证示例;
- 基于数据库的认证示例。
下面将分别对这两个示例进行详细解释。
4.1 基于内存的认证示例
在这个示例中,我们将使用内存中的用户名和密码进行认证,在示例中有两个用户信息,一个是 admin,密码是 123456,另一个是 crossover,密码是 654321。在示例代码中,我们将这些用户信息写到了一个配置类 InMemorySecurityConfig 中。
示例代码中的 InMemorySecurityConfig 配置类代码如下:
@Configuration
@EnableWebSecurity
public class InMemorySecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").access("hasRole('ADMIN') or hasRole('USER')")
.anyRequest().authenticated();
http.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/home")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll();
// 禁用 CSRF
http.csrf().disable();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("{noop}123456").roles("ADMIN", "USER")
.and()
.withUser("crossover").password("{noop}654321").roles("USER");
}
}
在上面的代码中,我们通过重写 configure 方法来配置安全策略,其中:
-
第一部分是配置资源访问的权限,如配置访问 /admin/ 的资源必须有角色为 ADMIN 的用户才能访问,访问 /user/ 的资源必须有 ADMIN 或者 USER 的角色才能访问。
-
第二部分是配置登录和登出行为,其中定义了登录页面的地址为 /login,登录失败后的请求地址是 /login?error,登录成功后默认跳转的地址是 /home,登出请求的地址是 /logout。
-
第三部分是配置内存信息,使用 inMemoryAuthentication 方法可以创建一个认证信息,包括用户名、密码和角色。
需要注意的是,在示例代码中对密码使用了 >=5.0 版本推荐的 {noop} 模式进行明文存储,这是因为 5.0 版本之后的 Spring Security 默认开启了加密存储密码。
4.2 基于数据库的认证示例
在这个示例中,我们将使用数据库中的用户名和密码进行认证,数据库结构和表的定义如下:
CREATE DATABASE IF NOT EXISTS `test`;
USE `test`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `user` (`username`,`password`) VALUES ('admin','$2a$10$6GJt/5tSxMAVh3SsAyPgbetuGgpYcD2buGSM5PeJUkvp988K10nmy');
INSERT INTO `user` (`username`,`password`) VALUES ('crossover','$2a$10$6GJt/5tSxMAVh3SsAyPgbetuGgpYcD2buGSM5PeJUkvp988K10nmy');
示例代码中的 JdbcSecurityConfig 配置类代码如下:
@Configuration
@EnableWebSecurity
public class JdbcSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("select username,password,1 as enabled from user where username=?")
.authoritiesByUsernameQuery("select username, 'ROLE_USER' from user where username=?")
.passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.successForwardUrl("/home")
.and()
.logout()
.permitAll();
// 禁用 CSRF
http.csrf().disable();
}
}
在上面的代码中,我们注入了一个 DataSource,用于连接数据库。
在 configureGlobal 方法中,我们使用了 jdbcAuthentication 方法来创建一个认证信息,其中:
- dataSource 参数用于指定使用的数据源;
- usersByUsernameQuery 方法用于指定查询用户信息的 SQL 语句;
- authoritiesByUsernameQuery 方法用于指定查询用户权限信息的 SQL 语句;
- passwordEncoder 方法用于指定密码编码方式,这里使用了 BCryptPasswordEncoder。
5. 示例的运行方式
在完成代码的编写之后,我们需要将代码打包成 WAR 包并部署到 Tomcat 中运行。具体操作方式如下:
- 执行 maven 打包命令,生成 war 包:
mvn clean package
- 将生成的 war 包复制到 Tomcat 的 webapps 目录下,并启动 Tomcat 服务:
cd target/
cp springboot-security-1.0-SNAPSHOT.war [TOMCAT_HOME]/webapps/springboot-security.war
cd [TOMCAT_HOME]/bin/
./startup.sh
- 访问 http://localhost:8080/springboot-security/login 进行登录。其中,springboot-security 是在 application.properties 中配置的 contextPath。
6. 附加示例
如果你希望使用更加完善的示例,你可以参考以下链接:
https://github.com/wuyouzhuguli/SpringAll/tree/master/30.Spring%20Security
这个示例代码中,提供了使用 Spring Security 实现 OAuth2.0 认证、授权的示例,涉及到了代码鉴权、Token 认证等概念,更加详细全面。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security 安全认证的示例代码 - Python技术站