我正在使用带有Thymeleaf的Spring Data REST创建应用程序。
最初,我创建了模型,控制器,Dao和服务。一切正常。我现在正尝试为我的应用程序增加安全性。现在,我只是专注于登录/注销。
我已经能够创建一个内存中身份验证,如下所示:
#lang racket
(define lst
'(("a" "a")
("b" "a")
("c" "z")
("c" "a")
("b" "z")
("d" "a")
("a" "z")
("d" "z")))
(define (sort-items-index lst)
(local [(define index-lst
(map (λ (s) (string-length (first s))) lst))
(define (combile-2-str s)
(string-append (first s) (second s)))
(define (spilt-str-by-index s n)
(list (substring s 0 n) (substring s n (string-length s))))]
(map spilt-str-by-index
(sort (map combile-2-str lst) string<?)
index-lst)))
(sort-items-index lst)
(define (sort-items-v2 lst)
(sort lst (λ (s1 s2)
(string<?
(string-append (first s1) (second s1))
(string-append (first s2) (second s2))))))
(sort-items-v2 lst)
我想将其更改为数据库身份验证。我很确定我可以创建一个jdbc连接并将我的config方法更改为如下所示:
@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"));
}
}
我的问题是我已经通过我的DAO界面访问数据库。例如:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(securityDataSource);
}
“我的用户”表的电子邮件和密码列将用作用户名/密码。
是否可以通过某种方式使用此方法进行身份验证?我可以提供其他信息,但不愿意发布所有内容,希望有人会为我编写。
答案 0 :(得分:1)
假设数据库表名是用户和授权者。 datasource是在application.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());
}
}
答案 1 :(得分:1)
由于您已经创建了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;
}
}