【问题标题】:Spring Security, Rest Authentication and CSRFSpring Security、Rest 身份验证和 CSRF
【发布时间】:2014-03-18 07:03:49
【问题描述】:

我想对我的应用程序使用身份验证。 我有一个 Spring MVC 应用程序并应用了 Spring Security。针对浏览器,它工作正常。 这意味着,我对我的应用程序的用户进行身份验证并使用网页。

现在,我想使用休息。我在我的不安全控制器方法上添加了@ResponseBody,我收到了 json 响应。 但是如何使用 RestTemplate 使用用户名和密码连接到我的应用程序?

我在 RestClient 中的代码是(用于测试):

public void unsecureProfileTest() {

    String url = articleServiceUrl + "unsecure/profile/test.json";
    url = articleServiceUrl + "secure/profile/wiew.json";
    HttpEntity<Object> entity = new HttpEntity<Object>(getHeaders("user:userpassword"));
    Object s = restTemplate.exchange(url, HttpMethod.GET, entity, Object.class);

}

static HttpHeaders getHeaders(String auth) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON,
            MediaType.TEXT_HTML));

    byte[] encodedAuthorisation = Base64.encode(auth.getBytes());
    headers.add("Authorization", "Basic "
            + new String(encodedAuthorisation));

    return headers;
}

我的安全配置:

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.csrf().disable();

    http.authorizeRequests().antMatchers("/*").permitAll().and()
            .formLogin().successHandler(successHandler)
            .defaultSuccessUrl("/").failureHandler(failureHandler)
            .failureUrl("/login?error=true").permitAll().and().logout()
            .permitAll();

    http.authorizeRequests().antMatchers("/resources/**").permitAll();
    http.authorizeRequests().antMatchers("/welcome").permitAll();
    http.authorizeRequests().antMatchers("/unsecure/**").permitAll();

    http.authorizeRequests().antMatchers("/secure/*").authenticated();
    http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated();
}

结果是:访问被拒绝。 我猜问题来自于来自 restTemplate 的身份验证,但我该如何进行身份验证?

我的第二个问题是关于 csrf 谁被禁用但我想启用它(我的表单使用它)

我正在使用 Spring 4.0 和 Spring Security 3.2

编辑 我用

更新了我的代码
String url = articleServiceUrl + "unsecure/profile/test.json";
url = articleServiceUrl + "secure/profile/wiew.json";
HttpEntity<Object> entity = new HttpEntity<Object>(getHeaders("{user:userpassword, password:userpassword}"));
Object s = restTemplate.exchange(url, HttpMethod.GET, entity, Object.class);

我收到一个代码302

编辑 18022014 - 16:46 我更新到

String url = articleServiceUrl + "login?username=user&password=userpassword";
HttpEntity entity restTemplate;exchange(url, HTTPMethod.POST,null, HttpEntity.class)
system.out.println(entity);

在 Web 服务器的日志中,我收到了一条成功消息(请参阅“用户”上的用户详细信息)。

现在,我想使用身份验证来访问其他 url ("secure/profile/view.json")

如何保持身份验证?

谢谢

【问题讨论】:

  • 当您没有交互式登录(并且可能没有会话)时,基于表单的身份验证不是一个好的选择。考虑改用基本身份验证之类的东西。
  • 我有一个交互式登录,因为我有一个网站来管理用户和管理员制作的很多东西
  • 是的,但大概这是您在这个问题中谈论的 ReST API 的另一个关注点?您最好的选择可能是为 ReST 部分定义一个单独的、无状态的过滤器链。表单登录配置不会处理基本身份验证标头。
  • 现在你想允许用户使用他们的名字和密码通过基本身份验证登录吗?如果是,您需要启用基本身份验证 spring 安全过滤器并将其配置为使用用户的 DAO
  • 不,我没有真正使用基本身份验证,但我扩展了 UserDetailsS​​ervice 以使用 DAO(使用 Spring Data JPA)。事实上,我可能不了解不同的身份验证类型。

标签: java spring rest spring-security


【解决方案1】:

我一直在玩 spring security 和 spring boot REST 应用程序,我创建了自己的 MapCsrfTokenRepository,我使用它来代替默认的 HttpSessionCsrfTokenRepository

然后你可以为你的rest URIs启用csrf

http.csrf().csrfTokenRepository(tokenRepository)

主要思想是当客户端使用 GET 访问 /login 资源时返回新的 CSRF_TOKEN,因为 GET 不需要 csrf 令牌。然后客户端必须在下次调用中使用此令牌。

示例在github

【讨论】:

  • 嗨,bsmk。那么,如果您将令牌存储到存储库中,那如何使它变得 Restful?
  • 它并不完全是 Restful。那只是权衡,我不确定这是否是正确的方法,但我还没有找到其他任何东西。
猜你喜欢
  • 2016-03-20
  • 2014-07-03
  • 2016-04-30
  • 2015-05-30
  • 2013-10-30
  • 2014-04-07
  • 2012-02-18
  • 2019-05-29
  • 2013-12-05
相关资源
最近更新 更多