How to make spring security to call the requested resource after a successful authentication?

混江龙づ霸主 提交于 2021-02-19 03:46:52

问题


The title might be a bit misleading and might give you the impression this is an easy one so I will elaborate.

I have a set of endpoints (REST services) that I want to secure without using the regular login way that Spring security provides. Usually you would first aim to the login 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 redirections.

From the client-side I want to send a Header with an API-Key and an HMAC directly to the service endpoint, and then on the server authenticate the requester against these parameters and then proceed to process the request. I dont want to use sessions (similar to what the BasicAuthenticationFilter does).

To summarize, i want to be able to authenticate and process 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 the 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 issue here is that spring security is authenticating and returning a 200 RC but not calling the rest service. So, how can i make the framework to call the rest services after authentication? I need kinda what the SavedRequestAwareAuthenticationSuccessHandler does but without using redirections, everything should be done with just one request from the client.


回答1:


JSESSIONID changing at time outs and may occure strange problem such well known session fixation issues! I think instead of using JSESSIONID ,for your case using cookie is better choice ,you can open cors filter authantication and send via header cookie .store data such specific user id (encrypted) and validate in method body but not user pass !. for use cookie you can use :

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

strating from tomcat 7 servlet 3.



来源:https://stackoverflow.com/questions/31842162/how-to-make-spring-security-to-call-the-requested-resource-after-a-successful-au

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!