Java login issue (while posting to login url)

Added by Ismo over 7 years ago

Hi,

I am having problem with posting Get to login url from Java. I have attached below source code
(it also includes RSA encryption for login & password but those can be ignored so far as I am
having problems in https get posting).

Problematic part: gotString = doGet(url2); fails to HTTP error 401 (authentication failure).
Any idea why it fails?

Br,
Ismo

package nordnetapitest;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Date;
import sun.misc.BASE64Encoder;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import com.sun.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class NextTest {

    public static void main(String[] args) {        
        System.out.println("main()");
        login();        
    }

    private static void login() {

        // login and password in base64
        String loginAsBase64 = new BASE64Encoder().encode("login".getBytes()); 
        String passwordAsBase64 = new BASE64Encoder().encode("password".getBytes());             

        // timestamp
        Date date=new Date();     
        long timeInMilliseconds = date.getTime();          
        String timeAsString =  "" + timeInMilliseconds;
        System.out.println("Timestamp=" + timeAsString);
        String phraseAsBase64 = new BASE64Encoder().encode(timeAsString.getBytes());

        // login message
        String msg = loginAsBase64+':'+passwordAsBase64+':'+phraseAsBase64;
        System.out.println("Message (Base64)=" + msg);

        Cipher c = null;
        try {            
            // Load public key (from .der file)
            Key pubKey = loadPublicKey("D:\\nordnet\\NEXTAPI_TEST_public.der");

            // Get an instance of the Cipher for RSA encryption, use padding as otherwise data 
            // to be encrypted would need to be of right size             
            c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            c.init(Cipher.ENCRYPT_MODE, pubKey);        

            // RSA encrypt
            byte[] ciphertext = c.doFinal(msg.getBytes());                                                     
            String encodedInBase64 = new BASE64Encoder().encode(ciphertext);
            System.out.println("Encoded base64 message=" + encodedInBase64);        

            String URL = "api.test.nordnet.se";
            String BASE_URL ="api.test.nordnet.se/next";
            String API_VERSION = "1";

            System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
            java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

            // Do get to site url (this works)
            String url = new String("https://"+URL);
            String gotString = doGet(url);
            System.out.println("Output=" + gotString);

            // Do get to login url (this fails to HTTP response code 401)
            String url2 = new String("https://"+BASE_URL+"/"+API_VERSION+"/login");
            gotString = doGet(url2);
            System.out.println("Output2=" + gotString);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } 

    }

    private static Key loadPublicKey(String filename)
    {        
         try {                
                File file = new File(filename);
                FileInputStream fileInputStream = new FileInputStream(file);
                DataInputStream dataInputStream = new DataInputStream(fileInputStream);
                byte[] keyBytes = new byte[(int)file.length()];
                dataInputStream.readFully(keyBytes);
                dataInputStream.close();

                KeyFactory keyFact = KeyFactory.getInstance("RSA");
                return keyFact.generatePublic(new X509EncodedKeySpec(keyBytes));
              }
         catch(Exception e){
             e.printStackTrace();             
         }

         return null;
    }

    public static String doGet( String urlStr){
      HttpsURLConnection conn = null;
      try {
              conn = (HttpsURLConnection) new URL(urlStr).openConnection();                                 
              conn.setDoOutput(true);
              conn.setUseCaches(false);

              InputStream inStream = conn.getInputStream();
              BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inStream));
              String line = "";
              StringBuffer stringBuffer = new StringBuffer();
              while ((line=bufferedReader.readLine()) != null){
                stringBuffer.append(line + "\n");
              }
              bufferedReader.close();
              return stringBuffer.toString();

          } catch (IOException e) {
                  e.printStackTrace();
          } finally {
                  if(conn != null ) conn.disconnect();
          }
          return null;
    }       

}

Replies (2)

RE: Java login issue (while posting to login url) - Added by Ismo over 7 years ago

The beginning part of error message is

*
java.io.IOException: Server returned HTTP response code: 401 for URL: https://api.test.nordnet.se/next/1/login
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl.getInputStream(Unknown Source) *

And failure happens in line InputStream inStream = conn.getInputStream(); of function doGet.

RE: Java login issue (while posting to login url) - Added by Nordnet Tommi over 7 years ago

Try setting the request method to POST instead. The HttpUrlConnection  seems to default to GET and that is not valid for the Rest login.

(1-2/2)