将用户添加到会话,弹出安全性默认登录

时间:2011-10-18 10:52:07

标签: java spring spring-mvc spring-security

我已设置spring security以正确拦截并使用自定义登录页面提示用户,然后正确进行身份验证并将用户详细信息添加到SecurityContextHolder。

补充一点,我现在想要在执行登录时添加我自己的自定义User对象添加到会话中;所以代码看起来像这样:

public returnwhat? doMySupplementaryLogin() {

   UserDetails principal = (UserDetails) SecurityContextHolder.getContext()
                                .getAuthentication().getPrincipal();
   MyUser user = myUserService.getMyUser(principal.getUsername());

   add user to what ?
}

此代码将在何处发布?我希望执行nomral spring身份验证,然后上面的代码将MyUser对象放入会话,然后将用户发送到原始拦截的url / viewname。我有强烈的感觉,我使事情变得比他们需要的更复杂......

2 个答案:

答案 0 :(得分:10)

你确实让它变得复杂......:)

您想要的是为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类。

答案 1 :(得分:1)

或添加您自己的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");

请注意,扩展的SavedRequestAwareAuthenticationSuccessHandler存储原始URL,并在成功登录后将其恢复。