Uploaded image for project: 'OASIS Open Data Protocol (OData) TC'
  1. OASIS Open Data Protocol (OData) TC
  2. ODATA-974

Flesh out recommendations around OAuth support in OData

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: V4.0_ERRATA03
    • Fix Version/s: V4.01_WD01
    • Component/s: Protocol
    • Labels:
      None
    • Environment:

      Proposed

    • Proposal:
      Hide

      Define an Authorization vocabulary as follows:

      <Term Name="Authorizations" Type="Collection(Auth.Authorization)" AppliesTo="EntityContainer EntitySet NavigationProperty">
      <Annotation Term="Core.Description" String="Lists the methods available to authorize access to the annotated resource."/>
      </Term>

      <ComplexType Name="Authorization" Abstract="true">
      <Annotation Term="Core.Description" String="Base type for all Authorization types."/>
      <Property Name="Description" Type="Edm.String"/>
      </ComplexType>

      <ComplexType Name="OpenIDConnect" BaseType="Auth.Authorization">
      <Property Name="IssuerUrl" Type="Edm.String" Nullable="false">
      <Annotation Term="Core.Description" String="Issuer location for the OpenID Provider. Configuration information can be obtained by appending /.well-known/openid-configuration to this Url."/>
      </Property>
      </ComplexType>

      <ComplexType Name="Http" BaseType="Auth.Authorization">
      <Property Name="Scheme" Type="Edm.String" Nullable="false">
      <Annotation Term="Core.Description" String="HTTP Authorization scheme to be used in the Authorization header, as per RFC7235."/>
      </Property>
      <Property Name="BearerFormat" Type="Edm.String">
      <Annotation Term="Core.Description" String="Format of the bearer token."/>
      </Property>
      </ComplexType>

      <ComplexType Name="OAuthAuthorization" BaseType="Auth.Authorization" Abstract="true">
      <Property Name="Scopes" Type="Collection(Auth.AuthorizationScopes)">
      <Annotation Term="Core.Description" String="Available scopes."/>
      </Property>
      <Property Name="RefreshUrl" Type="Edm.String">
      <Annotation Term="Core.Description" String="Refresh Url."/>
      <Annotation Term="IsURL"/>
      </Property>
      </ComplexType>

      <ComplexType Name="OAuth2ClientCredentials" BaseType="Auth.OAuthAuthorization">
      <Property Name="TokenUrl" Type="Edm.String" Nullable="false">
      <Annotation Term="Core.Description" String="Token Url."/>
      <Annotation Term="IsURL"/>
      </Property>
      </ComplexType>

      <ComplexType Name="OAuth2Implicit" BaseType="Auth.OAuthAuthorization">
      <Property Name="AuthorizationUrl" Type="Edm.String" Nullable="false">
      <Annotation Term="Core.Description" String="Authorization URL."/>
      <Annotation Term="IsURL"/>
      </Property>
      </ComplexType>

      <ComplexType Name="OAuth2Password" BaseType="Auth.OAuthAuthorization">
      <Property Name="TokenUrl" Type="Edm.String" Nullable="false">
      <Annotation Term="Core.Description" String="Token Url."/>
      <Annotation Term="IsURL"/>
      </Property>
      </ComplexType>

      <ComplexType Name="OAuth2AuthCode" BaseType="Auth.OAuthAuthorization">
      <Property Name="AuthorizationUrl" Type="Edm.String" Nullable="false">
      <Annotation Term="Core.Description" String="Authorization URL."/>
      <Annotation Term="IsURL"/>
      </Property>
      <Property Name="TokenUrl" Type="Edm.String" Nullable="false">
      <Annotation Term="Core.Description" String="Token Url."/>
      <Annotation Term="IsURL"/>
      </Property>
      </ComplexType>

      <ComplexType Name="AuthorizationScopes">
      <Property Name="Scope" Type="Edm.String" Nullable="false">
      <Annotation Term="Core.Description" String="Scope name."/>
      </Property>
      <Property Name="Description" Type="Edm.String">
      <Annotation Term="Core.Description" String="Description of the scope."/>
      </Property>
      </ComplexType>

      <ComplexType Name="ApiKey" BaseType="Auth.Authorization">
      <Property Name="KeyName" Type="Edm.String" Nullable="false">
      <Annotation Term="Core.Description" String="The name of the header or query parameter"/>
      </Property>
      <Property Name="Location" Type="Auth.KeyLocation" Nullable="false">
      <Annotation Term="Core.Description" String="Whether the API Key is passed in the header or as a query option"/>
      </Property>
      </ComplexType>

      <EnumType Name="KeyLocation">
      <Member Name="Header"/>
      <Member Name="QueryOption"/>
      </EnumType>

      </Schema>
      </edmx:DataServices>
      </edmx:Edmx>

      Example of usage:

      <Annotation Term="Auth.Authorizations">
      <Collection>
      <Record Type="Auth.Http"/>
      <Record Type="Auth.OpenIDConnect">
      <PropertyValue Name="IssuerUrl" String="https://example.com/issuer1"/>
      </Record>
      <Record Type="Auth.OAuth2AuthCode">
      <PropertyValue Name="AuthorizationUrl" String="http://myauth/authorize"/>
      <PropertyValue Name="TokenUrl" String="http://myauth/token"/>
      <PropertyValue Name="Scopes">
      <Collection>
      <Record>
      <PropertyValue Name="Scope" String="write:pets"/>
      <PropertyValue Name="Description" String="modify pets"/>
      </Record>
      </Collection>
      </PropertyValue>
      </Record>
      </Collection>
      </Annotation>

      Show
      Define an Authorization vocabulary as follows: <Term Name="Authorizations" Type="Collection(Auth.Authorization)" AppliesTo="EntityContainer EntitySet NavigationProperty"> <Annotation Term="Core.Description" String="Lists the methods available to authorize access to the annotated resource."/> </Term> <ComplexType Name="Authorization" Abstract="true"> <Annotation Term="Core.Description" String="Base type for all Authorization types."/> <Property Name="Description" Type="Edm.String"/> </ComplexType> <ComplexType Name="OpenIDConnect" BaseType="Auth.Authorization"> <Property Name="IssuerUrl" Type="Edm.String" Nullable="false"> <Annotation Term="Core.Description" String="Issuer location for the OpenID Provider. Configuration information can be obtained by appending /.well-known/openid-configuration to this Url."/> </Property> </ComplexType> <ComplexType Name="Http" BaseType="Auth.Authorization"> <Property Name="Scheme" Type="Edm.String" Nullable="false"> <Annotation Term="Core.Description" String="HTTP Authorization scheme to be used in the Authorization header, as per RFC7235."/> </Property> <Property Name="BearerFormat" Type="Edm.String"> <Annotation Term="Core.Description" String="Format of the bearer token."/> </Property> </ComplexType> <ComplexType Name="OAuthAuthorization" BaseType="Auth.Authorization" Abstract="true"> <Property Name="Scopes" Type="Collection(Auth.AuthorizationScopes)"> <Annotation Term="Core.Description" String="Available scopes."/> </Property> <Property Name="RefreshUrl" Type="Edm.String"> <Annotation Term="Core.Description" String="Refresh Url."/> <Annotation Term="IsURL"/> </Property> </ComplexType> <ComplexType Name="OAuth2ClientCredentials" BaseType="Auth.OAuthAuthorization"> <Property Name="TokenUrl" Type="Edm.String" Nullable="false"> <Annotation Term="Core.Description" String="Token Url."/> <Annotation Term="IsURL"/> </Property> </ComplexType> <ComplexType Name="OAuth2Implicit" BaseType="Auth.OAuthAuthorization"> <Property Name="AuthorizationUrl" Type="Edm.String" Nullable="false"> <Annotation Term="Core.Description" String="Authorization URL."/> <Annotation Term="IsURL"/> </Property> </ComplexType> <ComplexType Name="OAuth2Password" BaseType="Auth.OAuthAuthorization"> <Property Name="TokenUrl" Type="Edm.String" Nullable="false"> <Annotation Term="Core.Description" String="Token Url."/> <Annotation Term="IsURL"/> </Property> </ComplexType> <ComplexType Name="OAuth2AuthCode" BaseType="Auth.OAuthAuthorization"> <Property Name="AuthorizationUrl" Type="Edm.String" Nullable="false"> <Annotation Term="Core.Description" String="Authorization URL."/> <Annotation Term="IsURL"/> </Property> <Property Name="TokenUrl" Type="Edm.String" Nullable="false"> <Annotation Term="Core.Description" String="Token Url."/> <Annotation Term="IsURL"/> </Property> </ComplexType> <ComplexType Name="AuthorizationScopes"> <Property Name="Scope" Type="Edm.String" Nullable="false"> <Annotation Term="Core.Description" String="Scope name."/> </Property> <Property Name="Description" Type="Edm.String"> <Annotation Term="Core.Description" String="Description of the scope."/> </Property> </ComplexType> <ComplexType Name="ApiKey" BaseType="Auth.Authorization"> <Property Name="KeyName" Type="Edm.String" Nullable="false"> <Annotation Term="Core.Description" String="The name of the header or query parameter"/> </Property> <Property Name="Location" Type="Auth.KeyLocation" Nullable="false"> <Annotation Term="Core.Description" String="Whether the API Key is passed in the header or as a query option"/> </Property> </ComplexType> <EnumType Name="KeyLocation"> <Member Name="Header"/> <Member Name="QueryOption"/> </EnumType> </Schema> </edmx:DataServices> </edmx:Edmx> Example of usage: <Annotation Term="Auth.Authorizations"> <Collection> <Record Type="Auth.Http"/> <Record Type="Auth.OpenIDConnect"> <PropertyValue Name="IssuerUrl" String="https://example.com/issuer1"/> </Record> <Record Type="Auth.OAuth2AuthCode"> <PropertyValue Name="AuthorizationUrl" String="http://myauth/authorize"/> <PropertyValue Name="TokenUrl" String="http://myauth/token"/> <PropertyValue Name="Scopes"> <Collection> <Record> <PropertyValue Name="Scope" String="write:pets"/> <PropertyValue Name="Description" String="modify pets"/> </Record> </Collection> </PropertyValue> </Record> </Collection> </Annotation>

      Description

      Today there is no interoperable way to consume an OData service that supports authentication. We recommend, in Chapter 20, the use of basic auth (which is more interoperable, but less secure than something more common like oauth).

      If we could provide information, perhaps through a vocabulary, that would describe the authentication flow of the service, it would hugely improve interoperability across authenticated services.

      One option would be to advertise in $metadata action annotated as an authorization action, with (well-known) parameters for the information it needs (clientid, secret, scope, etc.). I.e., when the client invokes the "Login" action with the appropriate parameter values, the service would build the authentication url using the parameter values with a redirect url to itself, redirect the client to that authentication url, and then wait to be called back on its own supplied redirect url.

      Note that Swagger/OneAPI defines some auth flow here, but it is unclear whether this is would work for all cases (the only listed auth types are "basic", "apiKey", and "OAuth2" – OAuth1, at least, is absent) https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#securityDefinitionsObject

        Attachments

          Activity

            People

            • Assignee:
              mikep Michael Pizzo
              Reporter:
              mikep Michael Pizzo
            • Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: