当前位置: 首页 > 知识库问答 >
问题:

如何在Spring Security中为来自两个不同表的不同用户配置身份验证?

闾丘冠玉
2023-03-14

在我的Spring启动应用程序中,我有2种不同类型的用户-用户和供应商,它们存储在我的SQL数据库的不同表中。

我只允许访问/user/login和/vendor/login,这将返回一个JWT。

我无法理解如何配置spring security,以便在有人请求/用户/登录时仅检查USERS表,在供应商请求/供应商/登录时仅检查VENDORS表。这可能吗?如果没有,谁能建议我如何配置Spring Security性来验证来自不同表的用户?

这是我当前的配置,仅在USERS上进行身份验证-

@Configuration
@EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService myUserDetailsService;   // this fetches data from the USERS table

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    // *** How do I configure this to check both VENDORS OR USERS table? ***
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests()
            .antMatchers("/user/auth/login").permitAll()
            .antMatchers("/vendor/auth/login").permitAll()
            .anyRequest().authenticated()
            .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

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

我已经为用户和供应商实现了UserDetailsService。下面是userService的实现-

@Service
public class UserService implements UserDetailsService {

    @Autowired
    private UserRepository repository;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    public UserService() {
    }

    public UserService(UserRepository repository) {
        this.repository = repository;
    }

    public Users findOne(String id) {
        Optional<Users> user = repository.findById(id);
        return user.orElse(null);
    }

    public List<Users> findAll() {
        List<Users> users = new ArrayList<>();
        repository.findAll().forEach(users::add);
        return users;
    }

    public Users insert(Users user) throws UnknownError {
        // somecode here
    }

    public Users update(String id, Users user) {
       // some code here
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        final Users user = findByEmail(username);
        if (user == null) {
            throw new UsernameNotFoundException("No user Found");
        }

        return new User(user.getEmail(), user.getPassword(), new ArrayList<>());
    }
}

这是UserController(VendorController与此类似)-

@RestController
@RequestMapping(path = "/user")
public class AuthController {

    @Autowired
    UserService service;

    @Autowired
    AuthenticationManager authenticationManager;

    @PostMapping(path = "/login")
    public ResponseEntity<?> login(@RequestBody AuthenticationRequest form) throws Exception {
        try {
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(form.getEmail(), form.getPassword()));
        } catch (Exception e) {
            throw new Exception("Incorrect Credentials");
        }

        final UserDetails user = service.loadUserByUsername(form.getEmail());
        Users returnedUser = service.insert(user);
        ResponseStructure response = new ResponseStructure(true, returnedUser);
        return ResponseEntity.ok(response);
    }

共有1个答案

景鹏飞
2023-03-14

您可以让UserService同时查找这两个存储库

@Service
public class UserService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private VendorRepository vendorRepository;

   // all the other stuff

    private Users findByUsername(String username){
        return userRepository.findByUserName(username);
    }

    private Vendors findByVendorName(String vendorName){
        return VendorRepository.findByVendorName(vendorName); // given you have such method declared in the Spring Data repository
    }

    @Override
    public UserDetails loadUserByName(String name) throws UsernameNotFoundException {
        Users user = findByUsername(name);
        if (user != null) {
             return new User(user.getEmail(), user.getPassword(), new ArrayList<>());
        }

        Vendors vendor = findByVendorName(name);

        if (vendor != null) {
             return new Vendor(vendor.getEmail(), vendor.getPassword(), new ArrayList<>());
        }
        else{
               throw new UsernameNotFoundException("No user Found");
        }

    }
}
 类似资料:
  • 我使用的是Spring3.1.1.版本和附带的Spring Security。我正在部署到JBoss7.1.1.final。我想配置两个http安全元素,每个元素都有不同的身份验证筛选器。我该怎么做?使用下面的Spring Security配置,我在部署WAR时得到异常“java.lang.IllegalArgumentException:在筛选器链中的其他模式之前定义了一个通用匹配模式('/**

  • 假设我有两个不同的模型和表,分别名为和。 正如你所知laravel使用模型来管理身份验证。但是因为我有两个不同的模型,我想可以分别管理它们。 我使用laravel 5.4,我不知道如何能做到这一点。

  • 我的应用程序对spring-data-rest访问使用基本身份验证(“/API/**”下的所有内容),对面向客户端的API使用UserDetailsService进行JWT身份验证(本例中的所有内容都在“/component”下)。在升级到Spring Boot2之前,我的一切工作如下: CORS的东西有一个单独的配置,我现在不关心,因为它以前工作得很好,现在不是任何麻烦的来源。 因此,在升级到S

  • 问题内容: 我有大约5个表,其中的公用字段为“ serid”。我想在所有这些表中计算不同的用户ID。某些用户ID可能出现在这些表中的大约2个中。但是我想将5个表中不同用户ID的UNION数在一起。我可以用ff代码在一张表中计算不同的用户ID。我希望能够从所有表中计数。 问题答案: 用一个 与相比,标准将从结果集中删除重复的值。您的陈述看起来像 从w3schools 默认情况下,UNION运算符仅选

  • 问题内容: 这是我的情况: 一个Web应用程序对许多应用程序执行某种SSO 登录的用户,而不是单击链接,该应用就会向正确的应用发布包含用户信息(名称,pwd [无用],角色)的帖子 我正在其中一个应用程序上实现SpringSecurity以从其功能中受益(会话中的权限,其类提供的方法等) 因此,我需要开发一个 自定义过滤器 -我猜想-能够从请求中检索用户信息,通过自定义 DetailsUserSe

  • 此时此刻,我不太确定如何处理这个问题。我还打算尝试使用外键。如有任何帮助,不胜感激。