Oauth 2.0 具有隐式客户端和csrf保护的OAuth2

Oauth 2.0 具有隐式客户端和csrf保护的OAuth2,oauth-2.0,spring-security-oauth2,Oauth 2.0,Spring Security Oauth2,我有一个我想用OAuth2保护的API。我已经用passwordgrant_类型做了一个虚拟测试,一切正常。我可以请求令牌,使用令牌访问安全端点,等等。服务器充当授权和资源服务器 后来我读到,我应该使用隐式的grant_类型,因为客户端将是一个javascript应用程序 我的客户端的配置如下: @Override public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {// @f

我有一个我想用OAuth2保护的API。我已经用passwordgrant_类型做了一个虚拟测试,一切正常。我可以请求令牌,使用令牌访问安全端点,等等。服务器充当授权和资源服务器

后来我读到,我应该使用隐式的grant_类型,因为客户端将是一个javascript应用程序

我的客户端的配置如下:

@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {// @formatter:off
clients
    .inMemory().withClient("web")
    .redirectUris("http://localhost:3000")
    .secret("secret")
    .authorizedGrantTypes("implicit", "refresh_token").scopes("read", "write")
    .accessTokenValiditySeconds(3600).refreshTokenValiditySeconds(2592000);
}
如果我尝试像这样访问端点:

我明白了:

{
  "timestamp": 1464136960414,
  "status": 403,
  "error": "Forbidden",
  "message": "Expected CSRF token not found. Has your session expired?",
  "path": "/oauth/authorize"
}
{
  "timestamp": 1464136840865,
  "status": 403,
  "error": "Forbidden",
  "exception": "org.springframework.security.authentication.InsufficientAuthenticationException",
  "message": "Access Denied",
  "path": "/oauth/authorize"
}
如果这是我第一次调用API,如何拥有CSRF令牌? 如果(仅用于测试)我禁用了csrf,则我得到以下结果:

{
  "timestamp": 1464136960414,
  "status": 403,
  "error": "Forbidden",
  "message": "Expected CSRF token not found. Has your session expired?",
  "path": "/oauth/authorize"
}
{
  "timestamp": 1464136840865,
  "status": 403,
  "error": "Forbidden",
  "exception": "org.springframework.security.authentication.InsufficientAuthenticationException",
  "message": "Access Denied",
  "path": "/oauth/authorize"
}
将客户端设置为密码授予类型我可以拨打此电话,一切正常: 以及添加具有客户端id/secret的授权基本头

只是想澄清一下,我们的想法是拥有这个独特的可信任客户机。因此,用户只需输入登录名/密码,而无需请求用户授予应用程序的访问权限

对不起,如果这是一个愚蠢的问题。我一直在阅读我能找到的所有东西,但似乎没有取得进展

谢谢

编辑:

我的Spring安全配置:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private MongoDBAuthenticationProvider authenticationProvider;

  @Autowired
  public void globalUserDetails(final AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(authenticationProvider);
  }

  @Override
  @Bean
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }
}
我的OAuth配置:

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends     AuthorizationServerConfigurerAdapter {

  @Autowired
  @Qualifier("authenticationManagerBean")
  private AuthenticationManager authenticationManager;

  @Override
  public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
  }

  @Override
  public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
    clients
    .inMemory().withClient("web")
    .redirectUris("http://localhost:3000")
    .secret("secret")
    .authorizedGrantTypes("implicit", "refresh_token").scopes("read", "write")
    .accessTokenValiditySeconds(3600).refreshTokenValiditySeconds(2592000);
  }

  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints)     throws Exception {
    endpoints.authenticationManager(authenticationManager);
  }  
}
服务器中的异常:

2016-05-25 19:52:20.744 DEBUG 34968 --- [nio-8080-exec-5] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /oauth/authorize
2016-05-25 19:52:20.744 DEBUG 34968 --- [nio-8080-exec-5] .s.o.p.e.FrameworkEndpointHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)]
2016-05-25 19:52:20.746 DEBUG 34968 --- [nio-8080-exec-5] o.s.s.w.a.ExceptionTranslationFilter     : Authentication exception occurred; redirecting to authentication entry point

org.springframework.security.authentication.InsufficientAuthenticationException: User must be authenticated with Spring Security before authorization can be completed.
at     org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(AuthorizationEndpoint.java:138) ~[spring-security-oauth2-2.0.9.RELEASE.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40]
....
2016-05-25 19:52:20.744调试34968---[nio-8080-exec-5].s.o.p.e.FrameworkEndpointHandlerMapping:查找路径/oauth/authorize的处理程序方法
2016-05-25 19:52:20.744调试34968---[nio-8080-exec-5].s.o.p.e.FrameworkEndpointHandlerMapping:返回处理程序方法[public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map、java.util.Map、org.springframework.web.bind.support.SessionStatus、java.security.Principal)]
2016-05-25 19:52:20.746调试34968---[nio-8080-exec-5]o.s.s.w.a.ExceptionTranslationFilter:发生身份验证异常;重定向到身份验证入口点
org.springframework.security.authentication.InsufficientAuthenticationException:必须使用Spring security对用户进行身份验证,才能完成授权。
在org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorization(AuthorizationEndpoint.java:138)~[spring-security-oauth2-2.0.9.RELEASE.jar:na]
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)~[na:1.8.0\u 40]
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)~[na:1.8.0\u 40]
....

当您为隐式授权类型调用授权服务器时,必须包含不透明字符串值作为状态参数,以避免csrf攻击。因此,到授权服务器的请求url如下所示:

您在状态参数中提到的值将在响应中回显给您。然后您将回显值与初始值进行比较,以确认没有发生csrf攻击

谢谢,,
Soma.

谢谢你的回答@Soma。我听说过“国家”param,但仍然没有处理与我的案例相关的问题。我修改了它,但仍然有错误。我发布它作为POST,我收到csrf错误,get拒绝访问。我将用更多代码更新我的问题,看看你是否能发现任何错误。非常感谢!请求应该是get。只是为了确认,你注册了吗客户端?请使用GET发布详细的错误消息。谢谢我编辑了答案。非常感谢您的帮助和时间。当您访问授权端点时,是否显示了登录屏幕?如果是,您必须提供用户名和密码以进行身份验证,然后才能使用t重定向到提供的重定向uri这是怎么回事?如果不是,请解释一下流程。谢谢。