Spring boot 我可以使用两个不同的表来登录SpringSecurity的SpringBoot应用程序吗?

Spring boot 我可以使用两个不同的表来登录SpringSecurity的SpringBoot应用程序吗?,spring-boot,authentication,spring-security,Spring Boot,Authentication,Spring Security,在我当前的项目中,我有两个独立的实体 用户:-对用户进行身份验证 客户:-验证客户身份 我很困惑,SpringSecurity如何管理同一项目中两个独立实体的登录过程 到目前为止,它与一个用户实体一起工作,现在我必须在Customer表的帮助下为客户集成一个登录 可能吗 注:-由于其他一些要求,我不能对用户和客户使用相同的表。 我正在分享一些代码以获得更多许可 下面的代码是用户详细信息服务的实现。 } 登录api @PostMapping(“/userLogin”) @定时 公众反应授权( @有

在我当前的项目中,我有两个独立的实体

  • 用户:-对用户进行身份验证
  • 客户:-验证客户身份
  • 我很困惑,SpringSecurity如何管理同一项目中两个独立实体的登录过程

    到目前为止,它与一个用户实体一起工作,现在我必须在Customer表的帮助下为客户集成一个登录

    可能吗

    注:-由于其他一些要求,我不能对用户和客户使用相同的表。 我正在分享一些代码以获得更多许可

    下面的代码是用户详细信息服务的实现。 }

    登录api
    @PostMapping(“/userLogin”)
    @定时
    公众反应授权(
    @有效@RequestBody UserLoginReq UserLoginReq){
    Map responseData=null;
    试一试{
    UsernamePasswordAuthenticationToken authenticationToken=新UsernamePasswordAuthenticationToken(
    userLoginReq.getUsername(),userLoginReq.getPassword());
    身份验证=this.authenticationManager
    .验证(authenticationToken);
    SecurityContextHolder.getContext()
    .setAuthentication(认证);
    

    }

    首先,客户也是用户,不是吗?所以可能更简单的解决方案是将客户也创建为用户(使用一些标志/db字段
    usertype={user | customer |……}
    )。如果您仍然需要管理两个实体,您的方法是正确的,但在您的DetailService中,只需实现另一个方法,该方法将读取customer实体,然后创建spring的用户。

    是的,您可以将用户类型组合在
    用户名中,并用如下字符分隔:

    例如:

  • String userName=inputUserName+“:APP\u USER”;

  • UsernamePasswordAuthenticationToken authenticationToken=
    新用户名PasswordAuthenticationToken(用户名、密码);

  • UserDetailsService.loadUserByUsername(用户名)
    首先,获取
    userName
    部分,同时获取
    userType
    部分。 现在在
    userType
    base上,您可以决定应该从哪个表中验证用户

    String userNamePart = null;
    if (userName.contains(":")) {
        int colonIndex = userName.lastIndexOf(":");
        userNamePart = userName.substring(0, colonIndex);
    }
    userNamePart = userNamePart == null ? userName : userNamePart;
    
    
    String userTypePart = null;
    if (userName.contains(":")) {
        int colonIndex = userName.lastIndexOf(":");
        userTypePart = userName.substring(colonIndex + 1, userName.length());
    }
    

  • “UserDetailsService”接口中只有一个方法,我已经实现了。请您再解释一下,我如何实现另一个方法?以及这个新方法将如何得到调用,到目前为止,它自动调用默认方法“loadUserByUsername”。如果您可以提供一些与此相关的链接,那就太好了……在这种方法中,您可以通过调用或另一个存储库来区分用户和客户。如果userRepository不返回用户,请尝试调用customerRepository。但我仍然认为您应该修改应用程序逻辑,并且只为auth用户使用一个实体。但是在这种情况下ase如果我想从customer表中验证凭据,并且相同的凭据存在于user表中而不是customer表中,那么它也将有效。对于多个身份验证过程来说,这是一种糟糕的方法吗?
    private final AuthenticationManagerBuilder authenticationManagerBuilder;
    
    private final UserDetailsService userDetailsService;
    
    private final TokenProvider tokenProvider;
    
    private final CorsFilter corsFilter;
    
    private final SecurityProblemSupport problemSupport;
    
    public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService,TokenProvider tokenProvider,CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
        this.authenticationManagerBuilder = authenticationManagerBuilder;
        this.userDetailsService = userDetailsService;
        this.tokenProvider = tokenProvider;
        this.corsFilter = corsFilter;
        this.problemSupport = problemSupport;
    }
    
    @PostConstruct
    public void init() {
        try {
            authenticationManagerBuilder
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
        } catch (Exception e) {
            throw new BeanInitializationException("Security configuration failed", e);
        }
    }
    
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
            .antMatchers(HttpMethod.OPTIONS, "/**")
            .antMatchers("/app/**/*.{js,html}")
            .antMatchers("/i18n/**")
            .antMatchers("/content/**")
            .antMatchers("/swagger-ui/index.html");
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
            .exceptionHandling()
            .authenticationEntryPoint(problemSupport)
            .accessDeniedHandler(problemSupport)
        .and()
            .csrf()
            .disable()
            .headers()
            .frameOptions()
            .disable()
        .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
            .authorizeRequests()
            .antMatchers("/api/register").permitAll()
            .antMatchers("/api/activate").permitAll()
            .antMatchers("/api/userLogin").permitAll()
            .antMatchers("/api/account/reset-password/init").permitAll()
            .antMatchers("/api/account/reset-password/finish").permitAll()
            .antMatchers("/api/**").authenticated()
            .antMatchers("/management/health").permitAll()
            .antMatchers("/management/info").permitAll()
            .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
            .antMatchers("/v2/api-docs/**").permitAll()
            .antMatchers("/swagger-resources/configuration/ui").permitAll()
            .antMatchers("/swagger-ui/index.html").hasAuthority(AuthoritiesConstants.ADMIN)
        .and()
            .apply(securityConfigurerAdapter());
    
    }
    
    private JWTConfigurer securityConfigurerAdapter() {
        return new JWTConfigurer(tokenProvider);
    }
    
    @PostMapping("/userLogin")
    @Timed
    public Response<JWTToken> authorize(
            @Valid @RequestBody UserLoginReq userLoginReq) {
    
        Map<String, Object> responseData = null;
        try {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
                    userLoginReq.getUsername(), userLoginReq.getPassword());
    
            Authentication authentication = this.authenticationManager
                    .authenticate(authenticationToken);
    
            SecurityContextHolder.getContext()
                    .setAuthentication(authentication);
    
    String userNamePart = null;
    if (userName.contains(":")) {
        int colonIndex = userName.lastIndexOf(":");
        userNamePart = userName.substring(0, colonIndex);
    }
    userNamePart = userNamePart == null ? userName : userNamePart;
    
    
    String userTypePart = null;
    if (userName.contains(":")) {
        int colonIndex = userName.lastIndexOf(":");
        userTypePart = userName.substring(colonIndex + 1, userName.length());
    }