Mobile and OAuth

NYC.ID fully supports web-based and native mobile applications. To securely integrate your native mobile application ("app"), with NYC.ID, we recommend using OAuth 2.0. The following information assumes familiarity with the OAuth 2.0 RFC.

! IMPORTANT: Your NYC.ID Service Account MUST NOT be stored on mobile devices, since there is no way to securely embed it within your mobile application.

To integrate NYC.ID with your app, follow these steps:

  1. Configure your app to
    1. invoke the authorization service with the following required parameters:

      GET /account/api/oauth/authorize.htm

      Parameter Name Parameter Description
      response_type The OAuth 2.0 response type. This value must equal token.
      client_id Your application's NYC.ID Service Account username
      redirect_uri The URI that the user is sent to after completing the authorization process. The "redirect_uri" must be registered and have a domain name of doitt.nycnet, nyc.gov, nycid.nycnet, csc.nycnet, cloudapp.net, hpd.nycnet, nycgovparks.org, finance.nycnet, hpdnyc.org, cs.nycnet, gcomsoft.com, records.nycnet, dcas.nycnet, dhs.nycnet, redcapcloud.com, cityofnewyork.us, dynamics.com, dynamics365portals.us, getinfo.nyc, fdnycloud.org, microsoftonline.com, mkscloud.com, samaritan.com, ivalua.us, sbs.nycnet, communityneeds.nyc, ukrosoft.com.ua, appgeo.com, azurewebsites.net, or gigya.com. Please contact nycidintegration@doitt.nyc.gov to add your domain name to the list of valid domains.
      ! IMPORTANT: After a user authenticates, if the "client_id" is unknown, a HTTP 404 Not Found response is returned.
      ! IMPORTANT: After a user authenticates, if the "redirect_uri" is invalid, a HTTP 404 Not Found response is returned.
    2. read the access token or JSON Web Token (JWT), and user attributes from the redirect URI
      NOTE: The URI is separated from the first attribute by a hash (#). Parameters are separated by an ampersand (&). Parameter names and values are separated by an equals (=).
    3. securely store the access token
      ! IMPORTANT: The access token expiration is configurable within your application's NYC.ID Service Account. The default access token expiration is 12 hours.
    4. destroy the access token when the user logs out
  2. Configure your Resource Server to:
    1. accept access tokens from your mobile application
    2. invoke the Get OAuth User Web Service to validate the access tokens with the NYC.ID Authorization Server
    3. invoke NYC.ID Web Services using your application's NYC.ID Service Account

 

NYC.ID User Authentication using OAuth and SAML

This sequence diagram describes how your app can integrate with the NYC.ID IdP using OAuth 2.0. Note the following:

  • Your app must use an embedded web browser for authentication and account management.
  • NYC.ID protected resources (Web Services) cannot be accessed via OAuth 2.0; they must always be accessed via a NYC.ID Service Account.

Sequence Diagram: NYC.ID User Authentication

Sequence Diagram: NYC.ID User Authentication

Get OAuth User Web Service

Your application may use this service to get a JSON-formatted user.

GET /account/api/oauth/user.htm

Input

Header Name Header Description Optional/ Required
Authorization The access token returned by the authorization service (i.e., Authorization: Bearer ${accessToken}) Required
Parameter Name Parameter Description Optional/ Required
dateTime The current date and time formatted as a Java SimpleDateFormat pattern (MM/dd/yyyy HH:mm or M/d/yy HH:mm). Optional, unless your application's NYC.ID Service Account is configured to prevent replay attacks
userName Your application's NYC.ID Service Account username Required
signature The signature generated for this request. Refer to calculating the authentication signature Required

Output

Http Status (Code) Response Description
OK (200) JSON-formatted user
! IMPORTANT: A deactivated user will not be returned.
Indicates the access token is valid and not expired
BAD REQUEST (400) Refer to Bad Request Status table below Indicates there was an error in the http request
UNAUTHORIZED (401) Refer to Unauthorized Status table below Indicates there was an error in the http request related to authentication
INTERNAL SERVER ERROR (500) Refer to Internal Server Error Status table below Indicates there was an error while processing the http request
SERVICE UNAVAILABLE (503) Not Applicable Indicates the server is undergoing maintenance and is temporarily unavailable

Bad Request Status

A bad request status indicates there was a problem with the http request. Each http response contains one or more error codes and messages. Refer to the table below for descriptions.

Here is a sample error:

{"ERRORS":{"accessToken":"required","userName":"required","signature":"invalid"}}
Code Message Description
accessToken required "accessToken" was required.
cpui.oauth.unknownOauthAccessToken Unknown Access Token: <accessToken> "accessToken" was not found within NYC.ID or was expired.
cpui.oauth.invalidOauthAccessTokenScope Invalid Access Token Scope: <accessToken> "accessToken" was created for a different NYC.ID Service Account.
userName invalid "userName" was not provided or was invalid.
signature invalid "signature" was not provided or was not in the required format.

Unauthorized Status

An unauthorized status indicates there was a problem with the http request related to authentication. Each http response contains one or more error codes and messages. Refer to the table below for descriptions.

Here is a sample error:

{"ERRORS":{"cpui.failedToAuthenticate":"The combination of userName and signature is incorrect."}}
Code Message Description
cpui.invalidDomainName Invalid Domain Name: <domainName>. Valid Domains: [[an error occurred while processing this directive]] The referrer domain name was invalid.
cpui.failedToAuthenticate The combination of userName and signature is incorrect. Authentication failed. Either "userName" or "signature" was incorrect or "dateTime", if provided, differs by more than 15 minutes from the current date and time.

Internal Server Error Status

An internal server error status indicates there was a problem while processing the http request. Each http response contains one or more error codes and messages. Refer to the table below for descriptions.

Code Message Description
cpui.exception This value is dynamically computed based on the cause of the error. For those that are curious, it's the output of the getMessage() method of the java.lang.Exception class. Indicates an unknown error occurred while processing the request

Delete OAuth User Web Service

Your application may use this service to revoke an access token.

DELETE /account/api/oauth/user.htm

! IMPORTANT: When integrating OAuth within a Web application, you must destroy the user's IdP session after revoking the user's access token. Learn how to perform an IdP Logout.
! IMPORTANT: After a user changes his or her password via Forgot Password, all active access tokens for the user are revoked.

Input

Header Name Header Description Optional/ Required
Authorization The access token returned by the authorization service (i.e., Authorization: Bearer ${accessToken}) Required
Parameter Name Parameter Description Optional/ Required
dateTime The current date and time formatted as a Java SimpleDateFormat pattern (MM/dd/yyyy HH:mm or M/d/yy HH:mm). Optional, unless your application's NYC.ID Service Account is configured to prevent replay attacks
userName Your application's NYC.ID Service Account username Required
signature The signature generated for this request. Refer to calculating the authentication signature Required

Output

Http Status (Code) Response Description
OK (200) Indicates the access token was revoked
BAD REQUEST (400) Refer to Bad Request Status table below Indicates there was an error in the http request
UNAUTHORIZED (401) Refer to Unauthorized Status table below Indicates there was an error in the http request related to authentication
INTERNAL SERVER ERROR (500) Refer to Internal Server Error Status table below Indicates there was an error while processing the http request

Bad Request Status

A bad request status indicates there was a problem with the http request. Each http response contains one or more error codes and messages. Refer to the table below for descriptions.

Here is a sample error:

{"ERRORS":{"accessToken":"required","userName":"required","signature":"invalid"}}
Code Message Description
accessToken required "accessToken" was required.
cpui.oauth.unknownOauthAccessToken Unknown Access Token: <accessToken> "accessToken" was not found within NYC.ID or was expired.
cpui.oauth.invalidOauthAccessTokenScope Invalid Access Token Scope: <accessToken> "accessToken" was created for a different NYC.ID Service Account.
userName invalid "userName" was not provided or was invalid.
signature invalid "signature" was not provided or was not in the required format.

Unauthorized Status

An unauthorized status indicates there was a problem with the http request related to authentication. Each http response contains one or more error codes and messages. Refer to the table below for descriptions.

Here is a sample error:

{"ERRORS":{"cpui.failedToAuthenticate":"The combination of userName and signature is incorrect."}}
Code Message Description
cpui.invalidDomainName Invalid Domain Name: <domainName>. Valid Domains: [[an error occurred while processing this directive]] The referrer domain name was invalid.
cpui.failedToAuthenticate The combination of userName and signature is incorrect. Authentication failed. Either "userName" or "signature" was incorrect or "dateTime", if provided, differs by more than 15 minutes from the current date and time.

Internal Server Error Status

An internal server error status indicates there was a problem while processing the http request. Each http response contains one or more error codes and messages. Refer to the table below for descriptions.

Code Message Description
cpui.exception This value is dynamically computed based on the cause of the error. For those that are curious, it's the output of the getMessage() method of the java.lang.Exception class. Indicates an unknown error occurred while processing the request