java - 休息模板错误 403

标签 java android rest csrf-protection

我正在尝试实现一个请求方法,但我不知道如何将 X-XSRF-TOKEN 发送到我的网络服务。

在Web服务中, token 配置为X-XSRF-TOKEN

<beans:bean id="csrfTokenRepository"
    class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository">
    <beans:property name="headerName" value="X-XSRF-TOKEN" />
</beans:bean>

我的 Android 应用程序中有它

public class WSConfig {
private static String urlBase = "http://192.168.25.226:8080/webapi/";
private static HttpHeaders httpHeaders;
private static RestTemplate restTemplate = new RestTemplate();
private static HttpEntity<String> httpEntity = new HttpEntity(getXSRF());
private static ResponseEntity<String> response;

public static HttpHeaders getXSRF() {
    try {
    HttpEntity<String> responseEntity = restTemplate.exchange(urlBase, HttpMethod.GET, null, String.class);
    CookieManager cookieManager = new CookieManager();
    List<String> cookieHeader = responseEntity.getHeaders().get("Set-Cookie");
    httpHeaders = new HttpHeaders();
    httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

    if (cookieHeader != null) {
        for (String cookie : cookieHeader) {
            String[] tokens = TextUtils.split(cookie, "=");
            if (tokens[0].equals("XSRF-TOKEN")) {
                String[] tokenValue = TextUtils.split(tokens[1],";");
                httpHeaders.add("X-XSRF-TOKEN", tokenValue[0]);
            }
            if (tokens[0].equals("JSESSIONID")) {
                String[] tokenValue = TextUtils.split(tokens[1],";");
                httpHeaders.add("Cookie", "JSSESSIONID="+tokenValue[0]);
            }
        }
    }
    } finally {
        return httpHeaders;
    }
}

public static HttpEntity<String> makeRequest(String uri, HttpMethod method) {
    try {
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
            protected boolean hasError(HttpStatus statusCode) {
                return false;
            }});

        System.out.println(httpEntity.getHeaders());
        response = restTemplate.exchange(urlBase + "registrar", HttpMethod.POST, null, String.class);
        System.out.println(response.getHeaders());
        System.out.println(response.getBody());
    } catch (HttpStatusCodeException e) {
        e.printStackTrace();
    }
    return null;
}
}

在我的 LogCat 中,我从 System.outs 获得了这些结果

System.out.println(httpEntity.getHeaders());
{Accept=[application/json], Cookie=[JSSESSIONID=D0D537D4C38D2D69B01BF4F98B540763], X-XSRF-TOKEN=[8c21c671-bba4-4624-ada1-ff1e9e8f2e22]}

System.out.println(response.getHeaders());
{Server=[Apache-Coyote/1.1], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-XSS-Protection=[1; mode=block], X-Frame-Options=[DENY], X-Content-Type-Options=[nosniff], Set-Cookie=[JSESSIONID=7DBA84F6218BC9A8328A97587FC6293A; Path=/webapi/; HttpOnly], Content-Type=[text/html;charset=utf-8], Content-Language=[en], Content-Length=[1073], Date=[Thu, 20 Aug 2015 00:53:46 GMT], X-Android-Sent-Millis=[1440032027763], X-Android-Received-Millis=[1440032027805], X-Android-Response-Source=[NETWORK 403]}

而且,错误

System.out.println(response.getBody());
HTTP Status 403 - Expected CSRF token not found. Has your session expired?

我不知道我必须做什么,我正确发送了 header ,但无法发布帖子。

已更新

我认为这个错误与 JSESSIONID 有关,而不是与 XSRF-TOKEN 有关,在我第一次 GET(获取 XSRF)之后, session 即将过期。

最佳答案

解决方案

正如我所说,这个错误与 JSESSIONID 有关。

当我分割 JSESSIONID cookie 时,它​​会丢失一些需要使 cookie 存活的东西(也许是路径?)

所以,不要像这样添加 cookie

httpHeaders.add("Cookie", "JSSESSIONID="+tokenValue[0]);

我是这样附加的

httpHeaders.add("Cookie", cookie);

在制作过程中,我确保所有内容都附加到新标题中。

final方法。

public static HttpHeaders getXSRF() {
    try {
    HttpEntity<String> responseEntity = restTemplate.exchange(urlBase, HttpMethod.GET, null, String.class);
    CookieManager cookieManager = new CookieManager();
    List<String> cookieHeader = responseEntity.getHeaders().get("Set-Cookie");
    httpHeaders = new HttpHeaders();
    httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

    if (cookieHeader != null) {
        for (String cookie : cookieHeader) {
            String[] tokens = TextUtils.split(cookie, "=");
            if (tokens[0].equals("XSRF-TOKEN")) {
                String[] tokenValue = TextUtils.split(tokens[1],";");
                httpHeaders.add("X-XSRF-TOKEN", tokenValue[0]);
            }
            if (tokens[0].equals("JSESSIONID"))
                httpHeaders.add("Cookie", cookie);
        }
    }
    } finally {
        return httpHeaders;
    }
}

关于java - 休息模板错误 403,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32107926/

相关文章:

java - 导出到 .JAR 时不会抓取资源

json - 如何通过 Swift 和 Rest API 之间的连接获取和发布 JSON?

android - 有什么特别的方法可以让系统卸载弹出窗口出现在android中的监听器

java - 如何从 Java 替换 cocos2d-x 场景?

java - 无法在 Worklight 6.2、6.3 中获取 HTTP 响应

python - 测试经过身份验证的 django-rest-framework 路由时出现 405 错误

java - Hibernate HQL 嵌套查询

java - 即使计算正确,方法仍返回 NaN

java - Web 脚本中的 Alfresco 节点锁定

android - 横向模式下的软键盘不会在 Android 模拟器中弹出