Configuração server protheus para autenticação via oAuth 1.0:

No arquivo appserver.ini inclua as configurações necessárias como mostra o passo a passo no link abaixo:
Configuração rest protheus

Para a autenticação oAuth funcionar é necessário configurar o servidor rest com https, para isso na seção HTTPREST (conforme link acima) precisa estar configurado da seguinte forma:

[HTTPREST]
Port=8090
URIs=HTTPURI
Security=1
SSL2=0
SSL3=1
CERTIFICATE   =C:\TOTVS\totvs_harpia\Protheus\bin\appserver\totvs_certificate.crt
KEY           =C:\TOTVS\totvs_harpia\Protheus\bin\appserver\totvs_certificate_key.pem
TLS1    =3

Atenção

Alerta de risco: fique atento ao utilizar o parâmetro de configuração com a chave Security=0, pois isso fará com que as integrações (APIs) não exijam autenticação, consequentemente dados do seu ambiente poderão ser consultados sem qualquer controle de autorização.

Aviso

Em um ambiente de produção o certificado utilizado precisa ser um certificado valido e emitido por uma empresa autenticadora reconhecida.
Certificados auto assinados irão resultar em falha no reconhecimento do https pelo client.


Para a autenticação via oAuth é necessário gerar as chaves publica e privada conforme é demonstrado no link abaixo:
Gerando as chaves oAuth no configurador


Exemplo de um fonte advpl consumindo uma api rest do protheus e autenticando via oAuth:

#include "protheus.ch"
#include "rwmake.ch" 
//-------------------------------------------------------------------
/*/{Protheus.doc} OAuthT1
    Teste oAuth, consumo manual
@author Caio Lima
@since 14/06/2022
//-----------------------------------------------------------------*/
User Function OAuthT1()
    Local oUrl as object
    Local oOauth as object
    Local cUrlBase as character
    Local cUrlReq as character
    Local cUrlAut as character
    Local cUrlAcc as character
    Local cConsumerKey as character
    Local cConsumerSecret as character
    Local oJsonRet as object

    cConsumerKey := "155dfkjh2uhi1uh237y1231sdfad20f093fc"
    cConsumerSecret := "b090cf3asdfsaf123dafjh2u1291c6f8328"
    cUrlBase := "https://localhost:8090/rest"
    cUrlReq := cUrlBase + "/oAuth/Request_Token"
    cUrlAut := cUrlBase + "/oAuth/Login"
    cUrlAcc := cUrlBase + "/oAuth/Access_Token"

    oUrl := FWoAuthURL():New(cUrlReq, cUrlAut, cUrlAcc)
    oOauth := MyoAuthClient():New( cConsumerKey, cConsumerSecret, oUrl, /* cCallBack */ "" )

    oOauth:SetMethodSignature("PLAINTEXT")

    oOauth:SetUser("admin","1234")
    oOauth:SetContentType("application/json")

    cReturn := oOauth:Get(cUrlBase + "/shiftf6/",,,)
    If !Empty(cReturn)
        oJsonRet := JsonObject():New()
        oJsonRet:FromJSON(cReturn)
        Aviso( 'VarInfo', VarInfo('oJsonRet', oJsonRet , , .F. ) ,{'ok'} ,4,,,, .T.)
    EndIf
Return

//-------------------------------------------------------------------
/*/{Protheus.doc} MyoAuthClient
    Classe para conexão com cliente oAuth com assinatura plaintext
@author Caio Lima
@since 14/06/2022
//-----------------------------------------------------------------*/
Class MyoAuthClient From FWoAuthClient
    Data cUser as character
    Data cPassword as character
    Data aLastError as array

    // token definitivo
    Data cDefToken as character
    Data cDefTokenSecret as character

    Method New() CONSTRUCTOR
    Method UpdateParam()
    Method SetUser()
    Method Authorize()
    Method AccessToken()
    Method GetOAuthHeader()
    Method Get()
EndClass

//-------------------------------------------------------------------
/*/{Protheus.doc} setUser
    define usuario e senha
@author Caio Lima
@since 14/06/2022
//-----------------------------------------------------------------*/
Method SetUser(cUser, cPassword) CLASS MyoAuthClient
    self:cUser := cUser
    self:cPassword := cPassword
Return

//-------------------------------------------------------------------
/*/{Protheus.doc} New
    Metodo construtor
@author Caio Lima
@since 14/06/2022
//-----------------------------------------------------------------*/
Method New(cConsumer,cSecret,oURL,cCallback) CLASS MyoAuthClient
    _Super:New(cConsumer,cSecret,oURL,cCallback)
Return self

//-------------------------------------------------------------------
/*/{Protheus.doc} Get
    GET
@author Caio Lima
@since 15/06/2022
//-----------------------------------------------------------------*/
Method Get(cUrl) CLASS MyoAuthClient
    Local aHeader as array
    Local cRet as character
    Local cHeadRet as character

    self:RequestToken()

    If self:Authorize()
        If self:AccessToken()
            self:UpdateParam(.T.)
            aHeader := self:GetOAuthHeader()
            cRet := HttpGet(cUrl, "",120, aHeader, @cHeadRet)
            If !"200 OK" $ cHeadRet .OR. Empty(cRet)
                self:aLastError := {cHeadRet, cRet}
                Aviso( 'Method Get', VarInfo('aLastError', self:aLastError , , .F. ) ,{'ok'} ,4,,,, .T.)
            EndIf
        EndIf
    EndIf
Return(cRet)

//-------------------------------------------------------------------
/*/{Protheus.doc} GetOAuthHeader
    retorna o header com Authorization:OAuth conforme self:parametros
@author Caio Lima
@since 15/06/2022
//-----------------------------------------------------------------*/
Method GetOAuthHeader() CLASS MyoAuthClient
    Local cHeadAut as character
    Local aHeader as array
    Local _nx as numeric

    aHeader := {}

    cHeadAut := "Authorization:OAuth "
    For _nx := 1 to Len(self:aParametros)
        cHeadAut += self:aParametros[_nx,1] + '="' + self:aParametros[_nx,2] + '" '
    Next
    If !Empty(self:cUser)
        cHeadAut += 'user="'+ self:cUser +'" password="'+ self:cPassword +'"'
    Else
        // retira a virgula final
        cHeadAut := Left(cHeadAut, Len(cHeadAut) - 1)
    EndIf

    Aadd(aHeader, cHeadAut)
Return(aHeader)

//-------------------------------------------------------------------
/*/{Protheus.doc} AccessToken
    Define o token definitivo de acesso que já pode ser utilizado 
    no consumo das apis
@author Caio Lima
@since 14/06/2022
//-----------------------------------------------------------------*/
Method AccessToken(ntipo) Class MyoAuthClient
    Local cHeadRet as character
    Local aRet as array
    Local lRet as logical

    cHeadRet := ""

    self:UpdateParam()

    cRet := HttpGet(self:oURL:cAccess, "",120, self:GetOAuthHeader(), @cHeadRet)

    If "200 OK" $ cHeadRet .AND. "oauth_token_secret" $ cRet
        cRet := StrTran(cRet, "oauth_token=", "")
        cRet := StrTran(cRet, "oauth_token_secret=", "")
        aRet := StrTokArr(cRet,"&")
        self:cDefToken := aRet[1]
        self:cDefTokenSecret := aRet[2]
        lRet := .T.
    Else
        lRet := .F.
        self:aLastError := {cHeadRet, cRet}
        Aviso( 'Method AccessToken', VarInfo('aLastError', self:aLastError , , .F. ) ,{'ok'} ,4,,,, .T.)
    EndIf
Return(lRet)

//-------------------------------------------------------------------
/*/{Protheus.doc} Authorize
    Efetua a autenticação do usuario no server
@author Caio Lima
@since 15/06/2022
//-----------------------------------------------------------------*/
Method Authorize() Class MyoAuthClient
    Local lRet as logical
    Local cHeadRet as character

    lRet := .F.
    cHeadRet := ""

    self:UpdateParam()

    cRet := HttpGet(self:oURL:cAuthorize, "",120,self:GetOAuthHeader(), @cHeadRet)

    If "200 OK" $ cHeadRet .AND. "<error>0</error>" $ Lower(cRet)
        lRet := .T.
    Else
        lRet := .F.
        self:aLastError := {cHeadRet, cRet}
        Aviso( 'Method Authorize', VarInfo('aLastError', self:aLastError , , .F. ) ,{'ok'} ,4,,,, .T.)
    EndIf
Return(lRet)

//-------------------------------------------------------------------
/*/{Protheus.doc} UpdateParam
    Atualiza parâmetros do oAuth
@author Caio Lima
@since 15/06/2022
/*/
//-------------------------------------------------------------------
Method UpdateParam(lDefToken) CLASS MyoAuthClient

    Default lDefToken := .F.

    self:aParametros	:= {}

    self:cNonce := SubStr(Sha1(DToS(Date()) + Time()),1,32)
    self:cTimeStamp := FWTimeStamp(4)

    aAdd(self:aParametros,{"oauth_consumer_key",Escape(self:cConsumerKey)})
    aAdd(self:aParametros,{"oauth_timestamp",self:cTimeStamp})
    aAdd(self:aParametros,{"oauth_nonce",self:cNonce})
    aAdd(self:aParametros,{"oauth_signature_method","PLAINTEXT"})
    aAdd(self:aParametros,{"oauth_version","1.0"})
    aAdd(self:aParametros,{"oauth_signature", self:cSecretKey + Iif(Empty(self:cSecretToken),"","&" + self:cSecretToken) })

    If lDefToken
        aAdd(self:aParametros,{"oauth_token",self:cDefToken})
        aAdd(self:aParametros,{"oauth_token_secret",self:cDefTokenSecret})
    ElseIf !Empty(self:cToken)
        aAdd(self:aParametros,{"oauth_token",self:cToken})
        aAdd(self:aParametros,{"oauth_token_secret",self:cSecretToken})
    EndIf

Return self


Após configurado o rest e gerado as chaves de autenticação,
basta alterar as variáveis cConsumerKey e cConsumerSecret da função acima e corrigir o endereço na cUrlBase.
Depois é só chamar a função U_OAuthT1()

  • Sem rótulos