【问题标题】:How to make spring security to call the requested resource after a successful authentication?认证成功后如何让spring security调用请求的资源?
【发布时间】:2017-08-12 00:23:45
【问题描述】:

标题可能有点误导,可能会让你觉得这很简单,所以我会详细说明。

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

在这种情况下,我想在没有重定向的情况下工作。

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

总而言之,我希望能够一次性验证和处理请求。

所以我创建了自己的过滤器:

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:

    <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 上进行身份验证

这里的问题是 Spring Security 正在验证并返回 200 RC,但没有调用其余服务。那么,如何使框架在身份验证后调用其余服务?我需要 SavedRequestAwareAuthenticationSuccessHandler 的功能,但不使用重定向,一切都应该通过来自客户端的一个请求来完成。

【问题讨论】:

    标签: java rest spring-mvc authentication spring-security


    【解决方案1】:

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

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

    从 tomcat 7 servlet 3 开始。

    【讨论】:

    • 是的,我想到了使用 cors 过滤器,通常我会采用这种方法,但是因为我们有其他使用 Spring Security 保护的路径,我们希望在整个应用程序中保持统一的安全设计。无论如何谢谢你的建议!
    猜你喜欢
    • 2012-03-13
    • 2022-09-23
    • 1970-01-01
    • 2020-02-08
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 2019-06-03
    相关资源
    最近更新 更多