gpt4 book ai didi

java - 如何让Spring Security在身份验证成功后调用所请求的资源?

转载 作者:行者123 更新时间:2023-12-02 03:54:11 26 4
gpt4 key购买 nike

标题可能有点误导,可能会给您留下这是一个简单的印象,所以我会详细说明。

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

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

从客户端,我想将带有 API key 和 HMAC 的 header 直接发送到服务端点,然后在服务器上根据这些参数对请求者进行身份验证,然后继续处理请求。我不想使用 session (类似于 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"
/>

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

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

最佳答案

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

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

从 tomcat 7 servlet 3 出发。

关于java - 如何让Spring Security在身份验证成功后调用所请求的资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31842162/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com