Programmatic Access Specification

SMS Web Applications

Document Version: $Id: ProgrammaticAccessSpecification.html,v 1.14 2020/5/5 14:37:14 deh Exp $

Contents

1. Introduction

ISONE customers use programmatic access to SMD applications because, for some customers, their tasks are too overwhelming when done through the existing SMD UI, and must be automated to fit into some other process or GUI. SMD consists of web applications, which presents the opportunity to do programmatic access through a simple HTTPS client, as long as the client follows the correct authentication method and application protocol. (The application protocol is just the sequence of HTTPS URLs and their parameters).

ISONE wishes to lay out this authentication method and relevant application protocols as a specification so that customers can develop their own programmatic clients (or obtain them from third-party vendors). In addition, we will include whatever implementation notes or troubleshooting tips we have collected from our experience with these HTTPS clients. This document covers the SMS applications (IBTs, Meter Readings, Daily Tags). Please note that the SMS application protocols are currently based entirely on UI behavior, and are subject to change as new UI features are introduced. A separate protocol for programmatic clients would require a new project to develop it, and this project would have to be supported by the whole ISONE customer base.

2. Specification

2.1 Authentication method

The client must connect to ISONE's web server for SMD Applications (currently at smd.iso-ne.com) via HTTPS using authenticated SSL. The client must authenticate itself using a digital certificate issued by ISONE. The certificate must be currently valid, and must be authorized by ISONE to access the specific SMD applications requested.

Certificate holders are authorized on an application-by-application basis, so, for example, an individual certificate holder may be allowed to access https://smd.iso-ne.com/sms_oper_contract/main (IBTs) but not https://smd.iso-ne.com/sms_oper_metering/main (Meter Readings). The authorizations also depend on the SMD environment. For instance, SMD Sandbox (currently at sandboxsmd.iso-ne.com) can be accessed using the same clients, but could potentially have different authorizations from smd.iso-ne.com. There are other differences between these environments as well (such as server ID certificates), so the developer must always be certain about which environment his client is authenticating itself to.

The SSL protocols accepted by the ISONE SMD web server are SSLv3 and TLSv1. SSLv2 is not accepted. Both the client and server certificates contain RSA private keys, and therefore RSA authentication is always used (as opposed to DSA, for instance). The accepted cipher suites for encryption include are (in order of strength):

Cipher-Tag Key Exchange Encryption Mac Strength
EDH-RSA-DES-CBC3-SHA DH 3DES(168) SHA1 Strong
DES-CBC3-SHA RSA 3DES(168) SHA1 Strong
RC4-SHA RSA RC4(128) SHA1 Moderate
RC4-MD5 RSA RC4(128) MD5 Moderate
EDH-RSA-DES-CBC-SHA DH DES(56) SHA1 Moderate
DES-CBC-SHA RSA DES(56) SHA1 Moderate

2.2 Application protocols

One thing common to all the application protocols is that they use a session cookie provided by a server. The first HTTPS request in the protocol will come back with a "Set-Cookie" header in the response where the cookie name is "SMS_STL_SESSIONID". Subsequent HTTPS requests in the protocol must include this SMS_STL_SESSIONID cookie in their headers.

2.2.1 IBT

2.2.1.1 Login
Request URL: "https://smd.iso-ne.com/sms_oper_contract/main"
Request method: GET
Response code: 302
Response Location header: "https://smd.iso-ne.com/sms_oper_contract/contractMain.jsp"
Response Set-Cookie header: "SMS_STL_SESSIONID=<SMS_STL_SESSIONID>; Version=1;Path=/...; Comment="SMS Settlement Session Tracking Cookie";"
2.2.1.2 Upload
Must follow Login.

Request URL: "https://smd.iso-ne.com/sms_oper_contract/main"
Request method: POST
Request Cookie header: <SMS_STL_SESSIONID>
Request Content-Type header: "multipart/form-data; boundary=<boundary string>"
Request post data (with newlines):

--<boundary string>
Content-Disposition: form-data; name="file"; filename="<name of contract upload XML file>"
Content-Type: text/xml

<body of contract upload XML file>

--<boundary string>--
Response code: 200
Response data for successful upload contains:
...
<table>
  <tr><td><b>Files uploaded with Warnings:</b></td></tr>
    <ul>
      <tr><td><li><name of contract upload XML file></li></td></tr>
...
Warning Messages:
<textarea>
  <---Contract ID XXXXX
     Effective 1/1/2013, the final acceptance of  <name of contract type> Bilateral Contracts is subject to the financial assurance review provisions in Section III.B.3(e) of the ISO New England Financial Assurance Policy.>
Response data for unsuccessful upload contains:
...
<table>
  <tr><td><b>Files failed to upload:</b></td></tr>
    <ul>
      <tr><td><li><name of contract upload XML file></li></td></tr>
...
Error messages:
<textarea>
  <Error messages for user>
2.2.1.3 Download
Must follow Login.

Downloads XML containing contracts and schedules for contracts of a given contract type within a given date range. The contract types are based on values listed in the "Search For Existing Contract" screen of the IBT UI, and are currently:

The date range is specified via a start date and an end date, which may include year, month, and day, and are in the mm/dd/yyyy format. Note that additional URL encoding must be applied to these three values, as described in 5.6 URL encoded post data.
  1. Request URL: "https://smd.iso-ne.com/sms_oper_contract/main"
    Request method: POST
    Request Cookie header: <SMS_STL_SESSIONID>
    Request Content-Type header: "application/x-www-form-urlencoded"
    Request post data (without newlines):
    servlet_action=SEARCH_CONTRACT
    &contractIDField=
    &contractTypeCheck=contractTypeCheck
    &contractTypeSelect=<requested contract type>
    &refIDField=
    &marketButton=DAMarket
    &marketCheck: marketCheck
    &startDateCheck=startDateCheck
    &startDateField=<requested date range start date>
    &locationField=
    &location_type=
    &endDateCheck=endDateCheck
    &endDateField=<requested date range end date>
    &statusButton=PENDING_REQUESTOR
    &party_name=
    &partyField=
    &schedPatternButton= On-Peak+5x16
    &schedStatusButton=PENDING_REQUESTOR
    &scheduleField=
    &subaccountIdField=
    &asset_name=
    &assetField=
    &commitment_period_id_field=
    &resource_name=
    &resourceField=
    
    
    Response code: 200
    Response data contains:
    ...
    <a onClick="return(showContract(this, matching contract number));">
    ...
    

  2. Request URL: "https://smd.iso-ne.com/sms_oper_contract/main"
    Request method: POST
    Request Cookie header: <SMS_STL_SESSIONID>
    Request Content-Type header: "application/x-www-form-urlencoded"
    Request post data (without newlines):
    servlet_action=DOWNLOAD_FILE
    &fileContent=contractsAndSchedules
    &fileFormat=xml
    
    Response code: 200
    Response data is:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE Download_ContractsAndSchedules PUBLIC "-//ISO New England, Inc//DTD Contract and Schedules Download//EN"
                                                    "">
    <Download_ContractsAndSchedules>
      <Contract>
        ...
      </Contract>
      ...
    </Download_ContractsAndSchedules>
    

2.2.2 LFR Asset Assign

2.2.2.1 Login
Request URL: "https://smd.iso-ne.com/sms_oper_lfrassetassign/assetSelect"
Request method: GET
Response code: 200
Response Set-Cookie header: "SMS_STL_SESSIONID=<SMS_STL_SESSIONID>; Version=1;Path=/...; Comment="SMS Settlement Session Tracking Cookie";"
Response data contains:
...
<td class="lfr_title" align="center" width="450"><b>Forward  Reserve  Asset Assignment<b></td>
...
Lead Participant:</td>                          <td width="300" ><b>name of lead participant</b>
...
2.2.2.2 Upload
Must follow Login.

Request URL: "https://smd.iso-ne.com/sms_oper_lfrassetassign/fileUpload"
Request method: GET
Request Cookie header: <SMS_STL_SESSIONID>
Response data contains:

...
<div class="upload_frame">
 <form name="UploadForm" ....><input type="hidden" name="_csrf" value="token value">
...

Request URL: "https://smd.iso-ne.com/sms_oper_lfrassetassign/fileUpload/submit"
Request method: POST
Request Cookie header: <SMS_STL_SESSIONID>
Request Content-Type header: "multipart/form-data; boundary=<boundary string>"
Request post data (with new lines):

--<boundary string>
Content-Disposition: form-data; name="_csrf"

-<token value used from earlier GET /fileUpload response.>

--<boundary string>
Content-Disposition: form-data; name="browseFile"; filename="<name of lfr asset assignment upload XML file>"
Content-Type: text/xml

<body of lfr asset assignment upload XML file>

--<boundary string>
Content-Disposition: form-data; name="submitFile"

Submit
--<boundary string>
Content-Disposition: form-data; name="action"

FILEUPLOAD
--<boundary string>--
Response code: 200
Response data for successful upload contains:
...
<div class="upload_results_frame">
...
    <td colspan=2 valign=top>

      Successfully submitted.<br>
==============================<br>
<br>
Customer ID: <submitter's customer id><br>
Asset ID:    <asset id><br>
Reserve Zone ID: <reserve zone id><br>
Product Type:    <TMNSR|TMOR>  <br>
 Date: <assignment date>
<table border=0> 
<table of submitted data.>
...
<repeated for additional assets>
Response data for unsuccessful upload contains:
    <td valign=top>

     <center> Submission Failed, All records rejected: <br>
==============================<br>
<br>
Customer ID: <submitter's customer id><br>
Asset ID:    <asset id><br>
Reserve Zone ID: <reserve zone id><br>
Product Type:    <TMNSR|TMOR>  <br>
 Date: <assignment date>
<table border=0>
<table of submitted data.>
</table>
<Reason(s) for submission failure>
2.2.2.3 Download
Must follow Login.

Request URL: "https://smd.iso-ne.com/sms_oper_lfrassetassign/fileDownload?beginDate=yyyy-mm-dd&endDate=yyyy-mm-dd"
Request method: GET
Request Cookie header: <SMS_STL_SESSIONID>
Response code: 200
Content-Disposition: attachment;filename="asset_assignments.txt";
Response data contains:

   download file contents 

2.2.3 Forward Reserve Bidding

2.2.3.1 Login
Request URL: "https://smd.iso-ne.com/sms_oper_lfrbidding/biddingHome"
Request method: GET
Response code: 200
Response Set-Cookie header: "SMS_STL_SESSIONID=<SMS_STL_SESSIONID>; Version=1;Path=/...; Comment="SMS Settlement Session Tracking Cookie";"
Response data contains:
...
<td class="lfr_title" align="center" width="450"><b>Forward  Reserve  Bidding<b></td>
...
<input type="button" class="lfr_button" value="My Portfolio" width="50" onclick="javascript:setControllerMapping('myPortfolio')">
...
Participant:                              <b>name of  participant</b>
...
2.2.2.2 Upload
Must follow Login.

Request URL: "https://smd.iso-ne.com/sms_oper_lfrbidding/fileUpload"
Request method: GET
Request Cookie header: <SMS_STL_SESSIONID>
Response data contains:

...
<div class="upload_frame">
 <form name="UploadForm" ....><input type="hidden" name="_csrf" value="token value">
...

Request URL: "https://smd.iso-ne.com/sms_oper_lfrbidding/fileUpload/submit"
Request method: POST
Request Cookie header: <SMS_STL_SESSIONID>
Request Content-Type header: "multipart/form-data; boundary=<boundary string>"
Request post data (with new lines):

--<boundary string>
Content-Disposition: form-data; name="_csrf"

-<token value used from earlier GET /fileUpload response.>

--<boundary string>
Content-Disposition: form-data; name="browseFile"; filename="<name of lfr bidding upload XML file>"
Content-Type: text/xml

<body of lfr bidding upload XML file>

--<boundary string>
Content-Disposition: form-data; name="submitFile"

Submit
--<boundary string>
Content-Disposition: form-data; name="action"

FILEUPLOAD
--<boundary string>--
Response code: 200
Response data for successful upload contains:
...
<div class="upload_results_frame">
...
    <td colspan=2 valign=top>

      Successfully submitted.<br>
==============================<br>
<br>
Offer ID: <Unigue identifier for an Offer><br>
Customer ID: <submitter's customer id><br>
Auction Start Date: <Auction Begin date><br>
Auction   End Date: <Auction End date><br>
Reserve Zone ID: <reserve zone id><br>
Product Type: <TMNSR|TMOR><br>
<table border=0> 
<table of submitted data.>
...
<repeated for additional product types | reserve zones>
Response data for unsuccessful upload contains:
    <td valign=top>

     <center> Submission Failed: <br>
==============================<br>
<br>
Customer ID: <submitter's customer id><br>
Auction Start Date: <Auction Begin date><br>
Auction   End Date: <Auction End date><br>
Reserve Zone ID: <reserve zone id><br>
Product Type: <TMNSR|TMOR><br>
<table border=0>
<table of submitted data.>
</table>
<Reason(s) for submission failure>

3. Recommendations

3.1 Client certificate choice

The most appropriate certificate to use in authenticating to the ISONE web server depends on how the customer's HTTPS client program will be used. When the HTTPS client is executed as part of an interface with a live user (like a GUI front end) this certificate will probably be an individual employee's (e.g., "John Smith's Verisign Id"). When the HTTPS client is executed as part of an automated system unsupervised by a live user, this certificate should be one obtained for this purpose (e.g., "CMEEC Automated Download Verisign Id").

Because the SMS applications support the agent feature, where the client may specify the represented party after having authenticated, there is no need to use "third party" certificates that simulate an identity within another company. We recommend using a single certificate for all interactions with the SMS applications, and using the agent feature to select the company being represented. This makes certificate management easier and provides a tighter audit trail for all of your interactions with the SMS. CS&T can authorize your use of the SMS agent feature if you need to represent multiple companies.

3.2 Client certificate storage

It is important to protect client certificates as strongly as possible, because they represent your identity. Since your HTTPS client program must have access to a client certificate, certificate storage becomes an important management issue. Storage depends on how the HTTPS client program will be run.

In a totally automated system, the HTTPS client program should probably be only run as a privileged system user (like "root" on a Unix machine). The client certificate (including the private key) would be stored in a file on disk that's readable only by that privileged user. If your HTTPS client requires certificate files to be password-protected (like Sun's JSSE for the Java platform), the password should be kept in a file on disk with the same permissions. The HTTPS client program can then read the password from this file when it attempts to access the certificate file. The password should never be present in configuration files or passed on the command line.

In a GUI front end, the HTTPS client program should probably use a different method for obtaining the certificate, such as reading it from a user's key store in a default location and prompting the user for the password interactively. For the Java platform, for instance, your GUI could use Sun's JAAS API to initiate authentication with the user, depending on a JAAS authentication module that uses JSSE to access a private key in the user's Java Keystore.

4. Implementation notes

4.1 Java: JSSE and java.net

A Java HTTPS client based on Sun's JSSE will be adequate for accessing the SMS web applications. JSSE is an extension in J2SE 1.3, and standard in J2SE 1.4, therefore it's easiest to program the client for the J2SE 1.4 platform. JSSE provides SSL and the HTTPS implementation, but the program can be written solely against java.net APIs. The JSSE only has to be configured via system properties and on the CLASSPATH at runtime.

4.1.1 HTTPS

4.1.2 HTTPS credentials

4.1.3 HTTPS connection

The HTTPS URLs in the application protocol can then be accessed via java.net.URL.openConnection. Because the protocol handlers property includes the JSSE HTTPS implementation, an HTTPS URL will cause openConnection to return a com.sun.net.ssl.HttpsURLConnection.

5. FAQ/Troubleshooting

5.1 Client Certificate export

Many HTTPS client programs will require the certificate to be available as a standalone export file on disk, rather than in a browser key store. For instance, a JSSE-based Java client will require the certificate in a PKCS-12 file, which can be exported from the Netscape 4.x browser.

From Netscape 4.x, do the following to export your client certificate as a PKCS-12 file:

  1. Launch the Netscape Browser
  2. Click on the "padlock" icon in the toolbar or select the "Communicator->Tools->Security Info" command from the menubar
  3. On the sidebar click on the "Yours" item under "Certificates"
  4. Locate the VeriSign Client certificate used to authenticate to the SMD applications
  5. Click the "Export" button
  6. If the certificate has been renewed one or more times, select the most recent one and click the "Continue" button
  7. Provide a non-null password for the export file. Some HTTPS client implementations will depend on a password-protected file. And since the file contains a private key, it's important to limit its accessibility to others.
  8. Choose a location for the export file and complete the export, noting that location.

5.2 CA Certificate export

Your HTTPS client program will probably use some trust store to determine whether it trusts the server id certificate presented by ISONE's web server. The trust store will need to include the certificate for the CA who signed the ISONE server id certificate. The HTTPS client program's trust store may or may not already include that CA certificate. You may need to export that CA certificate into a temporary file to get it into your program's trust store. On MS Windows, you can use the Control Panels to create an export file for our current CA certificate ("Equifax Secure CA").

From the Windows desktop, do the following to export this CA certificate as a CER file:

  1. Start Menu->Settings->Control Panels
  2. Click on the "Internet Options" control panel
  3. Select the "Content" tab and click the "Certificates..." button
  4. Select the "Trusted Root Certification Authorities" tab
  5. Scroll down to "Equifax Secure Certificate Authority" and click to select
  6. Click the "Export..." button
  7. Click "Next >" through the "Certificate Manager Export Wizard" until you get to the "File to Export" screen.
  8. Choose a location like "c:\temp\equifax-secure-cert-auth" and complete the export. A CER file will be created, like "c:\temp\equifax-secure-cert-auth.cer".

5.3 CA certificate import

As explained above, different HTTPS client programs will have different ways of holding onto the trust store. In an HTTPS client program based on JSSE, you can use the JRE's default trust store of $JAVA_HOME/jre/lib/security/cacerts. The keytool utility provided with the JRE will allow you to import a CER file for the CA certificate into that trust store. The trust store's default password, set at JRE installation, is "changeit". The JSSE User's Guide explains more about the default keystore.

A command line like the following can be used to import the CA certificate into your JRE's default keystore:

keytool -import -alias "Equifax Secure Certificate Authority" \
        -file c:\temp\equifax-secure-cert-auth.cer \
        -keystore <JAVA_HOME>\jre\lib\security\cacerts
The command line will prompt for the password mentioned earlier, and you will have to answer "yes" to add the certificate to your trust store.

5.4 Establishing HTTPS connection

5.5 Setting headers

5.6 URL encoded post data

5.7 Multipart MIME post data