Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programatically return a json response after executing a custom filter UsernamePasswordAuthenticationFilter?

I'm creating a custom filter UsernamePasswordAuthenticationFilter to handle the authentication process. Basically, when the User performs login http post through the REST /login, the custom filter will execute and should respond a json format containing user details and generated token.

My problem is where do i set to respond a json response to the client? I'm thinking of creating a subclass of SavedRequestAwareAuthenticationSuccessHandler and set there the json response. Is this a good idea?

Any help will be much appreciated =)

Thanks

like image 992
Warner Avatar asked Oct 14 '12 09:10

Warner


1 Answers

You need to implement your own SuccessHandler and inject it into 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

        }

    }

}

Note the NoRedirectStrategy: by default UsernamePassword filter will redirect after a successful logon which you probably dont want in this case. Also note that in the above implementation filter chain is terminated on authentication success - you have to make sure your filter renders the proper response, dont rely on underlying servlet to do it for you.

Alternatively you can leave the redirect in place and send client to another URL which in turn renders the JSON response you are looking for.

Sample security context:

    <!--  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>
like image 182
rootkit Avatar answered Nov 15 '22 04:11

rootkit