执行自定义过滤器 UsernamePasswordAuthenticationFilter 后如何以编程方式返回 json 响应?
Posted
技术标签:
【中文标题】执行自定义过滤器 UsernamePasswordAuthenticationFilter 后如何以编程方式返回 json 响应?【英文标题】:How to programatically return a json response after executing a custom filter UsernamePasswordAuthenticationFilter? 【发布时间】:2012-10-04 13:33:04 【问题描述】:我正在创建一个自定义过滤器 UsernamePasswordAuthenticationFilter 来处理身份验证过程。基本上,当用户通过 REST /login 执行登录 http post 时,自定义过滤器将执行并应响应包含用户详细信息和生成令牌的 json 格式。
我的问题是我在哪里设置以响应客户端的 json 响应? 我正在考虑创建 SavedRequestAwareAuthenticationSuccessHandler 的子类并在那里设置 json 响应。这是个好主意吗?
任何帮助将不胜感激 =)
谢谢
【问题讨论】:
是否有理由实现自定义过滤器,而不是仅使用 spring 安全配置转发到生成所需 json 的 servlet? @mael:原因是要覆盖默认的 j_username/j_password 登录参数名称。所以我把它改成了用户名/密码。 无需为此实现自己的过滤器:The default parameter names to use are contained in the static fields SPRING_SECURITY_FORM_USERNAME_KEY and SPRING_SECURITY_FORM_PASSWORD_KEY. The parameter names can also be changed by setting the usernameParameter and passwordParameter properties. 感谢@Xaerxess,但这不是我最初的问题。问题出在我发布的那个=) @mael - 一个原因是 Ext-JS 在表单提交后期望返回 JSON,并且转发给它一个 html 文档。 【参考方案1】:您需要实现自己的 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:默认情况下,用户名密码过滤器将在成功登录后重定向,在这种情况下您可能不希望这样做。另请注意,在上述实现中,过滤器链在身份验证成功时终止 - 您必须确保您的过滤器呈现正确的响应,不要依赖底层 servlet 为您完成。
或者,您可以保留重定向并将客户端发送到另一个 URL,该 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>
【讨论】:
正文应该是response.getWriter().write(...)
吗?以上是关于执行自定义过滤器 UsernamePasswordAuthenticationFilter 后如何以编程方式返回 json 响应?的主要内容,如果未能解决你的问题,请参考以下文章