【问题标题】:RestTemplate not failing with 403 or 302 error when requesting secured pages请求安全页面时,RestTemplate 不会因 403 或 302 错误而失败
【发布时间】:2015-12-03 23:36:20
【问题描述】:

我有使用 spring-security 4.0.1 和 spring mvc 4.1.6 的网络应用程序。 它具有以下视图页面“/admin”和数据API“/admin/api/properties”的spring安全配置:

<http pattern="/admin.*" request-matcher="regex" auto-config="false">
    <intercept-url pattern="/admin" access="hasRole('ADMIN')"/>
    <intercept-url pattern="/admin/api/.+" access="hasRole('ADMIN')"/>
    <logout logout-url="/admin/logout" success-handler-ref="customLogoutSuccessHandler"/>
    <form-login login-page="/admin/login" login-processing-url="/admin/login"
                authentication-success-handler-ref="customSuccessHandler"
                authentication-failure-handler-ref="customFailureHandler"/>
    <csrf disabled="true" />
</http>

这工作正常。但现在我正在尝试通过具有不同凭据的 rest 模板向“/admin”和“/admin/api/properties”发送请求来测试安全性。

private HttpStatus fetchAccessStatusForPage(String username, String password, String requestUrl) {
    HttpHeaders headers = new HttpHeaders();
    String token = username + ":" + password;
    String authorizationValue = "Base " + new String(Base64.encode(token.getBytes()));
    headers.add("Authorization", authorizationValue);
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<Object> httpEntity = new HttpEntity<>(headers);
    HttpStatus resultCode;
    try {
        ResponseEntity<Object> responseEntity = restTemplate.exchange(requestUrl, HttpMethod.GET, httpEntity, Object.class);
        resultCode = responseEntity.getStatusCode();
    } catch (HttpClientErrorException e) {
        resultCode = e.getStatusCode();
    }
    return resultCode;

但它总是给我 200 OK 状态码,无论我提供什么凭据,无论我正在测试什么 api。 我还尝试了以下操作(没有任何凭据),由于某种原因,响应代码也是 200 OK。

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<Object> httpEntity = new HttpEntity<>(headers);      
    ResponseEntity<String> responseEntity = restTemplate.exchange(adminPageUrl, HttpMethod.GET, httpEntity, String.class);

我错过了什么吗?为什么休息模板不会因 403 错误或至少 302 与标题中的位置而失败?

也尝试了以下方法,结果是一样的

    URL u = new URL(getPageUrl(page));
    HttpURLConnection huc = (HttpURLConnection) u.openConnection();
    String token = username + ":" + password;
    String authorizationValue = "Base " + new String(Base64.encode(token.getBytes()));
    huc.setRequestProperty("Authorization", authorizationValue);
    huc.setRequestMethod("GET");
    huc.connect();
    return huc.getResponseCode()

【问题讨论】:

  • 你用这样的 RESTClient 测试过吗? github.com/wiztools/rest-client
  • 我使用了这个 chrome 扩展“Advanced Rest Client”,它显示了预期的结果 - 对于页面它有 302 和重定向 url,对于 api - 403。但我需要以编程方式发送休息请求,因为部分端到端测试
  • 好的,那么奇怪的是它在没有凭据的情况下使用 RestTemplate。
  • 我只是尝试在spring security中为api提供自动配置和,并且所有restTemplate requets都按预期工作......也许这与自定义安全配置有关?你怎么看?
  • HttpURLConnection 默认隐藏重定向。看到代码 200 时可能会进入登录页面?

标签: java spring-mvc spring-security resttemplate


【解决方案1】:

您可以通过以下方式创建 RestTemplate 来隐藏重定向:

    RestTemplate restTemplate = new RestTemplate(new SimpleClientHttpRequestFactory() {
        @Override
        protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException
        {
            super.prepareConnection(connection, httpMethod);
            connection.setInstanceFollowRedirects(false);
        }
    });

更新:为 API 提供一个单独的 HTTP 链通常是个好主意,例如:

<http pattern="/admin/api/.+" request-matcher="regex" create-session="stateless">
    <intercept-url pattern="/admin/api/.+" access="hasRole('ADMIN')"/>
    <http-basic/>
    <csrf disabled="true" />
</http>
<http pattern="/admin.*" request-matcher="regex">
    <intercept-url pattern="/admin" access="hasRole('ADMIN')"/>
    <logout logout-url="/admin/logout" success-handler-ref="customLogoutSuccessHandler"/>
    <form-login login-page="/admin/login" login-processing-url="/admin/login"
                authentication-success-handler-ref="customSuccessHandler"
                authentication-failure-handler-ref="customFailureHandler"/>
</http>

【讨论】:

  • 谢谢!现在我看到 api 和 page 都有 302 (找到状态)。但为什么会这样呢?我们正在发送用户名和密码..
  • @me1111 API 的单独链应该可以解决这个问题,请参阅更新。
  • 谢谢! 解决了这个问题。此外,将其添加到 amin 页面模式配置中也可以解决它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-06
  • 2014-09-08
  • 2012-08-09
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
相关资源
最近更新 更多