SpringBoot安全认证Security的实现方法

下面是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技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 详解SpringBoot时间参数处理完整解决方案

    下面我将详细讲解“详解SpringBoot时间参数处理完整解决方案”的完整攻略。 一、背景简介 在SpringBoot应用开发中,我们经常需要处理时间类型的参数。而在不同的场景下,我们需要对时间参数的传参方式进行不同的处理。本篇文章将对SpringBoot时间参数的传入方式和处理方式进行深入探讨,并给出完整的解决方案。 二、时间参数的传入方式 时间参数作为U…

    Java 2023年5月20日
    00
  • java中字符串与日期的转换实例

    我们来详细讲解一下“java中字符串与日期的转换实例”的完整攻略。 1. 字符串转日期 在Java中,可以用SimpleDateFormat类的parse方法来将字符串转换成日期对象。具体步骤如下: (1)创建SimpleDateFormat实例: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-…

    Java 2023年6月1日
    00
  • SpringBoot浅析依赖管理与自动配置概念与使用

    SpringBoot浅析依赖管理与自动配置概念与使用 Spring Boot是一个基于Spring框架的快速开发应用程序的工具。它提供了一种快速、便捷的方式来创建基于Spring的应用程序,同时也提供了一些有用的功能,如自动配置、依赖管理等。在本文中,我们将详细讲解Spring Boot的依赖管理和自动配置概念与使用。 依赖管理 在Spring Boot中,…

    Java 2023年5月15日
    00
  • java用户管理注册功能 含前后台代码

    下面是Java用户管理注册功能的完整攻略。 1. 前期准备 在编写Java用户管理注册功能的程序前,我们需要准备以下几个方面的内容:数据库、Java Web框架和IDE。 1.1 数据库 Java用户管理与注册功能需要使用到数据库进行用户信息存储。常用的数据库有MySQL、Oracle、SQL Server等。在本教程中,我们使用MySQL数据库。 我们需要…

    Java 2023年5月19日
    00
  • Javascript与flash交互通信基础教程

    “Javascript与Flash交互通信基础教程”指的是在一个HTML页面中,使用Javascript与Flash技术实现相互通信,从而达到一些动态效果或交互功能的目的。具体的实现方式可以通过swfobject.js插件实现,以下是详细的攻略: 步骤一:创建Flash文件 首先需要使用Flash软件创建Flash文件,并且为Flash文件命名。在编写Fla…

    Java 2023年6月15日
    00
  • Spring Boot使用模板引擎JSP实例解析

    针对“Spring Boot使用模板引擎JSP实例解析”的完整攻略,我将按照以下步骤逐一解析: 1. 添加依赖 首先,我们需要在pom.xml中添加JSP依赖。在<dependencies>标签内添加以下代码: <dependencies> <!– 省略其他依赖 … –> <dependency> &l…

    Java 2023年5月19日
    00
  • JIT的作用是什么?

    以下是关于“JIT的作用是什么?”的详细讲解: JIT的作用是什么? JIT(Just-In-Time)是一种编译技术,它将代码在程序运行时动态编译成机器码。与静态编译不同,JIT在程序运行时才生成真正的可执行代码,因此它可以对代码进行更高效的优化,从而提高程序的性能。 JIT的主要作用包括: 在程序运行时优化代码,以提高程序的性能; 提高代码的可读性,减少…

    Java 2023年5月11日
    00
  • Java Apache Commons报错“ObjectCreationException”的原因与解决方法

    “ObjectCreationException”是Java的Apache Commons类库中的一个异常,通常由以下原因之一引起: 无效的对象:如果对象无效,则可能会出现此错误。在这种情况下,需要检查对象以解决此问题。 无效的配置:如果配置无效,则可能会出现此错误。在这种情况下,需要检查配置以解决此问题。 以下是两个实例: 例1 如果对象无效,则可以尝试检…

    Java 2023年5月5日
    00
合作推广
合作推广
分享本页
返回顶部