OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

odata message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: [OASIS Issue Tracker] (ODATA-974) Flesh out recommendations around OAuth support in OData


     [ https://issues.oasis-open.org/browse/ODATA-974?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Michael Pizzo updated ODATA-974:
--------------------------------

    Proposal: 
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="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="AutheticationScopes" OpenType="true">
        <Annotation Term="Core.Description" String="A set of Name/Value pairs with the name being the name of the scope and the value being its description"/>
      </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.AuthorizationOptions">
  <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">
        <Record>
          <PropertyValue Name="write:pets" String="modify pets"/>
        </Record>
      </PropertyValue>
    </Record>
  </Collection>
</Annotation>

  was:
<?xml version="1.0" encoding="utf-8"?>
<!--  -->
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx";>
  <edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/os/vocabularies/Org.OData.Core.V1.xml";>
    <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core"/>
  </edmx:Reference>
  <edmx:DataServices>
    <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"; Namespace="Org.OData.Authentication" Alias="Auth">
      <Annotation Term="Core.Description" String="The Authentication Vocabulary provides terms for describing an OAuth Flow"/>

      <!--Enumerates available (named) authentication schemes-->
      <Term Name="NamedAuthentications" Type="Collection(Auth.NamedAuthentication)">
        <Annotation Term="Core.Description" String="Names authentication flows used by the service"/>
      </Term>

      <ComplexType Name="NamedAuthentication">
        <Property Name="Name" Type="Edm.String"/>
        <Property Name="Scheme" Type="Auth.Authentication"/>
      </ComplexType>

      <!--Enumerates required named or inline authentication schemes-->
      <Term Name="RequiredAuthentications" Type="Collection(Auth.Authentication)">
        <Annotation Term="Core.Description" String="Lists the authentications required by the annotated resource"/>
      </Term>

      <ComplexType Name="Authentication" Abstract="true"/>

      <ComplexType Name="AuthenticationName" BaseType="Auth.Authentication">
        <Property Name="Name" Type="Edm.String"/>  
      </ComplexType>

      <ComplexType Name="Basic" BaseType="Auth.Authentication">
        <Property Name="Description" Type="Edm.String"/>
      </ComplexType>

      <ComplexType Name="OAuthAutentication" BaseType="Auth.Authentication">
        <Property Name="Scopes" Type="Auth.AuthenticationScopes"/>
      </ComplexType>

      <ComplexType Name="OAuth2Application" BaseType="Auth.OAuthAuthentication">
        <Property Name="TokenUrl" Type="Edm.String" Nullable="false">
          <Annotation Term="IsURL"/>
        </Property>
      </ComplexType>

      <ComplexType Name="OAuth2Implicit" BaseType="Auth.OAuthAuthentication">
        <Property Name="AuthorizationUrl" Type="Edm.String" Nullable="false">
          <Annotation Term="IsURL"/>
        </Property>
      </ComplexType>

      <ComplexType Name="OAuth2Password" BaseType="Auth.OAuthAuthentication">
        <Property Name="TokenUrl" Type="Edm.String" Nullable="false">
          <Annotation Term="IsURL"/>
        </Property>
      </ComplexType>
      
      <ComplexType Name="OAuth2AccessCode" BaseType="Auth.OAuthAuthentication">
        <Property Name="AuthorizationUrl" Type="Edm.String" Nullable="false">
          <Annotation Term="IsURL"/>
        </Property>
        <Property Name="TokenUrl" Type="Edm.String" Nullable="false">
          <Annotation Term="IsURL"/>
        </Property>
      </ComplexType>

      <ComplexType Name="AutheticationScopes" OpenType="true">
        <Annotation Term="Core.Description" String="A set of Name/Value pairs with the name being the name of the scope and the value being its description"/>
      </ComplexType>
      
      <ComplexType Name="ApiKey" BaseType="Auth.Authentication">
        <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 usage:
<Annotation Term="Auth.NamedAuthentications">
  <Collection>
    <Record>
      <PropertyValue Name="Name" String="myApikeyFlow"/>
      <PropertyValue Name="Scheme">
        <Record Type="Auth.ApiKey">
          <PropertyValue Name="KeyName" String="api_key"/>
          <PropertyValue Name="Location" EnumMember="Auth.ApiKeyLocation/Header"/>
        </Record>
      </PropertyValue>
    </Record>
    <Record>
      <PropertyValue Name="Name" String="myImplicitFlow"/>
      <PropertyValue Name="Scheme">
        <Record Type="Auth.OAuth2Implicit">
          <PropertyValue Name="AuthorizationUrl" String="http://myauth/authorize"/>
          <PropertyValue Name="Scopes">
            <Record>
              <PropertyValue Name="read:pets" String="read pets"/>
              <PropertyValue Name="write:pets" String="modify pets"/>
            </Record>
          </PropertyValue>
        </Record>
      </PropertyValue>
    </Record>
  </Collection>
</Annotation>

or

<Annotation Term="Auth.RequiredAuthentications">
  <Collection>
    <Record Type="Auth.Basic"/>
    <Record Type="Auth.OAuth2AccessCode">
      <PropertyValue Name="AuthorizationUrl" String="http://myauth/authorize"/>
      <PropertyValue Name="TokenUrl" String="http://myauth/token"/>
      <PropertyValue Name="Scopes">
        <Record>
          <PropertyValue Name="write:pets" String="modify pets"/>
        </Record>
      </PropertyValue>
    </Record>
    <Record Type="Auth.NamedAuthentication">
      <PropertyValue Name="myImplicitFlow"/>
      <PropertyValue Name="Scopes">
        <Record>
          <PropertyValue Name="read:pets" String="read pets"/>
        </Record>
      </PropertyValue>
    </Record>
  </Collection>
</Annotation>



> Flesh out recommendations around OAuth support in OData
> -------------------------------------------------------
>
>                 Key: ODATA-974
>                 URL: https://issues.oasis-open.org/browse/ODATA-974
>             Project: OASIS Open Data Protocol (OData) TC
>          Issue Type: Bug
>          Components: OData Protocol
>    Affects Versions: V4.0_ERRATA03
>         Environment: Proposal needed for CSD01
>            Reporter: Michael Pizzo
>            Assignee: Michael Pizzo
>             Fix For: V4.01_WD01
>
>
> 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



--
This message was sent by Atlassian JIRA
(v6.2.2#6258)


[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]