Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在spring security中为来自两个不同表的不同用户配置身份验证?_Java_Spring_Spring Boot_Authentication_Spring Security - Fatal编程技术网

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

Java 如何在spring security中为来自两个不同表的不同用户配置身份验证?,java,spring,spring-boot,authentication,spring-security,Java,Spring,Spring Boot,Authentication,Spring Security,在我的SpringBoot应用程序中,我有两种不同类型的用户-用户和供应商,它们存储在SQL数据库的不同表中 我只允许访问返回JWT的/user/login和/vendor/login 我无法理解如何配置spring security,以便在有人请求/user/login时只检查用户表,在供应商请求/vendor/login时只检查VENDORS表。这可能吗?如果没有,谁能建议我如何配置spring安全性来验证来自不同表的用户 这是我当前的配置,它只对用户进行身份验证- @Configurati

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

我只允许访问返回JWT的/user/login和/vendor/login

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

这是我当前的配置,它只对用户进行身份验证-

@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<>());
    }
}
@服务
公共类UserService实现UserDetailsService{
@自动连线
私有用户存储库;
@自动连线
专用BCryptPasswordEncoder BCryptPasswordEncoder;
公共用户服务(){
}
公共用户服务(用户存储库){
this.repository=存储库;
}
公共用户findOne(字符串id){
可选用户=repository.findById(id);
返回user.orElse(空);
}
公共列表findAll(){
列表用户=新建ArrayList();
repository.findAll().forEach(users::add);
返回用户;
}
公共用户插入(用户)引发未知错误{
//这里有些代码
}
公共用户更新(字符串id、用户){
//这里有一些代码
}
@凌驾
public UserDetails loadUserByUsername(字符串用户名)引发UsernameNotFoundException{
最终用户user=findByEmail(用户名);
if(user==null){
抛出新的UsernameNotFoundException(“未找到用户”);
}
返回新用户(User.getEmail(),User.getPassword(),new ArrayList());
}
}
这是UserController(VendorController与此类似)——

@RestController
@请求映射(路径=“/user”)
公共类授权控制器{
@自动连线
用户服务;
@自动连线
AuthenticationManager AuthenticationManager;
@后期映射(路径=“/login”)
公共响应身份登录(@RequestBody AuthenticationRequest form)引发异常{
试一试{
authenticationManager.authenticate(
新用户名PasswordAuthenticationToken(form.getEmail(),form.getPassword());
}捕获(例外e){
抛出新异常(“不正确的凭据”);
}
final UserDetails user=service.loadUserByUsername(form.getEmail());
Users returnedUser=service.insert(用户);
ResponseStructure response=新的ResponseStructure(true,returnedUser);
返回ResponseEntity.ok(响应);
}

您可以让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");
        }

    }
}
@服务
公共类UserService实现UserDetailsService{
@自动连线
私有用户存储库用户存储库;
@自动连线
私人卖主或仓库卖主或仓库;
//所有其他的东西
私人用户findByUsername(字符串用户名){
返回userRepository.findByUserName(用户名);
}
私有供应商findByVendorName(字符串vendorName){
return VendorRepository.findByVendorName(vendorName);//假设您在Spring数据存储库中声明了这样的方法
}
@凌驾
public UserDetails loadUserByName(字符串名)引发UsernameNotFoundException{
Users user=findByUsername(name);
如果(用户!=null){
返回新用户(User.getEmail(),User.getPassword(),new ArrayList());
}
供应商供应商=findByVendorName(名称);
如果(供应商!=null){
返回新供应商(Vendor.getEmail()、Vendor.getPassword()、new ArrayList());
}
否则{
抛出新的UsernameNotFoundException(“未找到用户”);
}
}
}

谢谢,但这不是一个理想的解决方案,因为我们先查看用户表,然后查看供应商表,然后再查看供应商表,如果供应商或用户的名称和密码相同,可能会造成问题。请注意,您的请求来自不同的登录URL。也许您可以向AuthenticationRequest添加用户类型并根据用户类型选择正确的存储库。您可以将userType属性作为隐藏输入添加到登录表单中以使其变得简单,也可以将HttpServletRequest作为参数添加到login方法中,并获取use getRequestURI()以了解请求的来源
@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");
        }

    }
}