我很新Spring Security我有以下問題。 。如何從Spring MVC Boot Controller方法正確檢索記錄的用戶信息?
我正在使用春季安全,以保護所有的資源投入到/外網/」一春引導 prject
所以基本上我WebSecurityConfig配置類包含此代碼:
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = CustomUserDetailsService.class)
@EnableAutoConfiguration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/Extranet/**").access("hasRole('ROLE_USER')")
.anyRequest().permitAll()
.and()
.httpBasic()
.and()
.csrf().disable();
}
}
它工作正常,事實上訪問資源爲/Extranet/login我必須設置基本身份驗證並指定正確的用戶名和密碼(使用郵遞員工具來執行請求來測試它)。
好吧,這工作正常。
在我的春季安全配置involed這個CustomUserDetails類,它實現了Spring Security的接口的UserDetails。
public class CustomUserDetails extends User implements UserDetails {
private static final long serialVersionUID = 1L;
public CustomUserDetails(User user){
super(user);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for(UserRole role : this.getUserRoles()){
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getName());
authorities.add(grantedAuthority);
}
return authorities;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public String getUsername() {
return super.getUsername();
}
}
此對象的實例包含當前登錄的用戶的用戶詳細信息。
好吧,我的疑問是:我如何從控制器方法檢索這個對象? (我認爲這應該是在上下文中,我可以以某種方式檢索它)。
我已經tryied這樣做:
@RestController
@RequestMapping("/Extranet")
public class AccessController {
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<String> login(CustomUserDetails userInfo) {
System.out.println("login() START");
return ResponseEntity.ok("LOGGED IN");
}
}
但這種方式我得到這樣一個例外:
[ERROR] 2017-01-23 14:18:04 [com.betrivius.controller.exceptionHandler.ControllerExceptionHandler.handleException(ControllerExceptionHandler.java:106)] [http-nio-8080-exec-1] ControllerExceptionHandler - Request: http://localhost:8080/Extranet/login throws:
org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.betrivius.security.bean.CustomUserDetails]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.betrivius.security.bean.CustomUserDetails.<init>()
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:105) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
看來,它不能instantialete的CustomUserDetails目的。爲什麼?
從我所知我可以檢索CustomUserDetails與記錄的用戶相關的對象。我該怎麼做?
我也試着這樣做:
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<String> login(Principal principal) {
System.out.println("login() START");
return ResponseEntity.ok("LOGGED IN");
}
這樣的本金參數是否正確實例化,包含以前CustomUserDetails包含登錄用戶的信息對象的實例。
那麼,它是訪問當前記錄的用戶信息的正確方法嗎?
另一個疑問是:爲什麼我可以在此主要本金參數傳遞給我的登錄()方法?究竟發生了什麼?誰有效地將它傳遞給登錄()方法?
我認爲應該發生這樣的事情:
1)有一個POST的HttpRequest朝着「/外網/登錄」資源。調度程序servlet將其發送給登錄()方法。
2)校長在用戶啓用此資源之前(在調用控制器方法之前)被放入Spring Context中,因此Spring工廠可以從上下文中檢索它並將其傳遞給login()方法。
但我絕對不確定它。如何工作?我錯過了什麼?