Skip to content

WISPr Captive Portal Login Integration

This section describes how external applications can integrate with the HSG (HotSpot Gateway) captive portal using the WISPr (Wireless Internet Service Provider roaming) protocol to perform automated user authentication.

Overview

The WISPr login flow consists of three stages:

  1. The client app sends an HTTP probe request to trigger a captive portal redirect
  2. HSG responds with a WISPr XML payload containing the LoginURL
  3. The client app submits credentials to the LoginURL and follows redirects until authentication succeeds or fails

Step 1 — Trigger the Captive Portal

Send an HTTP GET request to any domain that is not whitelisted in HSG. The request must use plain HTTP to avoid TLS/HSTS complications.

GET / HTTP/1.1
Host: www.time.com

Recommended probe URL: http://neverssl.com

Sites with HSTS enabled will never work as probe targets because the browser/client will refuse to follow the HTTP redirect to the captive portal.


Step 2 — Parse the HSG WISPr Response

HSG replies with an HTTP redirect. The response body contains a WISPr XML block embedded in an HTML comment:

HTTP/1.1 302 Found
Location: https://splash.ransnet.com/pid/ransnet/login.php?res=notyet&uamip=192.168.80.1&uamport=5234...
Content-Type: text/html; charset=UTF-8
Content-Length: 868
Connection: close
<HTML><BODY><H2>Browser error!</H2>Browser does not support redirects!</BODY>
<!--
<?xml version="1.0" encoding="UTF-8"?>
<WISPAccessGatewayParam
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="http://www.wballiance.net/wispr_2_0.xsd">
  <Redirect>
    <MessageType>100</MessageType>
    <ResponseCode>0</ResponseCode>
    <VersionHigh>2.0</VersionHigh>
    <VersionLow>1.0</VersionLow>
    <AccessProcedure>1.0</AccessProcedure>
    <AccessLocation>CDATA[[isocc=,cc=,ac=,network=Coova,]]</AccessLocation>
    <LocationName>CDATA[[My_HotSpot]]</LocationName>
    <LoginURL>https://splash.ransnet.com/pid/ransnet/login.php?res=wispr&amp;uamip=192.168.80.1&amp;uamport=5234&amp;challenge=...</LoginURL>
    <AbortLoginURL>https://splash.ransnet.com:5234/abort</AbortLoginURL>
    <EAPMsg>AQEABQE=</EAPMsg>
  </Redirect>
</WISPAccessGatewayParam>
-->
</HTML>

Key fields

Field Description
LoginURL The URL to submit credentials to. Always extract from the XML — it varies by location.
uamip IP address of the hotspot server (e.g. 192.168.80.1)
uamport Port of the hotspot server (e.g. 5234)
challenge Random hex string generated by the hotspot server, used in the login request
AbortLoginURL URL to cancel the login attempt

Important: LoginURL is XML-encoded. Decode XML entities before use (e.g. &amp;&).


Step 3 — Submit Credentials

Using the decoded LoginURL, submit the user's credentials via either POST or GET.

POST method

POST <LoginURL>
Content-Type: application/x-www-form-urlencoded

UserName=<username>&Password=<password>

Both UserName/Password (standard) and username/password (non-standard) field names are accepted.

GET method

Append credentials as query parameters to the LoginURL:

https://splash.ransnet.com/pid/ransnet/login.php?res=wispr&uamip=192.168.80.1&uamport=5234&challenge=a63361d633eeeb4131001989dd37484d&UserName=test&Password=test123

Both UserName/Password (standard) and username/password (non-standard) parameter names are accepted.

HSG validates the credentials against its local or external RADIUS database and returns a WISPr authentication reply.

App owner credential variant

In addition to the standard UserName/Password pair, application owners may submit an alternative credential set that delegates authentication to the owning application. This uses a signed hash in place of the plaintext password.

Parameter Description
username The end-user's username, it must be email format
app Identifier of the application owner submitting the request, it is "tkg" for sportshub application
password Base64-encoded authentication token (md5 checksum of "##$username##")

Note: Full parameter specification and hash construction details for this variant will be documented once finalised.


Authentication Redirect Flow

After credential submission, follow the LoginResultsURL from each WISPr reply until res=success or res=failed is returned. Multiple redirects are normal before reaching a final result.

Redirect from login portal (ResponseCode 201)

<WISPAccessGatewayParam
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="http://www.acmewisp.com/WISPAccessGatewayParam.xsd">
  <AuthenticationReply>
    <MessageType>120</MessageType>
    <ResponseCode>201</ResponseCode>
    <LoginResultsURL>http://172.21.40.254:4070/www/externv2.chi?res=wispr&uamip=172.21.40.254&uamport=4070&challenge=0fcd2aca0c0cb94a57b3d169769bf318&called=00-60-E0-65-50-5C&mac=E4-A4-71-B4-9F-0B&ip=172.21.40.2&nasid=RansNet_HSG-Primary_vlan25_50-5c&sessionid=5dad72e500000002&userurl=http%3a%2f%2fyahoo.com%2f&ch=JJe1DOhCBt%2fQVsStE3BSK0o08XIjGmImIusRmzIL1xc%3d&md=CD0EB8D1FB5E489C1FC440BFF7F551F8</LoginResultsURL>
  </AuthenticationReply>
</WISPAccessGatewayParam>

Redirect from hotspot engine before RADIUS authentication (ResponseCode 201)

<WISPAccessGatewayParam
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="http://www.acmewisp.com/WISPAccessGatewayParam.xsd">
  <AuthenticationReply>
    <MessageType>120</MessageType>
    <ResponseCode>201</ResponseCode>
    <LoginResultsURL>http://172.21.40.254:4070/login?username=test&amp;password=c3b5a9e87701a002&amp;userurl=http%3A%2F%2Fmboxstatus.net</LoginResultsURL>
  </AuthenticationReply>
</WISPAccessGatewayParam>

Response codes

ResponseCode Meaning
0 Initial redirect (from Step 2)
201 Redirecting — follow LoginResultsURL
50 Authentication success (res=success)
100 Authentication failure (res=failed)

When res=success is received, notify the user that authentication was successful and internet access has been granted.


Implementation Notes

  • Always use HTTP (not HTTPS) for the initial probe request
  • Parse the WISPr XML from within the HTML comment block of the response body
  • XML-decode LoginURL before constructing the credential submission request
  • Follow all LoginResultsURL redirects in sequence; do not stop at the first 201 response
  • Do not assume a fixed LoginURL — it changes per hotspot location and session