Giter VIP home page Giter VIP logo

here-aaa-java-sdk's Introduction

HERE Authentication, Authorization, and Accounting

Introduction

This repository contains the complete source code for the here-aaa-sdk project. Basic technical information is contained in this file.

This project is maintained by the HERE Identity and Access Management team. For questions contact [email protected].

Deliverables

The here-aaa-sdk project produces artifacts distributed in two ways:

  • The here-oauth-client-dist-<version>.tar.gz bundle. External developers currently receive this bundle as part of onboarding.
  • via the Maven Central Repository

The following artifacts are published to Maven Central:

HERE OAuth Client

Contains code to assist developers to obtain authorization from the HERE OAuth2.0 Authorization Server, for use with HERE Services.

<dependency>
  <groupId>com.here.account</groupId>
  <artifactId>here-oauth-client</artifactId>
  <version>0.4.25</version>
</dependency>

HERE OAuth Client Examples

Example usage of the HERE OAuth Client library; these are tutorials intended to be adapted into or inform design of applications.

Specify the version of the HERE OAuth Client library to include in your code by setting the version element below with a version available on Maven Central:

http://central.maven.org/maven2/com/here/account/here-oauth-client/

Pick the version that you see most fit. We recommend that you select the latest version.

<dependency>
  <groupId>com.here.account</groupId>
  <artifactId>here-oauth-client-example</artifactId>
  <version>0.4.25</version>
</dependency>

Directory Layout

Here is an overview of the top-level files contained in the repository:

|
+- here-oauth-client      # Source and test code for supported HERE OAuth2.0 flows
|  |
|  +- src                 # Source and test code
|     |
|     +- main             # Source code.  The generated JAR file and javadocs are delivered to developers
|     |
|     +- test             # Test code
|
+- examples               # Examples across all projects; these are tutorials intended to be adapted into or inform design of applications
|  |
|  +- here-oauth-client-example # Tutorial example for here-oauth-client JAR
|     |
|     +- src              # Source and test code
|        |
|        +- main          # Source code for the tutorial example
|
+- here-oauth-client-dist # Descriptions of how to build the .tar.gz distribution bundle

Functionality

The purpose of here-oauth-client JAR is to obtain authorization from the HERE OAuth2.0 Authorization Server, for use with HERE Services. See also https://tools.ietf.org/html/rfc6749.

The HERE Access Tokens obtained are provided as Authorization: Bearer values on requests to HERE Services. See also https://tools.ietf.org/html/rfc6750#section-2.1.

The here-oauth-client JAR includes

  • Authentication features for signing requests to the HERE OAuth2.0 Authorization Server. The client provides its provisioned id and secret to make authenticated requests via the OAuth1.0 authentication method.
  • Authorization features for obtaining HERE Access Tokens from the HERE OAuth2.0 Authorization Server, including the ability to automatically refresh HERE Access Tokens. Supported flows include OAuth2.0 client_credentials grant for confidential clients.
  • Authorization features for using OAuth2.0 Bearer HERE Access Token in the Authorization header for requests to HERE Services.
  • Accounting claims in the Access Tokens it uses. HERE Services extract signed Accounting claims from the Access Tokens.

For help, contact [email protected]. Built using Apache Maven (https://maven.apache.org/)

Development Setup

Prerequisites

  1. Requires Java 1.8.
  2. Requires Apache Maven 3.3.

Build instructions

Open a command prompt at the working tree's root directory and type:

$ mvn -DskipTests clean package

To build the package without testing it.

Test instructions

The tests must be configured with valid HERE client credentials to pass. To get HERE client credentials, please contact [email protected].

When you commit your code in GitHub it will be automatically tested with Github Workflows.

https://docs.github.com/en/actions/using-workflows

Open a command prompt at the working tree's root directory and type:

$ mvn clean package

Which will succeed if your client credentials file is at ~/.here/credentials.properties, and fail the test phase otherwise. Another way to get passing tests, or to override your ~/.here/credentials.properties, you can optionally use the command-line arguments.

Open a command prompt at the working tree's root directory and type:

$ mvn -DargLine='-DhereCredentialsFile=/path/to/your/creds' clean package

Substitute your /path/to/your/creds above, to achieve success.

Examples instructions

The examples directory contains a tutorial example. To run it

  1. Download and place your HERE Account authorization server credentials.properties file to ~/.here/credentials.properties.
 $ chmod 400 ~/.here/credentials.properties
 $ java -jar examples/here-oauth-client-example/target/here-oauth-client-example-*[!javadoc][!sources].jar

This tutorial uses the recommended "always fresh" approach with the default ClientAuthorizationProviderChain. The tutorial will obtain a valid HERE Access Token and print portions of it to stdout. If in a secure location, optionally re-run with

 $ java -jar examples/here-oauth-client-example/target/here-oauth-client-example-*[!javadoc][!sources].jar -v

to print a full valid HERE Access Token to stdout. You can also put the file in a different location or give it a different name, just supply the file as input to the executable jar command line. The examples are for tutorial purposes only and MUST NOT be used in your deployed application. You might find it useful to start from the main(..) method's sample code, and adapt the integration to your environment.

You can use the -idToken option to output the HERE Id Token (in Open ID format) instead of the HERE Access Token.

 $ java -cp examples/here-oauth-client-example/target/here-oauth-client-example-*[!javadoc][!sources].jar com.here.account.oauth2.tutorial.ClientCredentialsProgram -idToken

If in a secure location, optionally add the -v option to print a full valid Id Token to stdout.

 $ java -cp examples/here-oauth-client-example/target/here-oauth-client-example-*[!javadoc][!sources].jar com.here.account.oauth2.tutorial.ClientCredentialsProgram -idToken -v

Developer Usage

Read the javadocs for details and helpful code snippets (such as setting the HTTP connection pool size). The mvn commands above will create javadocs locally, which you can see at 'here-oauth-client/target/apidocs/index.html'.

If you are just getting started, go to com.here.account.oauth2.HereAccessTokenProvider javadocs for the overview of two options:

  • To get a supplier of HERE Access Tokens optimized for making repeated API calls to resource servers, use HereAccessTokenProvider.builder().build(); once followed by repeated calls to .getAccessToken();. This option is also recommended for long-running scenarios. In this default option, created Access Tokens are reused during their lifetime and automatically updated for you when needed.
  • To get a new HERE Access Token only once, or if you want to manage your own token expirations, use HereAccessTokenProvider.builder().setAlwaysRequestNewToken(true).build(); followed by calls to .getAccessToken();.

A third option is to get an id_token

  • get Id Token via com.here.account.oauth2.HereAccount's TokenEndpoint.requestToken(..) approach by setting the scope field in the request.

License

Copyright (C) 2016-2019 HERE Europe B.V.

See the LICENSE file in the root of this project for license details.

here-aaa-java-sdk's People

Contributors

andreaskoppbmw avatar davidwcarlson avatar dependabot[bot] avatar jusmaki avatar kenmccracken avatar martin-mfg avatar mohithapani avatar molekyla avatar owenkellett avatar plm57 avatar riccardogulia avatar rohangtr avatar salinden avatar spaltis avatar srrajago avatar sschuberth avatar ssiyengar avatar stwwalton avatar swetha-iyengar avatar tsteenbe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

here-aaa-java-sdk's Issues

library should make correlationId available in AccessTokenResponse.

From the OLP specs, X-Correlation-ID is returned to customer in response headers.
It is best if we make this value available to customers on the AccessTokenResponse object.
Suggested to follow a similar pattern to #63, but on the response side, to use a private transient String correlationId with setter/getter.

library doesn't log X-Correlation-ID values at log level fine()

As a developer, I want to see the X-Correlation-ID logged when I configure my logging to include fine("messages").
Currently, the X-Correlation-ID header is not loggable with the response, unless I inject my own HTTP Provider.

Acceptance criteria:

The X-Correlation-ID is logged via something like

LOGGER.fine("X-Correlation-ID: {}", xCorrelationId);

Note that the headers are not currently exposed in the HttpResponse, so you'll need to add that as well.

Issue with the Android SDK

Hi

I was using AAA SDK to get the access token but I still can't get it. I get a crash saying the following error

java.lang.NoSuchFieldError: No static field INSTANCE of type Lorg/apache/http/conn/ssl/AllowAllHostnameVerifier; in class Lorg/apache/http/conn/ssl/AllowAllHostnameVerifier; or its superclasses (declaration of 'org.apache.http.conn.ssl.AllowAllHostnameVerifier' appears in /system/framework/framework.jar!classes4.dex)

According to this Android has deprecated the Apache module since API level 22 so any workaround for this or anything

The tool used
Android Studio 4.1.1
Language Used Java

[SignatureCalculator.constructAuthHeader()] Should nonce be URL encoded?

Hi,

I have observed a pattern regarding success or failure of the authorization request depending on whether the nonce was URL encoded while containing special characters. Removing the urlEncode() call seems to make all requests succeed.

Here are a couple examples to illustrate:

Successes

headerValue=OAuth oauth_consumer_key="***", oauth_signature_method="HMAC-SHA256", oauth_signature="wrlkVTMc%2F68A1asrCNlWNRPYzbpsQCrtrmrYYeBG7kk%3D", oauth_timestamp="1549652196", oauth_nonce="f1lpHr", oauth_version="1.0"

headerValue=OAuth oauth_consumer_key="***", oauth_signature_method="HMAC-SHA256", oauth_signature="Sl%2FECnifUqQQQJSkjrzhNxuZYfJGnepqXBAxxC4TwcI%3D", oauth_timestamp="1549652201", oauth_nonce="lrCx33", oauth_version="1.0"

headerValue=OAuth oauth_consumer_key="***", oauth_signature_method="HMAC-SHA256", oauth_signature="v%2Bz20gofBYj7UXXE1rAKjXLGZFkxsQWPiDwBCWCdkaI%3D", oauth_timestamp="1549653242", oauth_nonce="G8mmeS", oauth_version="1.0"

Failures

headerValue=OAuth oauth_consumer_key="***", oauth_signature_method="HMAC-SHA256", oauth_signature="4ia8%2Fsm1luNP2hXVxzl34%2BiGOkOQSkwmFC1GlQgW75w%3D", oauth_timestamp="1549653142", oauth_nonce="vH2Z%2FH", oauth_version="1.0"

headerValue=OAuth oauth_consumer_key="***", oauth_signature_method="HMAC-SHA256", oauth_signature="01j%2B85U77ehTBcDxd0OUTpfekIXjtfmzQX8YCvp12wU%3D", oauth_timestamp="1549653244", oauth_nonce="V%2FK6kl", oauth_version="1.0"

headerValue=OAuth oauth_consumer_key="***", oauth_signature_method="HMAC-SHA256", oauth_signature="UwULcKgLyzD0VpDZIChQE8R5kVycTNz0bWQI%2Fdn71iU%3D", oauth_timestamp="1549653304", oauth_nonce="A%2Bp5oH", oauth_version="1.0"

I haven't investigated too deep into the issue but removing the urlEncode(nonce) and only appending nonce as-is seems to lead a 100% success rate, even with oauth_nonce="7g+/D1" or oauth_nonce="Zs/a9h".

Please feel free to check the hypothesis a bit further.

Thanks,

Boris

Client.Builder class should use reasonable defaults, or fail-fast

Currently, the Client.Builder() class allows you to construct an instance without specifying, for example, a Serializer. The result is you get what appears to be a valid Client, but later when you send requests, they fail at the serialization step with a NullPointerException.

A Client instance that can be constructed, but cannot be used, is rather of pointless.

The solution should either

  1. Have the Client.Builder use reasonable defaults, such as apache HttpProvider, NoAuthorizer, and JacksonSerializer, when no override was specified.
  2. Have the Client.Builder.build() method validate not null with assertions that fail-fast and a clear null indicator.

Any interest in making it Android friendly?

Hi team,

I'm trying to use this library in an Android project with minSdkVersion 24. Here is a quick recap of the problems I face:

First, in order to avoid build issues with Apache httpcomponents, I had to exclude things as follow:
implementation('com.here.account:here-oauth-client:0.4.16') {
exclude group: 'org.apache.httpcomponents', module: 'httpclient'
}
And then I ended up using the pure JavaHttpProvider. I naively ran some unit tests and the authentication went through.
Then, I ran an instrumentation test and hit the wall mentioned above. Indeed, the library uses java.util.Base64 while Android only provides android.util.Base64, leading to the runtime issue: java.lang.NoClassDefFoundError: Failed resolution of: Ljava/util/Base64. I have found it in OAuth1Signer and SignatureCalculator.

My current workaround to get going is to copy those classes and make the small one-line changes to have them work with Android. I now use the Apache Base64 implementation in module 'commons-codec:commons-codec:1.10'.

I now have class AndroidOAuth1Signer.java:

import org.apache.commons.codec.binary.Base64;
.
.
String nonce = new String(Base64.encodeBase64(bytes)).substring(0, NONCE_LENGTH);

And class AndroidSignatureCalculator.java:

import org.apache.commons.codec.binary.Base64;
.
.
byte[] keyBytes = Base64.decodeBase64(key);
.
.
return new String(Base64.encodeBase64(signedBytes));
.
.
Plus a few more replacements

So I'm using those two classes above via third class ClientAuthorizationRequestProviderFromAndroidProperties.java:

package com.here.account.android;

import com.here.account.auth.OAuth1ClientCredentialsProvider;
import com.here.account.auth.provider.FromProperties;
import com.here.account.http.HttpProvider;
import com.here.account.util.SettableSystemClock;

import java.util.Properties;

/**
 * ClientAuthorizationRequestProviderFromAndroidProperties is the class allowing HERE AAA from given
 * properties.
 *
 * It does override getClientAuthorizer() in order to use classes
 * like AndroidOAuth1Signer and AndroidSignatureCalculator specifically modified for Android usage.
 *
 * @author guenebau
 * @since 1.0.0
 */
public class ClientAuthorizationRequestProviderFromAndroidProperties extends FromProperties {
    /**
     * The OAuth 1 signer created from properties.
     */
    private final AndroidOAuth1Signer mOAuth1Signer;

    /**
     * Class constructor.
     *
     * @param properties the properties containing credentials related values.
     */
    public ClientAuthorizationRequestProviderFromAndroidProperties(Properties properties) {
        super(new SettableSystemClock(), properties);
        mOAuth1Signer = new AndroidOAuth1Signer(
                getClock(),
                properties.getProperty(OAuth1ClientCredentialsProvider.FromProperties.ACCESS_KEY_ID_PROPERTY),
                properties.getProperty(OAuth1ClientCredentialsProvider.FromProperties.ACCESS_KEY_SECRET_PROPERTY));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public HttpProvider.HttpRequestAuthorizer getClientAuthorizer() {
        return mOAuth1Signer;
    }
}

It does work well and I can get authorization from HERE Account.

So please let me know if there is any Android friendly direction you would like to explore.

Thanks,

Boris

Add a configurable RetryPolicy to the HereAccessTokenProvider, that by default retries socket and 5xx errors with backoff

Add a configurable RetryPolicy to the HereAccessTokenProvider, that by default retries socket and 5xx errors up to 2x with backoff.

This would allow, particularly when using HereAccessTokenProvider.Builder.setAlwaysRequestNewToken(true), some additional client-side resilience to network hiccups or expected low-probability failures server-side.

The DefaultRetryPolicy can then be chosen from java.util.Random using exponential random backoff starting with [0,200] ms, with up to 3 max attempts. Or, other suitable alternative.

FileAccessTokenResponse, when constructed over time for a fixed file access token, must have correctly increasing getStartTimeMilliseconds() and decreasing getExpiresIn()

currently, if you create a FileAccessTokenResponse for an access_token response that is valid for an hour, and read from that file using HereAccessTokenProvider over time, the getStartTimeMilliseconds() does not increase, and the getExpiresIn() does not decrease with each new instance.


The behavior of FileAccessTokenResponse must be as follows. From the time the file is read, getExpiresIn() should represent how much time is left on the access_token.

The fix must have for 2 instances of the FileAccessTokenResponse constructed from the same file contents, but N seconds apart, a getStartTimeMilliseconds() that is ~N*1000 larger in the second one and a getExpiresIn() that is ~N smaller in the second one.

OAuth1 signature is not calculated correctly with query parameters in URL.

The OAuth1 signature is not calculated correctly if query parameters are included in the request URL.
For example for request like GET http://example.com/some/path?key1=value1 the key1=value should be included in the OAuth1 sorted signature base string. Now those are just included as part of the URL and thus the OAuth1 signature is wrongly calculated.

Apparently the OAuth1Signer class does not extract query parameters from URL and use those to calculate the OAuth1 signature as specified in the RFC-5849. The SignatureCalculator calculateSignature method has support for the query parameters, but those are currently passed as null in the OAuth1Signer class.

Also some characters like '*' and '~' are not correctly encoded when adding those to the signature base string.

Wrong version on README.md

The README.md is always one version ahead of the actual published version of the here-aaa-java-sdk.
The readme states to use:
<dependency> <groupId>com.here.account</groupId> <artifactId>here-oauth-client</artifactId> <version>0.4.23</version> </dependency>

But so far only version 0.4.22 is published.

Duplicate META-INF/DEPENDENCIES in Android

When we add your library from Maven (0.4.23) to our SDK it pulls in both Apache httpclient and httpcore.
This results in a duplicate META-INF/DEPENDENCIES resource:

Caused by: com.android.builder.merge.DuplicateRelativeFileException: 2 files found with path 'META-INF/DEPENDENCIES' from inputs:

+--- com.here.account:here-oauth-client:0.4.23|
+--- org.ini4j:ini4j:0.5.1|
+--- com.fasterxml.jackson.core:jackson-databind:2.10.0.pr1 -> 2.13.0 (*)|
--- org.apache.httpcomponents:httpclient:4.5.2|
+--- org.apache.httpcomponents:httpcore:4.4.4|
+--- commons-logging:commons-logging:1.2|
--- commons-codec:commons-codec:1.9

Which requires any app using our SDK to now have to add a packagingOptions to exclude it:
packagingOptions {
resources.excludes += "META-INF/DEPENDENCIES"
}

We think you should be excluding this duplicate resource as a packagingOptions section in your library build step.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.