下面是Spring Boot安全认证Security的实现方法的完整攻略。
1. Spring Security简介
Spring Security是基于Spring框架的安全认证框架,在Spring Boot项目中可以很方便地实现用户身份认证和授权管理。
Spring Security提供了一个功能强大且灵活的框架,能够应对绝大多数的安全需求。它提供了许多可自定义的插件和配置选项,使得开发人员可以根据自身需求来定制安全策略。
2. 依赖管理
要使用Spring Security,需要在pom.xml文件中添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
3. 配置Spring Security
3.1 配置用户信息
在Spring Security中,需要配置用户信息。可以在配置类中添加一个方法,返回一个UserDetails类型的对象。例如:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public UserDetailsService userDetailsService() {
String password = new BCryptPasswordEncoder().encode("123456");
UserDetails user = User.withUsername("user")
.password(password)
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll();
}
}
上面的配置中,我们定义了一个用户,用户名为“user”,密码为“123456”,角色为“USER”。
3.2 配置安全策略
在SecurityConfig类中,我们需要重写WebSecurityConfigurerAdapter类中的configure(HttpSecurity http)方法,配置安全策略。
在这个方法中,我们可以设置哪些请求需要认证,哪些请求不需要认证,以及如何处理认证和授权过程。例如:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/index").permitAll() // 静态资源和首页不需要认证
.antMatchers("/user/**").hasRole("USER") // user目录下的请求需要用户角色才能访问
.and().formLogin().loginPage("/login").failureUrl("/login-error") // 自定义登录界面和失败页
.and().exceptionHandling().accessDeniedPage("/401"); // 自定义权限不足页面
}
4. 示例
下面是两个简单的示例,演示如何使用Spring Security认证功能。
4.1 示例1:基本认证功能实现
首先,我们创建一个简单的Spring Boot项目,并添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
然后,在配置类中添加如下配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/index").permitAll()
.antMatchers("/user/**").hasRole("USER")
.and().formLogin().loginPage("/login").failureUrl("/login-error")
.and().exceptionHandling().accessDeniedPage("/401");
}
}
在我们的示例中,我们只为“user”这个用户配置了一个角色:USER。用户的密码经过了BCrypt加密,密码为“123456”。
创建一个UserController类:
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/list")
public String userList() {
return "user list";
}
@GetMapping("/add")
public String addUser() {
return "add user";
}
}
在UserController中,我们配置了两个请求:/user/list 和 /user/add。配置了“USER”角色的用户可以访问这两个请求,没有配置“USER”角色的用户则无法访问。
接下来我们需要创建一个登录页面和一个授权不足页面。
创建一个LoginController类:
@Controller
public class LoginController {
@GetMapping("/login")
public String login() {
return "login";
}
@GetMapping("/login-error")
public String loginError(Model model) {
model.addAttribute("loginError", true);
return "login";
}
}
在这个类中,我们定义了两个请求:/login 和 /login-error。/login是我们的登录页面,/login-error是登录失败后的跳转页面。
在templates目录下创建login.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<div th:if="${loginError}">
Invalid username or password!
</div>
<form th:action="@{/login}" method="post">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username"/>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password"/>
</div>
<button type="submit">Sign in</button>
</form>
</body>
</html>
在public目录下创建401.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Access Denied</title>
</head>
<body>
<h1>Access Denied</h1>
<p>Sorry, you don't have permission to access this page.</p>
</body>
</html>
最后再创建一个启动类:
@SpringBootApplication
public class SecurityDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SecurityDemoApplication.class, args);
}
}
启动项目,访问http://localhost:8080/login,进入登录页面。输入用户名和密码(用户名为“user”,密码为“123456”),点击Sign in按钮,即可登录成功。
如果输入的用户名或密码错误,则会跳转到 /login-error 页面。如果有一个未授权的用户尝试访问/user/list或/user/add页面,就会被重定向到 /401 页面。
4.2 示例2:使用数据库存储用户信息
上面的示例中,我们通过在代码中硬编码的方式配置了用户名和密码。但在实际开发中,我们一般会将用户信息保存在数据库中。下面我们演示如何使用数据库存储用户信息。
首先,在pom.xml文件中添加如下依赖:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-data</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
然后在数据库中创建两张表,users和authorities。其中users表用于保存用户信息,authorities表用于保存用户的权限信息。
create table users (
username varchar(50) not null primary key,
password varchar(100) not null,
enabled boolean not null
);
create table authorities (
username varchar(50) not null,
authority varchar(50) not null,
constraint fk_authorities_users foreign key (username) references users (username)
);
接下来,我们需要在SecurityConfig类中配置用户认证信息的来源,即UserDetailsService。UserDetailsService是一个接口,是用来获取用户详细信息的。我们可以使用Spring Security提供的JdbcUserDetailsManager来访问数据库中的用户信息。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@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(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/index").permitAll()
.antMatchers("/user/**").hasRole("USER")
.and().formLogin().loginPage("/login").failureUrl("/login-error")
.and().exceptionHandling().accessDeniedPage("/401");
}
}
这里我们配置了一个JdbcUserDetailsService,从users表和authorities表中获取用户的信息和角色信息。
最后,我们需要创建一个用于初始化用户信息的数据脚本。
执行以下SQL脚本,可以向users表和authorities表中插入初始数据:
insert into users (username, password, enabled) values ('admin', '$2a$10$5dAfNL4fb8TEqvg2Z9yYn.OrtlQfugCZaUEjoX9bnutgQqjRlWkM2', true);
insert into authorities (username, authority) values ('admin', 'ROLE_ADMIN');
在UserController类中添加一个/admin接口:
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/list")
public String userList() {
return "user list";
}
@GetMapping("/add")
public String addUser() {
return "add user";
}
@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public String admin() {
return "admin page";
}
}
在配置类SecurityConfig中添加一个君子,向/ADMIN路径授权:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/index").permitAll()
.antMatchers("/user/**").hasRole("USER")
.antMatchers("/admin/**").hasRole("ADMIN")
.and().formLogin().loginPage("/login").failureUrl("/login-error")
.and().exceptionHandling().accessDeniedPage("/401");
}
完成之后,启动Spring Boot应用,访问http://localhost:8080/login,输入用户名和密码(用户名为“admin”,密码为“123456”),点击登陆按钮。输入正确的用户名和密码后,成功进入应用。在地址栏输入http://localhost:8080/user/add,可以看到访问成功。但是当访问http://localhost:8080/user/admin路劲时,将会被重定向到401页面,表示您没有admin角色,没有访问的权限。
以上就是SpringBoot安全认证Security的实现方法的攻略,希望能对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot安全认证Security的实现方法 - Python技术站