【问题标题】:Spring OAuth Authorization Server Requires ScopeSpring OAuth 授权服务器需要范围
【发布时间】:2017-02-06 23:30:23
【问题描述】:

我们目前正在使用 Spring OAuth 授权服务器,但目前不使用 OAuth 规范中的“范围”参数。这有点让人头疼,因为 Spring OAuth 授权服务器要求在请求授权代码时明确要求范围。

来自 DefaultOAuth2RequestValidator

if (requestScopes.isEmpty()) {
    throw new InvalidScopeException("Empty scope (either the client or the user is not allowed the requested scopes)");
}

然而,这直接违反了 OAuth 2.0 规范:

4.1.1。授权请求 客户端通过添加以下内容来构造请求 URI 授权端点 URI 的查询组件的参数 根据附录 B,使用“application/x-www-form-urlencoded”格式: 响应类型 必需的。值必须设置为“代码”。 client_id 必需的。 2.2 节中描述的客户端标识符。 重定向uri 可选的。如第 3.1.2 节所述。 范围 可选的。访问请求的范围由 第 3.3 节。 状态 推荐的。客户端用来维护的不透明值 请求和回调之间的状态。授权 服务器在重定向用户代理时包含此值 给客户。该参数应该用于防止 跨站点请求伪造,如第 10.12 节所述。

Spring Authorization Server 这样做有明确的原因吗?我知道我可以用我自己的验证器替换验证器,但我很好奇为什么这是默认设置,以防我因为遗留原因而错过任何理解。

谢谢。

编辑

对于那些寻找遵循规范的替代实现的人,这是我的。它只是检查如果客户端被限制在某些范围内,那么只有请求的范围是必需的,并且请求的范围必须在分配的客户端范围的列表中。如果客户端没有分配范围,则此实现假定允许它们使用任何范围(与资源所做的假设相同)。还不太确定这意味着什么,或者它是否真的正确。如果不是,请告诉我。

import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.security.oauth2.common.exceptions.InvalidScopeException;
import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.TokenRequest;

public class OAuth2RequestValidator
    implements org.springframework.security.oauth2.provider.OAuth2RequestValidator {

  @Override
  public void validateScope(final AuthorizationRequest authorizationRequest,
      final ClientDetails client)
      throws InvalidScopeException {
    this.validateScope(authorizationRequest.getScope(), client.getScope());
  }

  @Override
  public void validateScope(final TokenRequest tokenRequest, final ClientDetails client)
      throws InvalidScopeException {
    this.validateScope(tokenRequest.getScope(), client.getScope());
  }

  private void validateScope(
      final Set<String> requestScopes, 
      final Set<String> clientScopes) {
    if (!CollectionUtils.isEmpty(clientScopes)) {
      if (CollectionUtils.isEmpty(requestScopes)) {
        throw new InvalidScopeException(
            "Empty scope (either the client or the user is "
              + "not allowed the requested scopes)");
      }

      for (final String scope : requestScopes) {
        if (!clientScopes.contains(scope)) {
          throw new InvalidScopeException("Invalid scope: " + scope, clientScopes);
        }
      }
    }
  }

}

【问题讨论】:

标签: spring spring-boot spring-security-oauth2


【解决方案1】:

根据 DefaultOAuth2RequestFactory,如果客户端没有提供范围,将使用为客户端注册的范围。

DefaultOAuth2RequestFactory.java

private Set<String> extractScopes(Map<String, String> requestParameters, String clientId) {
    Set<String> scopes = OAuth2Utils.parseParameterList(requestParameters.get(OAuth2Utils.SCOPE));
    ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);

    if ((scopes == null || scopes.isEmpty())) {
        // If no scopes are specified in the incoming data, use the default values registered with the client
        // (the spec allows us to choose between this option and rejecting the request completely, so we'll take the
        // least obnoxious choice as a default).
        scopes = clientDetails.getScope();
    }

    if (checkUserScopes) {
        scopes = checkUserScopes(scopes, clientDetails);
    }
    return scopes;
}

因此,您可以将您的客户端配置为 default 范围为“all”或类似的范围,例如

public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.inMemory()
            .withClient("client").secret("secret")
            .authorizedGrantTypes("authorization_code", "client_credentials")
            .scopes("all");

【讨论】:

  • 这不是一个坏主意,尽管我们此时没有使用范围,因此将范围分配给客户端可能被视为负面的事情,因为当范围限制被添加到时,他们可能有权执行操作我们未来的应用。问题更多地是围绕为什么 Spring Security OAuth(在我正在/正在使用的版本)不遵循规范。
猜你喜欢
  • 2019-04-05
  • 2013-10-05
  • 2022-01-14
  • 2018-05-07
  • 2015-07-31
  • 2015-01-15
  • 2015-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多