Use BBauth for Single Sign-On with Java

Yahoo! Browser Based Authentication (BBAuth) makes it possible for your applications to use data from millions of existing users (with their permission). BBAuth also offers a Single Sign-On (SSO) facility so that existing Yahoo! users can use your services without having to complete yet another registration process. In this HOWTO, we discuss and demonstrate BBAuth Single Sign-On (SSO) usage.

Get Your AppID and Secret

If you plan on developing applications using BBAuth, you'll need to register your application and obtain an Application ID and Shared Secret. To do that, go here:

Register your application on the Yahoo! Developer Network

You can view your Application IDs and Shared Secrets here:

Generate the BBauth Login URL

First, we will generate the initial authentication URL used for Yahoo! Browser Based Authentication. You typicallly display this URL to the user as the first step of the Browser Based Authentication process.

The current time is required to prevent stale requests.

// Get the current time. This is needed to sign the request.
long time = System.currentTimeMillis() / 1000;

Generate the portion of the URL that's used for signing.

String appData = "foobar";
String authWS = "/WSLogin/V1/wslogin";
String sig = authWS + "?appid=" + encode(appId) + "&appdata=" + encode(appData) + "&ts=" + time + secret;
String signature = MD5(sig);
String authURL = "" + authWS + "?appid=" + appId + "&appdata=" + appData + "&ts=" + time + "&sig=" + signature;

The auth URL is the location where a user verifies his or her Yahoo! credentials before being forwarded back to the endpoint URL specified when you registered your web application.


The source code for this example can be found in the file

Generate the WSSID and Authentication Cookie

The next example processes the data sent back to the endpoint URL after successful authentication to generate the subsequent request for a WSSID and auth cookie. Yahoo! appends the data required to continue the authentication process to the URL when it transfers control to your web application after the user authenticates. Once you have retrieved the authentication token and validated the response from Yahoo!, you have everything you need to retrieve the WSSID and Yahoo! cookie for subsequent calls to the SOAP or JSON-RPC endpoints.

Your endpoint URL will be the location of this application on your web server. In this case, the directory /BBAuth. So, your application endpoint URL would be:

The URI will be the pathname without the domain name:

String uri = "/BBAuth/YahooBBAuthServlet";

After the user authenticates, the appdata, ts, sig, and token parameters are returned to your application appended to the query string of your endpoint URL. So, they are available in the environment:

//Optional data set by you
String appdata = request.getParameter("appdata"); //Request time in the format of a Unix timestamp
String ts = request.getParameter("ts"); //Signature is the MD5 of the request URI including the querystring with the Secret appended
String requestsig = request.getParameter("sig"); //Authentication token
String token = request.getParameter("token");

We can ensure the validily of the signature sent to to the endpoint URL by recalculating the signature using known values. This is accomplished by taking the MD5 hash of the request URI including the querystring that was sent by Yahoo! and adding what we know is the correct secret.

MessageDigest digest = MessageDigest.getInstance("MD5");
String calcsig = uri + "?appid=" + appId + "&token=" + token + "&appdata=" + appdata + "&ts=" + ts + secret;
calcsig = new BigInteger(1,digest.digest((calcsig).getBytes())).toString(16); //Verify that the signature sent by Yahoo! matches the calculated signture
if (!calcsig.equals(requestsig)) {
out.println("Signature mismatch:<br>");

It is important to verify that our server time is within 10 minutes (600 seconds) of Yahoo!'s servers to handle stale requests.

long time = System.currentTimeMillis() / 1000;
long requesttime = Long.parseLong(ts);
long clockSkew = Math.abs(time-requesttime); if (clockSkew >= 600) //Request is outside the boundary

Now that the request has been verified, we can generate the authentication URL required to retrieve the WSSID and cookie values required for subsequent authenticated web service calls.

//Generate the portion of the URL that's used for signing.
String authWS = "/WSLogin/V1/wspwtoken_login";
String sig = authWS + "?appid=" + URLEncoder.encode(appId, "UTF-8") + "&token=" + URLEncoder.encode(token, "UTF-8") + "&ts=" + time + secret;
String signature = new BigInteger(1,digest.digest((sig).getBytes())).toString(16);
String authURL = "" + authWS + "?appid=" + appId + "&token=" + token + "&ts=" + time + "&sig=" + signature; //Retrieve the XML response to the auth request and parse it with an javax.xml.parsers.DocumentBuilderFactory
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(authURL);
InputStream rstream = null;
// Get the response body
rstream = method.getResponseBodyAsStream();
Document xmlresponse = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(rstream);

The wssid, cookie, and authentication timeout values can be saved for future API calls. Your application will need to re-authenticate when the timeout expires (3600 seconds which is 1 hour):

NodeList wssidResponse = xmlresponse.getElementsByTagName("WSSID");
NodeList cookieResponse = xmlresponse.getElementsByTagName("Cookie");
NodeList timeoutResponse = xmlresponse.getElementsByTagName("Timeout");
Node wssidNode = wssidResponse.item(0);
Node cookieNode = cookieResponse.item(0);
Node timeoutNode = timeoutResponse.item(0);
if (wssidNode != null) {
  out.println("BBauth authentication Successful");
  wssid = wssidNode.getTextContent();
  cookie = cookieNode.getTextContent();
  timeout = timeoutNode.getTextContent();
} else {
  String code = xmlresponse.getElementsByTagName("ErrorCode").item(0).getTextContent();
  String msg = xmlresponse.getElementsByTagName("ErrorDescription").item(0).getTextContent();
  out.println("BBAuth request failed with error code " + code + ", " + msg);

More BBAuth examples using Java can be found in the Yahoo Mail Web Service User Guide and API Reference

The source code for this example can be found in

Error Handling

A list of all BBAuth error codes can be found here:

If there is a problem serving your request, you will receive an XML response
with the error code and error description.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ErrorDescription>Invalid (missing) appid</ErrorDescription>

The following code can be used to retrieve and display the error code and error description:

String code = response.getElementsByTagName("ErrorCode").item(0).getTextContent();
String msg = response.getElementsByTagName("ErrorDescription").item(0).getTextContent();
System.out.println("BBAuth request failed with error code " + code + ", " + msg);

For More Information

For more information on using Java with Yahoo! Web Services APIs, see The Yahoo! Developer Network Java Developer Center.

Yahoo Forum Discussions