【问题标题】:Authentication of users from two database tables in Spring Security从 Spring Security 中的两个数据库表对用户进行身份验证
【发布时间】:2018-08-29 11:45:47
【问题描述】:

我有两个表:用户和管理员。我有一个用户名、密码和角色。我想使用管理员或用户的任何一种形式登录。我试过这个:

@Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth.
                jdbcAuthentication().dataSource(dataSource)
                .usersByUsernameQuery("SELECT username,password FROM user WHERE username =?  UNION SELECT username,password FROM admin WHERE username =? ")
                .authoritiesByUsernameQuery("SELECT username,role FROM user WHERE username =?  UNION SELECT username,role FROM admin WHERE username =? ");
    }

,但我遇到了异常:

org.springframework.security.authentication.InternalAuthenticationServiceException: PreparedStatementCallback; bad SQL grammar [SELECT username,password FROM user WHERE username =?  UNION SELECT username,password FROM admin WHERE username =? ]; nested exception is java.sql.SQLException: No value specified for parameter 2

那么我怎样才能通过两种对象类型(用户、管理员)的身份验证登录系统?

【问题讨论】:

  • 您在查询中定义了 2 个参数,在 UNION 子句之前和之后,但 spring 只将用户名传递给其中一个参数,用于角色查询

标签: java spring-security


【解决方案1】:

这是一个使用自定义UserDetailsService 的非常粗略的解决方案。

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private AdminRepository adminRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // first try loading from User table
        User user = userRepository.findByUsername(username);
        if (user != null) {
            return new CustomUserDetails(user.getUsername(), user.getPassword(), user.getRole());
        } else {
            // Not found in user table, so check admin
            Admin admin = adminRepository.findByUsername(username);
            if (admin != null) {
                return new CustomUserDetails(admin.getUsername(), admin.getPassword(), admin.getRole());
            }
        }
        throw new UsernameNotFoundException("User '" + username + "' not found");
    }

    public class CustomUserDetails implements UserDetails {

        private String username;
        private String password;
        private Collection<? extends GrantedAuthority> authorities;

        public CustomUserDetails() {
            super();
        }

        public CustomUserDetails(String username, String password, String role) {
            this.username = username;
            this.password = password;
            List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
            grantedAuthorities.add(new SimpleGrantedAuthority(role));
            this.authorities = grantedAuthorities;
        }

        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return authorities;
        }

        @Override
        public String getPassword() {
            return password;
        }

        @Override
        public String getUsername() {
            return username;
        }

        @Override
        public boolean isAccountNonExpired() {
            return true;
        }

        @Override
        public boolean isAccountNonLocked() {
            return true;
        }

        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }

        @Override
        public boolean isEnabled() {
            return true;
        }

    }

}

还有配置

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http

                .authorizeRequests()
                .anyRequest().authenticated()
                .and().formLogin();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider());
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new CustomUserDetailsService();
    }

    @Bean
    public DaoAuthenticationProvider authProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService());
        // This assumes passwords are in plain text (but I hope they aren't!)
        authProvider.setPasswordEncoder(NoOpPasswordEncoder.getInstance());
        return authProvider;
    }

}

【讨论】:

    猜你喜欢
    • 2011-11-02
    • 2016-01-11
    • 2020-04-16
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 2019-12-26
    • 2015-06-18
    • 2011-08-21
    相关资源
    最近更新 更多