在我的应用程序中,我有一个Account
类,它也实现了UserDetails
。我还创建了扩展SimpleUrlAuthenticationSuccessHandler
的类MyAuthenticaionSuccessHandler
。我想要的是在用户登录后更改Account
上的字段dateLastLogin
。在方法onAuthenticationSuccess
中,我想要方法save(Account account)
所在的AccountService
的实例,将更新后的Account
保存到数据库中。问题从这里开始。我不能进行字段注入,因为我必须在构造函数中初始化AccountService
的实例。我不能这么做,因为那样我就无法创建MyAuthenticaionSuccessHandler
的实例。我也无法手动创建它。其他类的实例,如服务或控制器,其中其他服务/存储库类的实例是自动创建的,因此它在那里工作。但是如何使其适用于自定义身份验证成功处理程序呢
以下是我的代码片段:
扩展WebSecurityConfigureAdapter 的类
// ...
.formLogin()
.loginPage("/guest/login")
.permitAll()
.failureHandler(new MyAuthenticationFailureHandler("/guest/login"))
.successHandler(new MyAuthenticationSuccessHandler("/user/overview"))
.and()
.logout()
// ...
会计服务
@Service
@Transactional
public class AccountService implements UserDetailsService {
private final AccountRepository accountRepository;
private final ActivationCodeService activationCodeService;
public AccountService(AccountRepository accountRepository, ActivationCodeService activationCodeService) {
this.accountRepository = accountRepository;
this.activationCodeService = activationCodeService;
}
public void saveAccount(Account account){
accountRepository.save(account);
}
// ...
以及我自己的身份验证成功处理程序
public class MyAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private final AccountService accountService; // <-- here it doesn't work
public MyAuthenticationSuccessHandler() {
}
public MyAuthenticationSuccessHandler(String defaultTargetUrl) {
super(defaultTargetUrl);
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
super.onAuthenticationSuccess(request, response, authentication);
Account account = (Account)authentication.getPrincipal();
account.setDateLastLogin(new Date());
accountService.saveAccount(account);
}
}
您不应该使用new
直接在spring应用程序中创建对象。您可以使用@Bean
注释创建一个bean,并使用@Autowired
注释自动连接它。
@Configuration
public class AppConfiguration() {
@Bean
public MyAuthenticationSuccessHandler myAuthenticationSuccessHandler (){
return new MyAuthenticationSuccessHandler("/user/overview");
}
}
---
@Autowired
private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
在查看您的代码时,我看不出您为什么不能将AccountService
注入MyAuthenticationSuccessHandler
。如果你发布的代码正是你的代码,那么问题就出在上
.successHandler(new MyAuthenticationSuccessHandler("/user/overview"))
因为通过在这里使用new
,您已经将Spring完全排除在等式之外,并且没有对MyAuthenticationFailureHandler
进行任何注入。
在WebSecurityConfigureAdapter
中,尝试添加成员变量
@Autowired
private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
然后,在你的链中,像这样添加
.successHandler(myAuthenticationSuccessHandler)
如果您在这个bean构造函数(url(中绝对必须有参数,那么您将需要创建一个BeanFactory,该BeanFactory生成包含您的url的类型为MyAuthenticationSuccessHandler
的Spring bean。