Appendix

Abstract

Describes Python and Java code for authentication.

Legacy Authorization

Sample Python code to generate access and refresh token:

from base64 import b64encode
import requests
import json

CLIENT_ID = 'Enter Client ID'
CLIENT_SECRET = 'Enter Client Secret'
AUTH_URL = 'https://api.login.yahoo.com/oauth2/get_token'

headers = {
    "Authorization": "Basic {}".format(
        b64encode(bytes(f"{CLIENT_ID}:{CLIENT_SECRET}", "utf-8")).decode("ascii")
    )
}
data = {
    'grant_type': 'authorization_code',
    'redirect_uri': 'oob',
    'code': 'Generate code - Follow steps shown in link below'

}
response = requests.post(AUTH_URL, headers=headers, data=data)
print('Response: ' + json.dumps(response.json(), indent=2))

Generate code: follow these steps

::

https://developer.yahoo.com/dsp/api/docs/authentication/enable-oauth.html#step-5-generate-authorization-code

DSP Authentication

Sample code to generate access token:

import base64
import hashlib
import hmac
import json
import time
import requests
from urllib.parse import urljoin

# Enter client id and secret here
client_config = {
    "CLIENT_ID": "",
    "CLIENT_SECRET": "",
    "REALM": "dsp",
    "BASE_URL": "https://id.b2b.yahooinc.com/identity",
    "SCOPE": "dsp-api-access"
}


class GenerateJWT:
    def hmac_sha256(self, key, msg, encode_output=False):
        message = bytes(msg, 'utf-8')
        secret = bytes(key, 'utf-8')

        signature = hmac.new(secret, message, digestmod=hashlib.sha256).digest()
        return base64.b64encode(signature) if encode_output else signature

    def get_access_token(self, client_config):
        client_id = client_config['CLIENT_ID']
        client_secret = client_config['CLIENT_SECRET']
        realm = client_config['REALM']
        base_url = client_config['BASE_URL']
        scope = client_config['SCOPE']
        access_token_url_path = 'identity/oauth2/access_token'

        jwt_header = json.dumps({
            "typ": "JWT",
            "alg": "HS256",
        })

        issue_time = int(time.time())  # Seconds since epoch
        expiry_time = issue_time + 600
        aud = urljoin(base_url, '{path}?realm={realm}'.format(path=access_token_url_path, realm=realm))

        jwt_body = {
            "iss": client_id,
            "sub": client_id,
            "aud": aud,
            "exp": expiry_time,
            "iat": issue_time,
        }

        jwt_body = json.dumps(jwt_body)
        jwt_signing_string = (base64.b64encode(jwt_header.encode(encoding='utf-8'))).decode(encoding='utf-8') + '.' + (
            base64.b64encode(jwt_body.encode(encoding='utf-8')).decode(encoding='utf-8'))

        signature = self.hmac_sha256(client_secret, jwt_signing_string)

        jwt_signature = base64.b64encode(signature)
        client_assertion = str(jwt_signing_string) + '.' + str(jwt_signature.decode(encoding='utf-8'))

        data = {
            'grant_type': 'client_credentials',
            'scope': scope,
            'client_assertion_type': 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
            'client_assertion': client_assertion,
            'realm': realm,
        }
        hed = {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Accept': 'application/json'
        }

        resp = requests.post(urljoin(base_url, access_token_url_path), data=data, headers=hed)

        result = resp.json()
        print(str(result))
        print('Access Token: ' + str(result['access_token']))
        return result['access_token']

    def get_advertiser(self, advertiser, access_token):
        hed = {'X-Auth-Token': '' + str(access_token),
               'X-Auth-Method': 'OAUTH2',
               'Content-Type': 'application/json'}
        url = 'https://dspapi.admanagerplus.yahoo.com/traffic/advertisers/' + advertiser
        print('URL:' + url)
        response = requests.get(url, headers=hed)
        print('Response: ' + json.dumps(response.json(), indent=2))


if __name__ == "__main__":
    g = GenerateJWT()
    access_token = g.get_access_token(client_config)
    # example of retrieving advertiser information - Enter advertiser id
    g.get_advertiser('21516', access_token)

Java Example

Add below dependency to pom.xml:

<dependency>
    <groupId>org.bitbucket.b_c</groupId>
    <artifactId>jose4j</artifactId>
    <version>0.5.2</version>
</dependency>
clientId = OAuth2 Client ID
secret = OAuth2 Client Secret

audience = {protocol}://{b2b.host}/identity/oauth2/access_token?realm=


public static String generateJsonWebToken(final String clientId, final String secret,
final String audience) throws OCAuthException {

    JwtClaims claims = new JwtClaims();
    claims.setIssuedAt(NumericDate.now());
    claims.setExpirationTimeMinutesInTheFuture(10);
    claims.setSubject(clientId);
    claims.setIssuer(clientId);
    claims.setAudience(audience);
    claims.setGeneratedJwtId();

    try {
        Key key = new HmacKey(secret.getBytes("UTF-8"));

        JsonWebSignature jws = new JsonWebSignature();
        jws.setPayload(claims.toJson());
        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
        jws.setKey(key);
        jws.setDoKeyValidation(false);

        return jws.getCompactSerialization();

    } catch (Exception e) {
        throw new OCAuthException("JWT Generation failed", e);
    }

}