API Access Control

This page explains the concept of access delegation, authentication and user consent flows in the context of SMA API consumption

SMA takes data privacy serious

SMA provides a data privacy compliant API-access framework which relies on the oAuth2 framework to meet the data privacy regulation outlined in GDPR and in similar international regulations (US: CCPA, Japan: PPI). Central conceptual element is that SMA system-owners are in control how their data assets are shared and processed. Therefore SMA system-owners are required to provide their explicit, revocable, logged user consent (permission) to share data with 3rd party applications. Our approach intends to keep non-compliance risks away from our partners which can result in potentially very costly penalties.

Recommendation:

Please encourage plant owners to create a SMA user account to manage their 3rd party permissions for full compliance to data privacy regulations. In most cases an installer/operator will not be eligible for access delegation on behalf of the plant owner. Furthermore, a SMA plant owner account will enable the user for consumer-centric use-cases such as enabling smartHome or eMobility Apps to access his SMA plant data.

SMA system-owner permission flows to support your App Use-case

Any SMA API such as SMA Monitoring API requesting data on system-basis, will need a permission from the related system-owner. Therefore, SMA provides two permission (user-consent) flow to support the related approval process.

a. End-user applications e.g. SmartHome Apps or eMobility Apps can integrate a Connect SMA-button on their user-interface. The system-owner is redirected to SMA in order to log-in and approve your applications access. Your application should implement our oAuth2 code grant flow.

b. O&M and back-channel oriented applications should implement SMA custom flow to capture the owner-permission asynchronously. Your client will request the owners-permission by providing the related owners eMail on SMA systems. This will trigger SMA to send out an eMail to the owner and once he logged in to SMA Portal & approved your request, your client can assess his system data.

  • On SMA SunnyPortal (see image): Ensure that the owner has set the “system-owner” flag on related SMA Sunny Portal systems (Admin user to set in Plant mngt. > User mngt).

  • On SMA ennexOS: Ensure that the owner has the “owner-role” defined for his account

System-owner permission (user-consent) screen

SMA will present a user-consent/permission screen on behalf of your application access request. In order to setup your client credentials and configure the according permission-screen for your application, we will need to receive data from you which will be embedded on this screen.

For both permission flows, SMA will need to receive URLs to following application content:

OAuth2 Authorization Code Grant Flow

To enable a 3rd party eMobility or Smart Home application to retrieve SMA data e.g. via SMA Monitoring-API of an on-screen SMA user, you will need to implement the OAuth2 authorization code grant flow as described here.

The authorization code grant type is used to obtain both access tokens and refresh tokens from the SMA authorization server and is optimised for confidential clients. Since this is a redirection-based flow, the client MUST be capable of interacting with the SMA user-agent (typically a web browser) and be capable of receiving incoming requests (via redirection) from the authorization server.

In the authorization code grant flow, the client needs to perform two steps to obtain the tokens, involving the browser in the first step and a back-channel request in the second step.

Step1


Purpose

a. Authenticate the SMA resource owner/user
b. Authorise the 3rd party client application


Via

Front-channel request


To

SMA Authorization endpoint
Sandbox: sandbox-auth.smaapis.de/oauth2/auth
Productive: auth.smaapis.de/oauth2/auth


Result on success

Authorization code
(as input parameter for step2)

Step2


Purpose

a. Authenticate the 3rd party client application
b. Exchange "code" for "token"


Via

Back-channel request


To

SMA Token endpoint
Sandbox: sandbox-auth.smaapis.de/oauth2/token
Productive: auth.smaapis.de/oauth2/token


Result on success

Access Token
Refresh Token

Step3


Purpose

Token Handling


Via

Back-channel request


To

Make use of the grant_type: refresh_token to maintain the session as detailed in “TokenHandling”


Result on success

If not used anymore, logout sessions to prevent exceeded max. session count

Step1: Authorization request

The client application initiates the flow by redirecting the browser to the SMA authorization server with an authorization request which includes the following parameters and encoded as application/x-www-form-urlencoded as defined here.

Sample request

12345
GET auth.smaapis.de/oauth2/auth?client_id={yourClientID}&response_type={code}&redirect_uri={clientRedirectURI/callback}&state={opaque_value}

Parameters

  • client_id: Value MUST be set according to Id provided by SMA

  • response_type: Value MUST be set to code

  • redirect_uri: Value MUST be set as defined on application registration form

  • scope: SMA will not make use of the optional OAuth2 scopes initially. Thus the 3rd party authorization is requesting access to all (API) resources of a given SMA user (privileges).

  • state: Value MUST be set. An opaque value your application adds to the initial request, which the authorization server includes when redirecting back to your application URI.

SMA authorization request processing

SMA authorization server validates the request to ensure that all required parameters are present and valid. If the request is valid, the authorization server authenticates the resource owner - either there is a valid session established by a browser cookie or by prompting the user to login. After that, the server will determine if the client is to be authorized or not, by asking the user for his permission on the user consent page.

When a user decision is established, the authorization server respond by redirecting the user back to the client URI along with an authorization code and the formerly provided state (opaque value) from the client request in the query string.

Sample response (success)

1
https://yourapp.example.com/callback?code=SplxlOBeZQQYbYS6WxSbIA&state=af0ifjsldkj

Your client application must validate the state parameter, and use the code to proceed to the next step.

Step2: Access token request (Exchange "code" for "token")

The authorization code is an intermediate credential, which encodes the authorization obtained at step 1. It is therefore opaque to the client and only has meaning to the authorization server. To retrieve the access token for the API endpoint, the client app must submit the code to the authorization server, but this time with a direct back-channel request.

This is done for two reasons:

  • To authenticate confidential clients with the authorization server before revealing the token;

  • To deliver the token straight to the client preventing cross-site forgery by avoiding exposing it to the browser.

Sample request

1234567
POST auth.smaapis.de/oauth2/tokenHTTP/1.1Host: smaapis.deContent-Type: application/x-www-form-urlencoded client_id={yourClientID}&client_secret={client_secret}&grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https://yourapp.example.com

Parameters

  • client_id: Value MUST be set according to Id provided by SMA

  • client_secret: Value MUST be set according to secret provided by SMA

  • grant_type: Value MUST be set to “authorization_code

  • redirect_uri: Value MUST be set as defined on application registration form

On success the authorization server will return a JSON object with the issued access and refresh token:

Custom OAuth2-oriented Authorization Flow

To enable a 3rd party application to retrieve SMA data, e.g. via SMA Monitoring-API of an off-screen SMA user, you will need to implement the custom authorization flow as described here.

SMA combines the standard oAuth2 client credential grant type illustrated in step1 with a custom backchannel user-authorization as explained in step2 / step3.

You will need to know the SMA userId (eMail) of related systems you want to gain access to. This usedId must be provided as “loginHint” in step2 and will trigger a notification of SMA to the system-owner requesting permission for your application. Make sure that the owner has set the plant-owner flag for all related systems in the User Management on SMA SunnyPortal and ennexOS alike.

In the custom authorization grant flow, the client needs to perform three steps to gain access to a user´s resources.

Step1


Purpose

a. Authenticate the 3rd Party Client
b. Authorize the 3rd party client app for specified SMA APIs


Via

Back-channel request


To

SMA Authorization endpoints
Sandbox: POST sandbox-auth.smaapis.de/oauth2/token
Productive: POST auth.smaapis.de/oauth2/token


Result on success

(Client) Token

Step2


Purpose

a. Authenticate the SMA resource user
b. Authorize the 3rd party client application


Via

Back-channel request


To

SMA BC-Auth endpoints
Sandbox: POST sandbox.smaapis.de/oauth2/v2/bc-authorize
Productive: POST async-auth.smaapis.de/oauth2/v2/bc-authorize


Result on success

Authorization Request Identifier

Step3


Purpose

a. Authenticate the 3rd party client app
b. Poll result for “user” (SystemOwner)


Via

Back-channel request


To

SMA BC-Auth endpoints
Sandbox: GET sandbox.smaapis.de/oauth2/v2/bc-authorize/{loginHint}
Productive: GET async-auth.smaapis.de/oauth2/v2/bc-authorize/{loginHint}


Result on success

User permits access;
Client can access user resources

Step4


Purpose

 

Token Handling


Via

Back-channel request


To

Make use of the grant_type: refresh_token to maintain the session as detailed in “TokenHandling”


Result on success

If not used anymore, logout sessions to prevent exceeded max. session count

Owner-Consent Information per Client

GET async-auth.smaapis.de/oauth2/v2/bc-authorize/consentinfo will provide you with a list of owner (eMail) consent status for the associated/related systems IDs

Step1: Client authorization request

As a pre-requisit for the custom flow, your client app will need to request a (Client)Token from the SMA authorization server which includes the following parameters and encoded as application/x-www-form-urlencoded as defined here.

Sample request

1234567
POST auth.smaapis.de/oauth2/tokenHTTP/1.1Host: smaapis.deContent-Type: application/x-www-form-urlencoded client_id={yourClientID}&client_secret={yourClientSecret}&grant_type=client_credentials

Parameters

  • client_id: Value MUST be set according to Id provided by SMA

  • client_secret: Value MUST be set according to secret provided by SMA

  • grant_type: Value MUST be set to “client_credentials”

Step2: Resource-owner authorization request

Once the ClientToken has been obtained it can be used to make calls to the SMA backchannel-authorization endpoint by passing it as a Bearer Token in the authorization header of the HTTP-request. If the request client authentication failed or is invalid, the authorization server returns an error response.

Sample request

12345678
POST async-auth.smaapis.de/oauth2/v2/bc-authorizeHTTP/1.1Host: smaapis.deContent-Type: application/jsonAuthorization: Bearer eyJhbGciOiJSUzI1...{     loginHint: {emailAddressResourceOwner}}

Parameters

  • loginHint: Value MUST be set in order to address the resource owner via email.
    Please assure that SMA user has previously got assigned “systemOwner” flag on the specific PV-systems via SMA Portal UIs.

12345678910
HTTP/1.1 201 CreatedContent-Type: application/json;charset=UTF-8Cache-Control: no-storePragma: no-cache     "loginHint": “max.mustermann@sma.de",     "state": "pending”,     "expirationDate": "2020-09-30T11:37:35.1300000Z",     "interval": 1800}

Parameters

  • loginHint: eMail address of SMA user (systemOwner) who should receive the access request of your 3rd party application.

  • state: Following states are possible: pending, accepted, rejected, expired, revoked.

  • expirationDate: Expiration date of the request. Currently, we foresee 7 day to allow resource-owner to provide his consent. After this time, request will be considered expired and the “state” value will change accordingly to “expired”.

  • interval: Minimum amount of time in seconds that the client SHOULD wait between polling requests to the token endpoint. Currently we foresee 30 minutes before you SHOULD start polling.

SMA authorization request processing (out of band)

SMA authorization server validates the request to ensure that the client is authenticated and all required parameters are present and valid. If the request is valid, the authorization server will notify the SMA resource owner by eMail and inform him about your clients´ access request on his resources. This eMail will include a link to prompt the user login (user authentication) and present the user consent screen as for the code grant flow.

When a user decision is established, the SMA authorization server will remember the user decision and update the status of the related authorization request.

Step3: Resource-owner authorization decision

In order to successfully access specific user data on SMA resource endpoints, loginHint must carry the status “accepted”. Your client must start polling against the SMA bc-authorization endpoint with the specific loginHint.

Sample request

12345
GET async-auth.smaapis.de/oauth2/v2/bc-authorize/{loginHint}HTTP/1.1Host: smaapis.deContent-Type: application/jsonAuthorization: Bearer eyJhbGciOiJSUzI1...

Sample response (Status: “accepted”)

12345678910
HTTP/1.1 200 OKContent-Type: application/json;charset=UTF-8Cache-Control: no-storePragma: no-cache{     “loginHint”: “max.mustermann@sma.de”,     “state”: “pending”,     “expirationDate”: "2020-09-30T11:37:35.1300000Z",     “interval”: 1800}

Parameters

In case the resource owner…

  • has not yet decided on your access request, our server will return a reply with status "pending"

  • has confirmed your access request, our server will return a reply with status "accepted"

  • has declined your access request, our server will return a reply with status "rejected"

  • has not taken any actions on 7 consecutive days, it is assumed that the request has been lost, the job will be terminated and status "expired" will be returned

  • has actively revoked his user consent for your application, our server will return a reply with status "revoked"

Token Handling

  • Make use of the grant_type: refresh_token to maintain the session and request new AccessTokenRefreshToken pair as specified below in sample request

  • If not used anymore, logout sessions to prevent exceeded max. session count (currently no set, but may be introduced in the near future)

  • Offline_Token: By adding scope=offline_access to your Token request in Code or Custom Flow (step1), you may retrieve a persistent refreshToken. You will receive a refreshToken with “refresh_expires_in: 0” which means that the refreshToken won’t expire.
    Make sure that your application is capable of handling offline tokens, since we may change the expiration period in the future.

Sample response (success)

1234567891011121314
HTTP/1.1 200 OKContent-Type: application/json;charset=UTF-8Cache-Control: no-storePragma: no-cache {    "access_token":"2YotnFZFEjr1zCsicMWpAA",    "token_type":"bearer",    "expires_in":”300”,    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",    "refresh_expires_in":”172800”} 
  • token_type: Bearer Token means that the Bearer can access authorized resources without further identification. Short lifespan for improved security. When the access token expires, the user must (re-)authenticate again to get a new access token. Once issued, this token_type cannot be revoked.

  • expires_in: Value in seconds. This value should be tracked as it could change in the future.

  • refresh_token: Long-lived token type, is used to obtain new access tokens without the user's interaction. Refresh tokens extend the connection to the user's account, while still allowing revokeability. If the user has revoked access to the 3rd party application, the refresh token is no longer valid.

  • refresh_expires_in: Value in seconds. This value should be tracked as it could change in the future.

A new access token can be obtained by using grant_type "refresh_token"

Sample request (refresh token)

1234567
POST auth.smaapis.de/oauth2/tokenHTTP/1.1Host: smaapis.deContent-Type: application/x-www-form-urlencoded client_id={yourClientID}&client_secret={yourClientSecret}&grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA

Sample request (logout – invalidate (unused) session)

1234567
POST auth.smaapis.de/oauth2/logoutHTTP/1.1Host: smaapis.deContent-Type: application/x-www-form-urlencoded client_id={yourClientID}&client_secret={yourClientSecret}&grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA

Access to the Ressource API (Use of access token in API-endpoint/resource requests)

Once the access token has been obtained it can be used to make calls to the SMA resource server by passing it as a Bearer Token in the Authorization header of the HTTP-request. If the request client authentication failed or is invalid, the authorization server returns an error response.

12345678
"securitySchemes": {      "Bearer": {        "type": "apiKey",        "description": "The authentication bearer(according to OAuth2) to authenticate itself to the API.",        "name": "Authorization",        "in": "header"      }    }

Cross-Origin Resource Sharing (CORS)

This Section is relevant for web developers. If you are writing apps, which does not require a browser, you can skip this section.

What is Cross-Origin Resource Sharing?

Cross-Origin Resource Sharing (CORS) is a mechanism that allows resources to be requested from other domains (e.g. foo.example requests some data from bar.example). This mechanism uses the Same-Origin Policy (SOP) to validate requests.

How might CORS affect your requests to the SMA servers?

Let us assume that your domain is foobar. When your web application does a request, the browser validates the SOP. It does an http request to our servers to check if CORS is allowed. We do not allow CORS for security reasons. Therefore, the browser running your web application will throw a CORS error.

How to solve this error?

Requests to our server should be redirect through a proxy running on your domain. By using a proxy you effectively bypasses the CORS error since no Cross-Origin request is made.

Code Flow JavaScript Example

Download

We will be happy to advise you on your API projects.

Contact us