当前位置: 首页 > 知识库问答 >
问题:

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

洪英豪
2023-03-14

我有一个API,我想与OAuth2安全。我已经用密码做了一个虚拟测试grant_type一切正常。我可以请求令牌,用它访问安全的endpoint,等等。服务器充当授权和资源服务器。

后来我读到,我应该使用隐式的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);
}

如果我尝试像这样访问endpoint:http://localhost:8080/oauth/authorize?grant_type=implicit

我明白了:

{
  "timestamp": 1464136960414,
  "status": 403,
  "error": "Forbidden",
  "message": "Expected CSRF token not found. Has your session expired?",
  "path": "/oauth/authorize"
}

如果这是我第一次调用API,如何拥有CSRF令牌?如果(仅用于测试)我禁用了csrf,则我得到以下结果:

{
  "timestamp": 1464136840865,
  "status": 403,
  "error": "Forbidden",
  "exception": "org.springframework.security.authentication.InsufficientAuthenticationException",
  "message": "Access Denied",
  "path": "/oauth/authorize"
}

设置客户端的密码grant_type我能够打这个电话,一切正常:http://localhost:8080/oauth/token?grant_type=password

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

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

谢谢

编辑:

我的Spring Security配置:

@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]
....

共有1个答案

计承德
2023-03-14

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

http://localhost:8080/oauth/authorize?grant_type=implicit

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

谢谢你,索玛。

 类似资料:
  • 我正在使用Spring构建Web应用程序。我有多个Spring客户端应用程序和一个OAuth2授权和资源服务器。最终用户首先在客户端应用内进行身份验证,然后客户端应用从资源服务器请求一些资源(从授权服务器获得访问令牌后),处理数据并将其返回给用户。用户也可以更改资源服务器上的数据,但只能通过客户端应用。对于仅使用客户端凭证的资源获取,在这种情况下资源所有者是可信客户端。 在资源服务器上,仅存储客户

  • 有可能保护无状态REST API免受XSS和CSRF攻击吗? 目前,我使用存储在secure/httpOnly cookie中的JWT令牌进行无状态身份验证。这应该可以保护API免受最常见的XSS攻击:使用XSS注入的JavaScript窃取Cookie并将其发送给攻击者。 然而,这并不能保护API免受CSRF攻击,在这种攻击中,攻击者会欺骗经过身份验证的用户跟踪特定web API调用的链接,从而

  • CSRF是指针对Web应用程序的跨站点伪造攻击。 CSRF攻击是系统的经过身份验证的用户执行的未授权活动。 因此,许多Web应用程序容易受到这些攻击。 Laravel以下列方式提供CSRF保护 - Laravel包含一个内置的CSRF插件,可为每个活动用户会话生成令牌。 这些令牌验证相关的经过身份验证的用户是否发送了操作或请求。 实现 (Implementation) 本节将详细讨论Laravel

  • 简介 Laravel 可以轻松地保护应用程序免受 跨站点请求伪造 (CSRF) 攻击,跨站点请求伪造是一种恶意攻击,它凭借已通过身份验证的用户身份来运行未经过授权的命令。 Laravel 会自动为每个活跃用户的会话生成一个 CSRF「令牌」。该令牌用于验证经过身份验证的用户是否是向应用程序发出请求的用户。 无论何时,当您在应用程序中定义HTML表单时,都应该在表单中包含一个隐藏的CSRF标记字段,

  • 如果扩展程序损害了他们的隐私或要求提供需要的更多权限,则用户将不会安装该扩展程序。权限请求应对用户有意义,并且限于实现扩展所需的关键信息。 收集或传输任何用户数据的扩展必须遵守用户数据隐私策略。 通过包括以下预防措施来保护和尊重用户,以确保其身份安全。切记:扩展可以访问的数据越少,意外泄漏的数据就越少。 减少所需的权限 扩展可以访问的 API 在 manifest 的权限字段中指定。赋予的权限越多

  • 我目前添加了一个CSRF令牌保护机制到我的php应用程序。正如我所读到的,唯一的要求是一个独特的每个用户令牌,我在php7中使用random_bytes生成。 我担心的是,如果攻击者使用用户的浏览器发送http请求,浏览器不会发送令牌的会话变量吗?(因为用户具有与令牌关联的sessionid)。 我将令牌存储在会话变量的一个隐藏值内。 例如:我的令牌存储在会话变量中,然后攻击者将我发送到具有csr