springboot 整合 spring security,实现用户鉴权

在 Spring Boot 项目中整合 Spring Security 实现用户鉴权涉及多个步骤,包括依赖配置、配置类创建、安全配置、用户详情服务的实现等。下面是一个详细的步骤和关键代码示例,帮助你理解如何在 Spring Boot 中整合 Spring Security。

1. 添加依赖

首先,在你的 pom.xml 文件中添加 Spring Security 相关的依赖。Spring Boot 的 Spring Security Starter 可以帮助你轻松集成 Spring Security。

<dependencies>
    <!-- Spring Boot Starter Security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
    <!-- Spring Boot Starter Web, 如果你的项目还没有的话 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- 数据库相关依赖,如果使用数据库存储用户信息 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    
    <!-- H2 Database (可选,用于测试或开发环境) -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

2. 配置 Spring Security

Spring Security 的配置主要包括创建一个配置类 SecurityConfig,继承 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.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/public/**").permitAll() // 公开访问路径
                .antMatchers("/admin/**").hasRole("ADMIN") // 只有 ADMIN 角色可以访问
                .anyRequest().authenticated() // 其他所有请求都需要认证
                .and()
            .formLogin() // 表单登录
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user")
                .password(passwordEncoder().encode("password"))
                .roles("USER")
                .and()
                .withUser("admin")
                .password(passwordEncoder().encode("admin"))
                .roles("USER", "ADMIN");
    }

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

在上面的代码中:

  • configure(HttpSecurity http) 方法定义了哪些路径是公开的,哪些路径需要特定角色的用户才能访问。还定义了登录页面和登出功能。
  • configure(AuthenticationManagerBuilder auth) 方法定义了用户的认证方式,这里我们使用了内存中的用户和角色。实际项目中你可能会用数据库来存储用户信息。
  • passwordEncoder() 方法提供了密码加密的方式,使用 BCryptPasswordEncoder 是推荐的做法。

3. 自定义用户详细信息服务

在实际项目中,你可能需要从数据库加载用户信息。你需要实现 UserDetailsService 接口,并提供自定义的用户加载逻辑。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository; // 假设你有一个 UserRepository 访问用户数据

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserEntity user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found"));
        
        return org.springframework.security.core.userdetails.User.builder()
                .username(user.getUsername())
                .password(user.getPassword())
                .roles(user.getRoles().toArray(new String[0])) // 将用户角色转换为字符串数组
                .build();
    }
}

你需要有一个 UserRepository 访问数据库中的用户数据以及一个 UserEntity 实体类来表示用户数据。

4. 实体类和存储库

定义一个 UserEntity 类来表示用户信息:

 

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ElementCollection;
import java.util.Set;

@Entity
public class UserEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
    private String password;

    @ElementCollection
    private Set<String> roles;

    // Getters and Setters
}

定义一个 UserRepository 接口:

import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;

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

5. 配置登录和登出页面

创建自定义登录页面 /src/main/resources/templates/login.html

<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
    <h2>Login Page</h2>
    <form 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>
        <div>
            <button type="submit">Login</button>
        </div>
    </form>
</body>
</html>

创建登出页面 /src/main/resources/templates/logout.html(可选):

<!DOCTYPE html>
<html>
<head>
    <title>Logout</title>
</head>
<body>
    <h2>You have been logged out</h2>
    <a href="/login">Login Again</a>
</body>
</html>

6. 测试应用

启动你的 Spring Boot 应用,访问 /login 来查看登录页面。使用配置中的用户名和密码进行登录(如 userpasswordadminadmin),并测试不同角色和权限的访问控制。

总结

以上内容提供了一个 Spring Boot 项目中整合 Spring Security 的基本流程和关键代码。实际上,你可能还需要根据项目的具体需求进行更多的自定义配置,如处理不同的认证方式、集成 OAuth2、JWT 等。这个基础的示例应该能帮助你入门 Spring Security 的集成和配置。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《Vue和SpringBoot打造假日旅社管理系统》课程,将讲解如何使用Vue和SpringBoot开发这个项目,手把手演示开发流程!附赠源码、文档、数据库脚本等全部资料,提供售后答疑。 课程简介本课程讲解的是《基于 Vue 和 SpringBoot 的假日旅社管理系统》,该系统支持民宿档案、民宿新闻、民宿预定、民宿评论这四大核心业务,适用于乡村民宿企业的民宿预定业务。系统给每个民宿档案提供一个唯一标识,对民宿预定、评论等各个环节进行快速批量的数据采集,确保游客及时掌握景区民宿的真实数据,方便游客进行民宿预定。另外系统还包括员工管理、组织机构管理、文件管理、权限管理功能,给旅社企业提供更个性化的民宿管理模式。假日旅社管理系统采用了基于角色的访问控制,角色和菜单关联,一个角色可以配置多个菜单权限;然后再将用户和角色关联,一位用户可以赋予多个角色。这样用户就可以根据角色拿到该有的菜单权限,更方便旅社企业的管理人员进行权限管控。   软件技术选型前端Vue:Vue 是构建前端界面的核心框架,本系统采用 2.6.14 版本。View UI:基于 Vue.js2.0 的组件库,本系统采用 4.7.0 版本。后端Spring Boot:构建系统核心逻辑的后端框架,本系统采用 2.7.0 版本。MyBatis / MyBatis Plus:后端连接数据库的框架,本系统采用 3.5.2 版本。数据库MySQL:本项目的主数据库,本系统采用 8.0.29 版本。Redis:本系统采用基于 Windows 版本的 Redis,用于图形验证码和用户菜单权限的临时存储,采用了 5.0.14 版本。开发环境VsCode:项目前端的开发工具,使用版本为 1.68.0。IntelliJ IDEA :项目后端的开发工具,使用版本为 2021.3.2。Jdk:Java 的开发环境,使用版本为 17.0.3.1。Maven:后端项目的打包工具,使用版本为 3.6.2。NodeJs:前端项目的开发环境,使用版本为 16.13.0。 软件架构分析基于 Vue 和 SpringBoot 的假日旅社管理系统包括了系统基础模块、民宿档案模块、民宿新闻模块、民宿预定模块、民宿评论模块这五大功能模块,其架构如下图所示。  接下来,分别对五大模块进行详细介绍。系统基础模块系统基础模块,是用于支撑假日旅社管理系统的正常运行,这个模块包括了登陆注册模块、员工部门管理、菜单权限管理等。假日旅社管理系统支持用户使用账号、密码和图形验证码登陆,操作界面如下图所示。  假日旅社管理系统支持用户使用手机号、姓名、密码和图形验证码注册,操作界面如下图所示。 用户成功进入系统后,可进入到基于 Vue 和 SpringBoot 的假日旅社管理系统的首页,首页展示了当前登陆的地址、现在的时间和用户配置的常用模块,如下图所示。 接着用户点击左侧的用户管理,即可进入用户管理模块,用户管理模块的首页如下图所示。 用户可以在这个模块对系统登陆用户的档案进行维护,包括添加新用户、删除用户、编辑用户、根据姓名/部门查询用户用户可以进入部门管理模块,管理旅社的部门数据,如下图所示。 同理用户可以进入到菜单管理模块,对系统的菜单进行管理,菜单管理模块的操作界面如下图所示。 民宿档案模块第二个模块是民宿档案模块,民宿档案就是用来管理民宿的数据,民宿档案包括民宿的名称、面积、房号、房间类型、早餐情况、价格、备注等,以下是民宿档案模块的主界面。用户可以点击顶部的“新增”按钮,进入民宿档案添加界面,添加民宿档案数据,如下图所示。 其中房间类型为下拉框单项选择,如下图所示。还有早餐情况也是下拉单选,如下图所示。 用户可以对现有的民宿档案数据进行编辑更新,只需点击每一行民宿档案数据的“编辑”按钮,即可进入民宿档案数据的编辑界面,如下图所示。 用户也可以对不需要的民宿数据进行删除操作,用户点击删除时,系统会弹出二次确认弹框,如下图所示。  民宿新闻模块第三个模块是民宿新闻模块,民宿新闻就是用来管理民宿的新闻资讯,包含的功能如下所示。 民宿新闻包括民宿的名称、面积、房号、房间类型、早餐情况、价格、备注等,以下是民宿新闻模块的主界面,其中的图片仅供测试样例使用。用户可以点击顶部的“新增”按钮,进入民宿新闻添加界面,添加民宿新闻数据,如下图所示。 新闻描述字段采用了 ueditor 富文本编辑器,这是由百度 web 前端研发部开发的所见即所得的开源富文本编辑器,具有轻量、可定制、用户体验优秀等特点,基于 MIT 开源协议,所有源代码可自由修改和使用。 用户可以对现有的民宿新闻数据进行编辑更新,只需点击每一行民宿新闻数据的“编辑”按钮,即可进入民宿新闻数据的编辑界面,如下图所示。 民宿预定模块第四个模块是民宿预定模块,旅客可以在民宿预定模块中预定民宿,达到旅客的住宿目的,民宿预定模块包含的功能如下所示。民宿预定包括了预定民宿 ID、预定民宿名称、预定日期、下单时间、下单人 ID、下单人姓名、价格、是否付款、下单备注等字段,旅客首先进入民宿档案模块,可以看到每一行民宿数据都有一个预约按钮,如下图所示。 如用户点击 1 幢 102 民宿的预约按钮后,会弹出预约确认框,需要输入预约的日期,日期表单默认选择今日,如下图所示。 旅客需要点击“确认预约”按钮,完成预约操作,系统给与“预约成功”提示,如下图所示。 预约成功后,旅客可以从民宿预定模块中进行查询,如下图所示。 最后旅客进行付款操作,点击每一行右侧的付款按钮,如下图所示。支付完成后,系统将预定单的支付状态改为付款,预定流程结束,如下图所示。 民宿评论模块 第五个模块是民宿预定模块,旅客可以在民宿预定结束后评论民宿,以帮助更多的人了解民宿,民宿评论模块包含的功能如下所示。 民宿评论包括了民宿名称、民宿 ID、评论时间、评论内容、评论人 ID、评论人姓名等字段,旅客首先进入民宿档案模块,可以看到每一行民宿数据都有一个评论按钮,如下图所示。 旅客点击评论后,系统给与弹框反馈,如下图所示。  用户输入评论内容后,点击确认评论按钮,即可完成评论操作,如下图所示。  旅客评论后,即可在民宿评论模块中查看此评论数据,如下图所示。 也可以在民宿模块中,双击民宿数据查看评论信息,如下图所示。 项目总结本软件是基于 Vue 和 SpringBoot 的假日旅社管理系统,包含了民宿档案、民宿新闻、民宿预定、民宿评论这四个功能模块。 开发本系统的目的,就是为了帮助旅游景点的民宿企业提高民宿管理效率,降低人力成本,让旅游景点的民宿企业获得更多的经济效益。
Spring Boot是一个开发Java应用程序的框架,AOP(面向切面编程)是Spring框架的一个核心特性之一,用于在程序运行期间的特定位置插入切面(Aspect)。而接口鉴权是一种常见的安全机制,用于确保用户具有足够的权限来访问特定的接口。 在Spring Boot中,可以使用AOP来实现接口鉴权。首先,需要定义一个切面类,以便在访问接口之前进行鉴权操作。可以使用@Aspect注解标记该类为一个切面。 接下来,可以使用@Before注解标记一个方法,该方法将在调用目标接口之前执行。在这个方法中,可以编写鉴权逻辑,例如检查用户的身份或权限,并根据结果决定是否允许访问目标接口。 示例代码如下所示: ```java @Aspect @Component public class AuthorizationAspect { @Before("execution(* com.example.api.*.*(..))") public void authorize(JoinPoint joinPoint) { // 获取当前登录用户的身份或权限信息 String userRole = getCurrentUserRole(); // 获取目标接口的注解信息 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); Authorization annotation = methodSignature.getMethod().getAnnotation(Authorization.class); // 检查用户的身份或权限是否满足目标接口的要求 if (!hasPermission(userRole, annotation)) { throw new UnauthorizedException("Unauthorized access"); } } private String getCurrentUserRole() { // 获取当前登录用户的身份或权限信息的逻辑 } private boolean hasPermission(String userRole, Authorization annotation) { // 检查用户的身份或权限是否满足目标接口的要求的逻辑 } } ``` 在目标接口上,需要使用一个自定义的注解(例如@Authorization)来标记该接口需要进行鉴权操作。例如: ```java @RestController @RequestMapping("/api/users") public class UserController { @Authorization @GetMapping("/{id}") public User getUserById(@PathVariable Long id) { // 根据用户ID查询用户信息的逻辑 } } ``` 通过这种方式,当用户访问需要进行鉴权操作的接口时,切面类中的鉴权方法将被调用,并根据用户的身份或权限判断是否允许访问接口。如果鉴权失败,则可以抛出异常或返回相应的错误信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值