【发布时间】:2016-03-14 22:53:19
【问题描述】:
我正在研究一个使用 spring-webmvc 4.07 版和 Spring Security v 3.2 的简单 Spring Boot 项目。基本安全配置被以下配置类覆盖,以提供安全 URL 和自定义 UserDetails 实现:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ReaderRepository readerRepository;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").access("hasRole('READER')")
.antMatchers("/**").permitAll()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true");
}
@Override
protected void configure(
AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
UserDetails userDetails = readerRepository.findOne(username);
if (userDetails != null) {
return userDetails;
}
throw new UsernameNotFoundException("User '" + username + "' not found.");
}
});
}
}
上面的readerRepository.findOne(username)是基于接口的
public interface ReaderRepository extends JpaRepository<Reader, String> {
List<Book> findByReader(String reader);
}
所以它正在使用登录页面上提供的用户名在数据库中寻找一个阅读器。 Reader 类是
@Entity
public class Reader implements UserDetails {
private static final long serialVersionUID = 1L;
@Id
private String username;
private String fullname;
private String password;
...Setters/Getters, getAuthorities(), isAccountNonExpired(), isAccountNonLocked(), isCredentialsNonExpired(), isEnabled()
}
只有一个控制器,
@Controller
@RequestMapping("/")
@ConfigurationProperties("amazon")
public class ReadingListController {
private ReadingListRepository readingListRepository;
private AmazonProperties amazonConfig;
@Autowired
public ReadingListController(ReadingListRepository readingListRepository,
AmazonProperties amazonConfig) {
this.readingListRepository = readingListRepository;
this.amazonConfig = amazonConfig;
}
@RequestMapping(method=RequestMethod.GET)
public String readersBooks(Reader reader, Model model) {
List<Book> readingList = readingListRepository.findByReader(reader);
if (readingList != null) {
model.addAttribute("books", readingList);
model.addAttribute("reader", reader);
model.addAttribute("amazonID", amazonConfig.getAssociateId());
}
return "readingList";
}
@RequestMapping(method=RequestMethod.POST)
public String addToReadingList(Reader reader, Book book) {
book.setReader(reader);
readingListRepository.save(book);
return "redirect:/";
}
}
我使用命令“gradle bootrun”运行应用程序。当我转到 localhost:8080/ 时,我会看到一个登录页面。当我登录时,会调用控制器的 readerBooks(...) 方法。此方法有一个 Reader 对象作为参数,其中包含登录页面上输入其用户名的已登录阅读器。 Reader 类(它实现了 UserDetails)显然是由 Spring 传入的。但是,我从未见过它以这种方式完成。我已经看到它是通过传入一个带有@AuthenticationPrincipal 注释的 Principal 或通过从控制器方法中访问 SecurityContext 来完成的,但是我找不到任何记录为什么在这种情况下传入 Reader 的任何内容。仅仅是因为 Reader实现 UserDetails?
【问题讨论】:
标签: spring security model-view-controller controller