我已经设置了spring security来正确拦截并提示用户使用自定义登录页面,然后正确验证并将userdetails添加到SecurityContextHolder
补充,我现在想添加我自己的自定义用户对象添加到会话每当登录执行;所以代码看起来像这样:
public returnwhat? doMySupplementaryLogin() {
UserDetails principal = (UserDetails) SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
MyUser user = myUserService.getMyUser(principal.getUsername());
add user to what ?
}
这段代码放到哪里?我希望执行正常的spring身份验证,然后上面的代码将把MyUser对象放入会话中,然后将用户发送到原始截获的url/viewname。我有一种强烈的感觉,我把事情弄得太复杂了。
你把事情弄复杂了…:)
您需要的是向spring的普通身份验证管理器添加一个自定义身份验证提供程序。您可以这样配置身份验证管理器:
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="authServiceImpl">
<security:password-encoder ref="passwordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"/>
现在只需要在spring上下文中定义authServiceImpl bean。您可以通过xml或注释(我喜欢的方式)来实现这一点。
@Service
public class AuthServiceImpl implements AuthService {
需要实现AuthService接口。只要从接口实现到方法-应该是相当直接的。你不需要自己把东西放到SecurityContextHolder中——spring会做的。
你想要的是:
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
return MyUser user = myUserService.getMyUser(username);
}
如果还有其他问题,请尽管问。
编辑:或者你可以让你的UserService类实现这个接口——我这样做是因为你没有提供你的UserService类。
或者添加自己的AuthenticationSuccessHandler,例如这个类,我添加了这样我就可以在会话中存储用户名和密码,这样我就可以在需要时登录到其他微服务:
public class AuthenticationSuccessWithSessionHandler extends SavedRequestAwareAuthenticationSuccessHandler implements AuthenticationSuccessHandler, LogoutSuccessHandler {
public static final String USERNAME = "username";
public static final String PASSWORD = "password";
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
request.getSession().removeAttribute(USERNAME);
request.getSession().removeAttribute(PASSWORD);
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
super.onAuthenticationSuccess(request, response, authentication);
request.getSession().setAttribute(PASSWORD, request.getParameter(PASSWORD));
request.getSession().setAttribute(USERNAME, request.getParameter(USERNAME));
}
}
并注册
AuthenticationSuccessWithSessionHandler successHandler = new AuthenticationSuccessWithSessionHandler();
http.authorizeRequests().antMatchers("/login", "/logout", "/images", "/js").permitAll().antMatchers("/feeds/**")
.authenticated().and().formLogin()
.successHandler(successHandler)
.and().logout().logoutUrl("/logout").logoutSuccessHandler(successHandler).logoutSuccessUrl("/login");
注意extends SavedRequestAwareAuthenticationSuccessHandler存储原始url,并在成功登录后恢复它。