首页 > 其他分享 >Spring Security 简单使用教程

Spring Security 简单使用教程

时间:2024-08-06 23:52:47浏览次数:9  
标签:教程 Spring springframework user import org Security security

Spring Security 是一个强大的、安全性框架,用于保护 Spring 应用程序。本文将详细介绍如何在一个 Spring Boot 项目中使用 Spring Security,从基础配置到自定义安全需求。

创建 Spring Boot 项目

首先,我们需要创建一个 Spring Boot 项目。可以通过 Spring Initializr 快速生成项目。

  1. 访问 Spring Initializr.
  2. 选择如下选项:
    • Project: Gradle Project 或 Maven Project
    • Language: Java
    • Spring Boot: 最新稳定版本
  3. 添加依赖:
    • Spring Web
    • Spring Security
    • Spring Data JPA(用于后续数据库操作)
    • H2 Database(用于演示)

生成并下载项目,解压后使用你喜欢的 IDE(如 IntelliJ IDEA 或 Eclipse)打开。

引入 Spring Security 依赖

如果你通过 Spring Initializr 创建了项目,Spring Security 依赖应该已经包括在内。如果没有,可以手动添加依赖:

Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Gradle:

implementation 'org.springframework.boot:spring-boot-starter-security'

默认配置和基本认证

Spring Security 默认提供了基本的 HTTP Basic 认证。启动项目后,访问任意端点,你会被要求输入用户名和密码。

默认情况下,Spring Boot 会生成一个随机密码并打印在控制台。默认用户名是 user

Using generated security password: <generated-password>

自定义用户认证

让我们创建一个自定义的用户认证。首先,创建一个配置类来扩展 WebSecurityConfigurerAdapter

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build());
        manager.createUser(User.withDefaultPasswordEncoder()
                .username("admin")
                .password("admin")
                .roles("ADMIN")
                .build());
        return manager;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasRole("USER")
                .antMatchers("/", "/home").permitAll()
                .and()
                .formLogin();
    }
}

基于数据库的用户认证

接下来,配置基于数据库的用户认证。首先,创建用户实体类和数据库表。

User 实体类:

import javax.persistence.*;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    private String role;

    // getters and setters
}

UserRepository 接口:

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsername(String username);
}

数据库初始化脚本:
src/main/resources 目录下创建 data.sql 文件,初始化一些数据。

INSERT INTO user (username, password, role) VALUES ('user', 'password', 'ROLE_USER');
INSERT INTO user (username, password, role) VALUES ('admin', 'admin', 'ROLE_ADMIN');

SecurityConfig 配置:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserRepository userRepository;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected UserDetailsService userDetailsService() {
        return username -> {
            User user = userRepository.findByUsername(username);
            if (user == null) {
                throw new UsernameNotFoundException("User not found");
            }
            return org.springframework.security.core.userdetails.User
                    .withUsername(user.getUsername())
                    .password(passwordEncoder().encode(user.getPassword()))
                    .roles(user.getRole())
                    .build();
        };
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasRole("USER")
                .antMatchers("/", "/home").permitAll()
                .and()
                .formLogin();
    }
}

自定义登录页面

创建一个自定义的登录页面。首先,在 src/main/resources/templates 目录下创建一个 login.html 文件。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Login</title>
</head>
<body>
<h1>Login</h1>
<form th:action="@{/login}" method="post">
    <div>
        <label>Username:</label>
        <input type="text" name="username"/>
    </div>
    <div>
        <label>Password:</label>
        <input type="password" name="password"/>
    </div>
    <div>
        <button type="submit">Login</button>
    </div>
</form>
</body>
</html>

然后,在 SecurityConfig 中配置自定义登录页面。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .antMatchers("/", "/home").permitAll()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll();
}

方法级别的安全性

Spring Security 还支持方法级别的安全性。我们可以在服务层使用注解来保护方法。

首先,启用全局方法安全性。在主应用程序类中添加 @EnableGlobalMethodSecurity(prePostEnabled = true) 注解。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

然后,在服务层方法上使用 @PreAuthorize 注解。

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    public void adminMethod() {
        // admin only logic
    }

    @PreAuthorize("hasRole('ROLE_USER')")
    public void userMethod() {
        // user only logic
    }
}

处理跨站请求伪造(CSRF)

Spring Security 默认启用了 CSRF 保护。在开发和测试过程中,我们可能需要禁用它。在 SecurityConfig 中进行配置。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .antMatchers("/", "/home").permitAll()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll();
}

日志记录和异常处理

我们可以通过自定义 AuthenticationEntryPointAccessDeniedHandler 来处理认证和授权异常。

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;


import org.springframework.security.web.access.AccessDeniedHandlerImpl;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }
}

@Component
public class CustomAccessDeniedHandler extends AccessDeniedHandlerImpl {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
        response.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden");
    }
}

SecurityConfig 中配置这些组件。

@Autowired
private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

@Autowired
private CustomAccessDeniedHandler customAccessDeniedHandler;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .antMatchers("/", "/home").permitAll()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
            .exceptionHandling()
            .authenticationEntryPoint(customAuthenticationEntryPoint)
            .accessDeniedHandler(customAccessDeniedHandler);
}

总结

通过这篇详细的教程,我们已经学习了如何在 Spring Boot 项目中集成 Spring Security,包括基本配置、自定义用户认证、基于数据库的用户认证、自定义登录页面、方法级别的安全性、CSRF 保护以及日志记录和异常处理。Spring Security 提供了强大的功能和灵活的配置选项,使我们能够根据需求来保护应用程序的安全。

标签:教程,Spring,springframework,user,import,org,Security,security
From: https://blog.csdn.net/qq_21484461/article/details/139692525

相关文章

  • Spring Security 的常用方法介绍
    当使用SpringSecurity时,有几种常见的方法和配置模式可以帮助您更好地保护和管理应用程序的安全性。除了上文中已经介绍的基本配置、自定义认证、方法级安全性和异常处理之外,还有一些其他重要的方法和技术,让我们来详细了解它们。常用方法和技术1.使用表达式进行授权Spri......
  • 【项目实战】整合阿里云短信服务到 Spring Boot 项目中,以实现短信发送功能
    一,需求描述整合阿里云短信服务到SpringBoot项目中,以实现短信发送功能短信商:阿里短信SDK:aliyun-java-sdk-core二,需求实现需要按照以下步骤进行操作:2.1第一步:注册阿里云账号并开通短信服务访问阿里云官网,注册账号并登录。进入短信服务页面,申请并开通短信服务。......
  • 微信小程序教程011-4:京西购物商城实战之分类页实现
    文章目录4、分类4.0创建cate分支4.1渲染分类页面的基本结构4.2获取分类数据4.3动态渲染左侧的一级分类列表4.4动态渲染右侧的二级分类列表4.5动态渲染右侧的三级分类列表4.6切换一级分类后重置滚动条的位置4.7点击三级分类跳转到商品列表页面4.8分......
  • Spring Boot 依赖之 lombok的@Data注解
    SpringBoot依赖之lombok的@Data注解编译之后的代码Java源代码引入lombok一、创建SpringBoot项目启动IntelliJIDEA,点击File->New->Project...在新项目对话框中,选择SpringInitializr,点击Next配置SpringInitializr项目元数据,如Group=com.dependen......
  • serial靶机教程
    靶机下载地址https://download.vulnhub.com/serial/serial.zip主机发现arp-scan-l端口扫描nmap192.168.229.131-A根据对⽐可知serial的⼀个ip地址为192.168.47.143该靶机开启了22端⼝和80端⼝对⽹站进⾏⼀个访问,⼤概意思为这是对新的cookie处理程序的测试版暂......
  • Spring Task详细使用
    一、定时任务的理解定时任务即系统在特定时间执行一段代码,它的场景应用非常广泛:购买游戏的月卡会员后,系统每天给会员发放游戏资源。管理系统定时生成报表。定时清理系统垃圾。定时任务的实现主要有以下几种方式:1、Java自带的java.util.Timer类,这个类允许调度一个java.util.......
  • Spring Boot(八十五):集成Apache PDFBox对pdf文件进行操作
    1 ApachePDFBox简介ApachePDFBox是一个强大的Java库,它可以用来读取、修改和创建PDF文件。在本教程中,我们将介绍如何在SpringBoot项目中集成PDFBox来实现PDF文件的读取与导出功能。官网地址:ApachePDFBox|AJavaPDFLibrary2代码示例创建一个springboot项目。2.1......
  • jsoncpp库的简易引入教程
    1.打开github上项目的主页jsoncpp2.clone到本地gitclonehttps://github.com/open-source-parsers/jsoncpp.git3.生成jsoncpp库的头文件以及源文件进入项目目录![[Pastedimage20240510150641.png]]执行Python命令,pythonamalgamate.py![[Pastedimage20240510150......
  • 【Mind+】掌控板入门教程05 心情灯
        大自然的各种色彩使人产生各种感觉,心理学家认为,不同的颜色会让人产生不同的情绪。比如,红色通常给人刺激、热情和幸福的感觉,而绿色作为自然界中草原和森林的颜色,给人以理想、年轻、新鲜的感觉,蓝色则让人感到悠远、宁静等等。    今天就让我们用......
  • Spring DI
    目录一、主要概念1.依赖2.控制反转(IoC)3.注入方式4.Spring容器二、优点三、示例SpringDI(DependencyInjection,依赖注入)是一种设计模式,用于实现控制反转(InversionofControl,IoC)。在Spring框架中,DI是核心特性之一,通过将对象的创建和管理从应用程序代码中抽离出......