Controle de Acesso em APIs OData no SAP

Alessandra Marinho
5 min readAug 3, 2023

--

vecteezy.com

Depois de assistir à palestra do José Sequeira no SAP Inside Track SP deste ano (que inclusive deixei o link aqui no final) falando sobre segurança de aplicativos Fiori, vou falar um pouco sobre como aumentar a segurança das informações de suas APIs OData criadas no SAP, tanto via CDS quanto via SEGW.

Minha ideia aqui não é falar sobre autenticação mas sim sobre como o desenvolvedor ABAP pode melhorar a segurança das APIs que estão desenvolvendo usando objetos de autorização e controles de acesso.

Vamos por partes:

CDS

Vamos imaginar o seguinte cenário: uma CDS exposta como uma API para ser utilizada por agências de viagens e elas só podem ver os dados de viagem da sua agência.

Primeiro criei uma CDS para fazer o teste deixando todas as annotations default:

@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Testando Access Control'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define view entity Z_TEST_ACCESS_CONTROL
as select from /dmo/travel_m
{
key travel_id,
agency_id,
customer_id,
@Semantics.amount.currencyCode: 'currency_code'
total_price,
currency_code
}

Executando esta CDS, o resultado é o seguinte:

Nesse primeiro momento a CDS está retornando tudo, então se a agência tiver autorização para executar o serviço da CDS teria acesso a dados que não poderia ver.

Para atender o requerimento de a agência ver somente viagens de sua própria agência vamos utilizar melhor a annotation: @AccessControl.authorizationCheck

Essa annotation possui as seguintes opções:

  • #NOT_REQUIRED — quando não é definido nem necessário controle de acesso.
  • #CHECK — se comporta semelhante ao NOT_REQUIRED mas quando ativa a CDS é exibido um alerta caso não tenha sido criado o controle de acesso.
  • #MANDATORY — Dará um dump ao acessar a CDS caso não tenha sido definido um controle de acesso.
  • #NOT_ALLOWED — Aparecerá uma mensagem de alerta se um controle de acesso for criado.
  • #PRIVILEGED_ONLY — Acesso via ABAP SQL vai funcionar somente se incluir o privilégio de acesso (SELECT * FROM table WITH PRIVILEGED ACCESS… ). Também aparece o alerta como no #CHECK caso não tenha sido implementado o controle de acesso.

Para criar o controle de acesso é só ir em: File > New > Other > ABAP > Core Data Services > Access Control ou botão direito em Core Data Services > Access Control.

Informa o nome do seu controle de acesso, a descrição e qual é a CDS que utilizará esse controle.

O modelo vem assim:

Como eu estou no ambiente ABAP do SAP BTP Trial meu exemplo está com um valor fixo… mas abaixo vou colocar um exemplo utilizando objeto de autorização.

@EndUserText.label: 'Test Access Control'
@MappingRole: true
define role Z_ACCESS_CONTROL {
grant
select
on
Z_TEST_ACCESS_CONTROL
where
agency_id = '070046';
}

O resultado ao executar a CDS:

Agora o exemplo de como utilizar um objeto de autorização que acredito que seria o cenário mais comum:

@EndUserText.label: 'Test Access Control'
@MappingRole: true
define role Z_USANDO_OBJETO_AUTORIZACAO{
grant select on Z_TEST_ACCESS_CONTROL
where (nome_campo) =
aspect pfcg_auth (nome_objeto, nome_campo, actvt='03'); }

Se você está criando uma CDS e está na dúvida se deveria ou não criar um controle de acesso, já pergunta pro funcional/usuário se deveria e qual é objeto que deve ser utilizado ou criado! 😉

SEGW

Bom, na SEGW o negócio já é mais free style 🤣🤣

Quando você cria um projeto de gateway via SEGW, você pode criar várias entidades e implementar os métodos de GET, POST, PATCH e DELETE para cada uma delas. Mas a autorização é por serviço, então se o usuário tiver acesso ao S_SERVICE do seu projeto poderia executar qualquer um dos métodos para qualquer entidade que estiver implementado.

A pergunta é: deveria? O usuário que executa seu serviço deveria ter acesso a executar a leitura de dados, gravar e até mesmo deletar?

Eu procurei algum tipo de recomendação para casos de criação de projetos gateway e confesso que não encontrei. Mentira, na verdade encontrei isso aqui no help da SAP:

https://help.sap.com/docs/SAP_HANA_PLATFORM/52715f71adba4aaeb480d946c742d1f6/83f6c5fb1c1b4c45a5c89877be01c585.html

Então minha ideia nesse cenário é usar o bom e velho AUTHORITY-CHECK.

Podemos fazer a validação de autorização no início de cada método implementado na classe DPC_EXT como nesse exemplo:

CLASS ZCL_TESTE_DPC_EXT IMPLEMENTATION.

METHOD /iwbep/if_mgw_appl_srv_runtime~create_deep_entity.

io_data_provider->read_entry_data(
IMPORTING
es_data = wa_dados ).

"Verifica objeto de autorização
AUTHORITY-CHECK OBJECT 'S_WERKS'
ID 'WERKS' FIELD wa_dados-werks
ID 'ACTVT' FIELD '01'.

IF sy-subrc = 0.
"Autorizado para continuar
...
ELSE.
CALL METHOD lo_message_container->add_message_text_only
EXPORTING
iv_msg_type = 'E'
iv_msg_text = 'Deu ruim!'

RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
textid = /iwbep/cx_mgw_busi_exception=>business_error
message_container = lo_message_container
ENDIF.

ENDMETHOD.
ENCLASS.

Assim a gente consegue garantir que quem tem acesso ao serviço também tem autorização para fazer aquele processo dentro do ambiente! Claro que, se seu código estiver usando alguma BAPI ou função standard que já tenha uma validação de autorização vai barrar se o usuário não tiver acesso mas mesmo assim precisa tratar a saída para retornar uma mensagem decente na API rs.

Links legais

A palestra que comentei:

Se você tiver alguma dica sobre como melhorar a segurança nas APIs customizadas comenta aí!

E é isso! 😊

Alessandra

--

--

Alessandra Marinho

Há 15 anos escrevendo códigos em ABAP e agora tentando escrever outras coisas 😊