有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java将数据库身份验证添加到Spring数据Rest应用程序

我正在使用SpringDataREST和Thymeleaf创建一个应用程序

最初,我创建了模型、控制器、dao和服务。一切都很好。我现在正在尝试为我的应用程序添加安全性。现在我只关注登录/注销

我已经能够创建内存内身份验证,如下所示:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    

    
    @Autowired
    @Qualifier("securityDataSource")
    private DataSource securityDataSource;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        
        // add users for in memory authentication
        UserBuilder users = User.withDefaultPasswordEncoder();
        
        auth.inMemoryAuthentication()
        .withUser(users.username("paul").password("test123").roles("MEMBER", "ADMIN"))
        .withUser(users.username("sandra").password("test123").roles("MEMBER", "ADMIN"))
        .withUser(users.username("matthew").password("test123").roles("MEMBER"));
    }

}

但我想将此更改为数据库身份验证。我非常确定我可以创建一个jdbc连接,并将配置方法更改为如下内容:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.jdbcAuthentication().dataSource(securityDataSource);
        
}

我的问题是我已经通过DAO接口访问了数据库。例如:

public interface UserRepository extends JpaRepository<User, Integer> {
    
    // method to sort by last name
    public List<User> findAllByOrderByLastNameAsc();

}

“我的用户”表有一个电子邮件和密码列,将用作用户名/密码

是否可以通过某种方式使用它进行身份验证?我可以提供额外的信息,但我不愿意只是张贴一切,希望有人会为我写


共 (2) 个答案

  1. # 1 楼答案

    因为您已经创建了DAO接口,所以创建DAO接口可能更容易 一个UserDetailsService实现:

    @Service
    @NoArgsConstructor @ToString @Log4j2
    public class UserDetailsServiceImpl implements UserDetailsService {
        @Autowired private UserRepository userRepository = null;
    
        @Override
        @Transactional(readOnly = true)
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            org.springframework.security.core.userdetails.User user = null;
    
            try {
                Optional<User> optional = userRepository.findBy...(username);
                HashSet<GrantedAuthority> set = new HashSet<>();
                /*
                 * Add SimpleGrantedAuthority to set as appropriate
                 */
                user = new org.springframework.security.core.userdetails.User(username, optional.get().getPassword(), set);
            } catch (UsernameNotFoundException exception) {
                throw exception;
            } catch (Exception exception) {
                throw new UsernameNotFoundException(username);
            }
    
            return user;
        }
    }
    

    并将其连接到:

        @Autowired private UserDetailsService userDetailsService = null;
        ... private PasswordEncoder passwordEncoder = ...;
    
        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder);
        }
    

    为了更加清晰,以下是我的实现的完整背景:

    @Service
    @NoArgsConstructor @ToString @Log4j2
    public class UserDetailsServiceImpl implements UserDetailsService {
        @Autowired private CredentialRepository credentialRepository = null;
        @Autowired private AuthorityRepository authorityRepository = null;
    
        @Override
        @Transactional(readOnly = true)
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User user = null;
    
            try {
                Optional<Credential> credential = credentialRepository.findById(username);
                Optional<Authority> authority = authorityRepository.findById(username);
                HashSet<GrantedAuthority> set = new HashSet<>();
    
                if (authority.isPresent()) {
                    authority.get().getGrants().stream()
                        .map(Authorities::name)
                        .map(SimpleGrantedAuthority::new)
                        .forEach(set::add);
                }
    
                user = new User(username, credential.get().getPassword(), set);
            } catch (UsernameNotFoundException exception) {
                throw exception;
            } catch (Exception exception) {
                throw new UsernameNotFoundException(username);
            }
    
            return user;
        }
    }
    
  2. # 2 楼答案

    假设数据库表名为users和authorities。数据源在应用程序中配置。yml

        @Autowired
        private DataSource dataSource;
        
    @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.jdbcAuthentication()
                    .dataSource(dataSource)
                    .usersByUsernameQuery("select username,password,enabled from users WHERE username=?")
                    .authoritiesByUsernameQuery("select username,authority from authorities where username=?")
                    .passwordEncoder(new BCryptPasswordEncoder());
                    }
        }