成功通过身份验证后,如何使Spring安全性来调用请求的资源? [英] How to make spring security to call the requested resource after a successful authentication?

查看:53
本文介绍了成功通过身份验证后,如何使Spring安全性来调用请求的资源?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标题可能有点误导,可能会给您一种容易理解的印象,因此我将对其进行详细说明.

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

我有一组要保护的端点(REST服务),而没有使用Spring安全性提供的常规登录方式.通常,您首先会瞄准登录端点(默认情况下为j_pring_security_check),进行身份验证,然后将请求与JSESSIONID一起发送至服务端点.

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.

我想从客户端将带有API密钥和HMAC的标头直接发送到服务端点,然后在服务器上根据这些参数对请求者进行身份验证,然后继续处理请求.我不想使用会话(类似于BasicAuthenticationFilter所做的事情.)

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);

}

还有security.xml:

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"
            />

此xmls覆盖j_spring_security_check URL,并在每个与/rest/api/**模式匹配的URL上进行身份验证

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

这里的问题是,Spring安全性正在认证并返回200 RC,但没有调用其余服务.那么,如何使框架在身份验证后调用其余服务?我需要某种SavedRequestAwareAuthenticationSuccessHandler所做的事情,但不使用重定向,所有操作都应仅使用来自客户端的一个请求来完成.

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.

推荐答案

JSESSIONID超时更改,可能会发生奇怪的问题,例如众所周知的会话固定问题!我认为不是使用JSESSIONID,对于您而言,使用cookie是更好的选择,您可以打开cors过滤器身份验证并通过标头cookie发送.存储数据(例如特定的用户ID)(加密)并在方法主体中进行验证,但不能通过用户通过!要使用Cookie,您可以使用:

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>

从tomcat 7 Servlet 3开始.

strating from tomcat 7 servlet 3.

这篇关于成功通过身份验证后,如何使Spring安全性来调用请求的资源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆