How do I make spring security to invoke the requested resource after successful authentication?

The title may be a little misleading and may give you the impression that it is not easy, so I will go into detail.

I have a set of endpoints (REST services) that I want to secure without using the normal login method that Spring security provides. Typically, you first target the entry endpoint (j_pring_security_check by default), authenticate, and then send the request to the service endpoint along with the JSESSIONID.

In this case, I want to work without redirection.

From the client side, I want to send the header with the API key and HMAC directly to the service endpoint, and then on the server authenticate the requestor with these parameters, and then continue processing the request. I don't want to use sessions (similar to what BasicAuthenticationFilter does).

To summarize, I want to be able to authenticate and handle the request in one shot.

So, I created my own filter:

public class HMACFilter extends BasicAuthenticationFilter {
private static final Logger LOGGER = Logger.getLogger(HMACFilter.class);

public static final String HMAC_SECURITY_HEADER_APIKEY_FIELD = "VU-API-Key";
public static final String HMAC_SECURITY_HEADER_HMAC_FIELD = "VU-HMAC";
public static final String HMAC_SECURITY_HEADER_TIMESTAMP_FIELD = "VU-Timestamp";
public static final String HMAC_SECURITY_URL_AFFILIATEID_FIELD = "affiliateid";

public HMACFilter() {
    //super("/api_security");
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest)req;
    HttpServletResponse response = (HttpServletResponse)res;

    String headerApiKey = obtainApiKey(request);
    String headerHmac = obtainHMACSignature(request);
    String headerTimestamp = obtainRequestDate(request);
    int requestAffiliateId = obtainAffiliateId(request);
    String requestMessage = obtainMessage(request);

    VUHMACCredentials credentials = new VUHMACCredentials();

    if (headerHmac == null || headerApiKey == null || headerTimestamp == null) {
        throw new AuthenticationServiceException("Authentication Headers cannot be null");
    }

    credentials.setApiKey(headerApiKey);
    credentials.setHMACSignature(headerHmac);
    credentials.setTimestamp(Long.valueOf(headerTimestamp));


        VUCustomHMACAuthenticationToken authRequest = new VUCustomHMACAuthenticationToken(requestAffiliateId, credentials, requestMessage);
        try{
            Authentication authResult =  this.getAuthenticationManager().authenticate(authRequest);
        SecurityContextHolder.getContext().setAuthentication(authResult);

        } catch (AuthenticationException var12) {
            SecurityContextHolder.clearContext();
            this.onUnsuccessfulAuthentication(request, response, var12);

            return;
        }
        chain.doFilter(request, response);

}

      

And security.xml:

    <security:http entry-point-ref="apiAuthenticationEntryPoint" pattern="/rest/api/**">
        <security:intercept-url pattern="/rest/api/**"
            access="ROLE_APIUSER" />
        <security:custom-filter position="FIRST"
            ref="hmacFilter" />

    </security:http>

    <bean id="hmacFilter" class="com.vu.acs.edge.external.api.security.HMACFilter"
          p:authenticationEntryPoint-ref="apiAuthenticationEntryPoint"
          p:authenticationManager-ref="hmacAuthenticationManager"/>

      

    <bean id="hmacAuthenticationManager" class="com.vu.acs.edge.external.spring.security.VUCustomHMACAuthenticationManager"
            />

      

This xmls overrides the j_spring_security_check url and authenticates on every url that matches the pattern / rest / api / **

The problem is that Spring security exits and returns 200 RC, but does not call the stop service. So how can I get the framework to call the rest of the services after authentication? I need something that SavedRequestAwareAuthenticationSuccessHandler does, but without using a redirect, everything should be done with just one request from the client.

+3


source to share


1 answer


The JSESSIONID changes to the logout time and a strange problem can occur, such a known session fixation problem! I think instead of using JSESSIONID for your cookie case it is better to choose, you can open the cors filter authorization and send through the .store header cookie the data of such user id (encrypted) and check in the body of the method, but don't let the user pass! to use cookie you can use:

  <session-config>
        <session-timeout>10</session-timeout>       
        <tracking-mode>COOKIE</tracking-mode>
 </session-config>

      



starting with tomcat 7 servlet 3.

0


source







All Articles