如何在执行自定义过滤器UsernamePasswordAuthenticationFilter后以编程方式返回json响应?

时间:2012-10-14 09:43:00

标签: json spring security filter spring-security

我正在创建自定义过滤器UsernamePasswordAuthenticationFilter来处理身份验证过程。基本上,当用户通过REST /登录执行登录http post时,自定义过滤器将执行,并应响应包含用户详细信息和生成的令牌的json格式。

我的问题是我在哪里设置响应客户端的json响应? 我正在考虑创建SavedRequestAwareAuthenticationSuccessHandler的子类并在那里设置json响应。这是个好主意吗?

任何帮助将不胜感激=)

由于

1 个答案:

答案 0 :(得分:6)

您需要实现自己的SuccessHandler并将其注入UsernamePasswordAuthenticationFilter:

public class MyAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

   public MyAuthenticationSuccessHandler() {
       super();
       setRedirectStrategy(new NoRedirectStrategy());
   }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {

           super.onAuthenticationSuccess(request, response, authentication);
           response.write("my JSON response");
    }


    protected class NoRedirectStrategy implements RedirectStrategy {

        @Override
        public void sendRedirect(HttpServletRequest request,
                HttpServletResponse response, String url) throws IOException {
            // no redirect

        }

    }

}

注意NoRedirectStrategy:默认情况下,UsernamePassword过滤器将在成功登录后重定向,在这种情况下您可能不想要。另请注意,在上面的实现中,过滤器链在身份验证成功时终止 - 您必须确保过滤器呈现正确的响应,不要依赖底层servlet为您执行此操作。

或者,您可以将重定向保留在原位,然后将客户端发送到另一个URL,从而呈现您正在寻找的JSON响应。

示例安全上下文:

    <!--  Security -->
    <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
        <sec:filter-chain-map path-type="ant">
            <sec:filter-chain pattern="/rest/login" filters="wsFilter"/>
        </sec>
    </bean>

    <bean id="wsFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
      <property name="authenticationManager" ref="myAuthenticationManager"/>
      <property name="authenticationSuccessHandler" ref="myAuthSuccessHandler"/>
      <property name="passwordParameter" value="pass"></property>
      <property name="usernameParameter" value="user"></property>
      <property name="postOnly" value="false"></property>
   </bean>

       <bean id="myAuthSuccessHandler" class="com.my.MyAuthenticationSuccessHandler"/>

    <sec:authentication-manager id="myAuthenticationManager" >
        <sec:authentication-provider user-service-ref="UserDetailsImpl">
            <sec:password-encoder hash="md5">
            </sec:password-encoder>
        </sec:authentication-provider>
    </sec:authentication-manager>