Forum Discussion

awitt's avatar
awitt
Guide
10 years ago

Unable to Authenticate - 401 Unauthorized

I've got two users, one an SSO user and one a non-SSO user.  The SSO user was created via our community page, and the non-SSO user created via the Lithium admin page.  Both are meant to be used for API calls.

 

We don't have the SSO token, unfortunately, since the person who has that is out right now, so we created the non-SSO user to get around that requirement.  Both of these users are granted API privileges as detailed at http://community.lithium.com/t5/Developers-Knowledge-Base/Subscribing-to-community-events-using-the-REST-API/ta-p/14785.  However, before I can even try to subscribe to a community event, I must log in the API user and get an auth token (http://community.lithium.com/t5/Community-API/bd-p/developers-rest-api?page=authentication).

 

To do that, I created a simple Java app that uses the standard HttpURLConnection method of making REST calls.  I've tried to make POST calls to http://community.stage.company.com/restapi/vc/authentication/sessions/login/ with user.login and user.password suppiled as both query string parameters and request properties (in separate requests, of course).  Either method very quickly returns a 401 Unauthorized response.  Even if I change the credentials, using either method, to invalid ones, I get the same 401 response.  I'd expect to get a 302 or some such error, but no matter what I do, I get a 401 when I hit that URL.

 

I've checked numerous times with the community manager, and he's certain he's applied appropriate priviliges to the API accounts.  Here's my simple code for trying to authenticate a non-SSO user.  I just want to get an auth token back so that I can then make event subscription REST calls.

 

package lithium;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class LithiumRestClient {

	static String apiUsername = "communityapi2";
	static String apiPassword = "*************";

	public static void main(String[] args) throws Exception {

		String url = "http://community.stage.company.com/restapi/vc/authentication/sessions/login/"
				+ "?user.login="
				+ apiUsername
				+ "&user.password="
				+ apiPassword;

		LithiumRestClient client = new LithiumRestClient();
		client.sendPost(url);
	}

	// HTTP POST request
	private void sendPost(String url) throws Exception {

		URL obj = new URL(url);
		HttpURLConnection con = (HttpURLConnection) obj.openConnection();

		con.setRequestMethod("POST");
		// con.setRequestProperty("user.login", apiUsername);
		// con.setRequestProperty("user.password", apiPassword);

		// Send post request
		con.setDoOutput(true);

		int responseCode = con.getResponseCode();
		System.out.println("\nSending 'POST' request to URL : " + url);
		System.out.println("Response Code : " + responseCode);
		System.out.println(con.getResponseMessage());
		
		BufferedReader in = new BufferedReader(new InputStreamReader(
				con.getInputStream()));
		String inputLine;
		StringBuffer response = new StringBuffer();

		while ((inputLine = in.readLine()) != null) {
			response.append(inputLine);
		}

		in.close();

		// print result
		System.out.println(response.toString());
	}
}

 Is the user perhaps set up incorrectly then?  Am I making the request incorrectly?  Any help would be greatly appreciated, thanks.

 

One thing I've noticed is that if I paste the same URL I'm using in my code into the browser and supply the user.login and user.password parameters in the query string, I actually get a success message and token back.  Likewise, if I provide incorrect credentials using this method, I get a 302 Authentication Failed response.  So, this tells me that I should be performing a GET for this request, but even when I do that, I nonetheless get that same 401 response via code.

  • The first thing I noticed is that you're making the call to the staging community, but you have not specified a basic authentication header.

     

    Most staging communities have basic authentication turned on by default. You see this in the browser when you first navigate to the site, and you get a little username/password pop-up. Browsers cache the username and password you specify, but when making calls via Java you will need to make sure that you include the appropriate header with every request.

     

    You'll need something like this (from this example):

    	// HTTP POST request
    	private void sendPost(String url) throws Exception {
    
    		URL obj = new URL(url);
    		HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    		String encoded = Base64.encode("username:password");
    		con.setRequestProperty("Authorization", "Basic "+encoded);
    
    		con.setRequestMethod("POST");
    		// con.setRequestProperty("user.login", apiUsername);
    		// con.setRequestProperty("user.password", apiPassword);
    
    		...
    	}

     

  • The first thing I noticed is that you're making the call to the staging community, but you have not specified a basic authentication header.

     

    Most staging communities have basic authentication turned on by default. You see this in the browser when you first navigate to the site, and you get a little username/password pop-up. Browsers cache the username and password you specify, but when making calls via Java you will need to make sure that you include the appropriate header with every request.

     

    You'll need something like this (from this example):

    	// HTTP POST request
    	private void sendPost(String url) throws Exception {
    
    		URL obj = new URL(url);
    		HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    		String encoded = Base64.encode("username:password");
    		con.setRequestProperty("Authorization", "Basic "+encoded);
    
    		con.setRequestMethod("POST");
    		// con.setRequestProperty("user.login", apiUsername);
    		// con.setRequestProperty("user.password", apiPassword);
    
    		...
    	}

     

    • awitt's avatar
      awitt
      Guide

      Well I feel like a doofus, that's exactly what was happening.  Thanks, nathan!