You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot Security多用户同端点Basic认证实现方法

Spring Boot多用户Basic认证落地实现方案

核心改造逻辑

原有代码仅从配置读取单组账号写入内存,无法满足多用户分凭证认证需求,本次改造覆盖两个核心要求:

  • 支持批量加载多组用户凭证,统一托管到Spring Security内存用户管理器
  • 新增请求身份一致性校验,Basic认证通过的用户名必须和请求传入的user参数匹配,避免跨用户越权访问
  • 修正原配置中路径匹配规则和实际接口路径不匹配的问题

第一步:调整多用户配置结构

替换原单组账号密码配置,改用列表形式存储多用户凭证,以application.yml为例:

app:
  auth:
    users:
      - username: user01
        password: pass01@2024
        role: OPERATOR
      - username: user02
        password: pass02@2024
        role: OPERATOR
      - username: admin
        password: admin@2024
        role: ADMIN

如果使用application.properties配置,写法如下:

app.auth.users[0].username=user01
app.auth.users[0].password=pass01@2024
app.auth.users[0].role=OPERATOR
app.auth.users[1].username=user02
app.auth.users[1].password=pass02@2024
app.auth.users[1].role=OPERATOR
app.auth.users[2].username=admin
app.auth.users[2].password=admin@2024
app.auth.users[2].role=ADMIN

第二步:定义配置映射类

用于绑定配置文件中的多用户列表为Java对象:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;

@Component
@ConfigurationProperties(prefix = "app.auth")
public class AuthUserProperties {
    private List<UserAuthConfig> users;

    public List<UserAuthConfig> getUsers() {
        return users;
    }

    public void setUsers(List<UserAuthConfig> users) {
        this.users = users;
    }

    public static class UserAuthConfig {
        private String username;
        private String password;
        private String role;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public String getRole() {
            return role;
        }

        public void setRole(String role) {
            this.role = role;
        }
    }
}

如果项目已引入Lombok,可直接给类加@Data注解省略getter/setter方法

第三步:改造安全配置类

基于原有代码做逻辑替换,完整可运行代码如下:

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.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

import javax.servlet.http.HttpServletRequest;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthUserProperties authUserProperties;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/").permitAll()
                // 匹配目标接口,绑定自定义身份校验规则
                .antMatchers("/function/id/**").access("@userMatchValidator.check(request,authentication)")
                .antMatchers("/login/**").authenticated()
                .and()
                .httpBasic();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        // 循环加载所有配置的用户凭证
        authUserProperties.getUsers().forEach(userConfig -> {
            String encodedPassword = passwordEncoder().encode(userConfig.getPassword());
            manager.createUser(User.withUsername(userConfig.getUsername())
                    .password(encodedPassword)
                    .roles(userConfig.getRole())
                    .build());
        });
        return manager;
    }

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

    // 自定义校验逻辑:请求参数user必须和当前Basic认证的用户名一致
    @Bean("userMatchValidator")
    public UserMatchValidator userMatchValidator() {
        return new UserMatchValidator();
    }

    public static class UserMatchValidator {
        public boolean check(HttpServletRequest request, org.springframework.security.core.Authentication authentication) {
            if (authentication == null || !authentication.isAuthenticated()) {
                return false;
            }
            String requestUser = request.getParameter("user");
            String currentAuthUser = authentication.getName();
            return currentAuthUser.equals(requestUser);
        }
    }
}

验证规则

  • 访问http://localhost:8080/function/id/?user=user01&id=xxx时,必须在Basic请求头中传入user01对应的正确密码,否则返回401
  • 若使用user01的账号密码发起请求,但参数传入user=user02,会直接返回403,拦截越权访问
  • 后续新增、修改用户凭证只需要调整配置文件列表,不需要修改业务代码

内容的提问来源于stack exchange,提问作者Rose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 19:09:23