javaauthenticationsiteminder

Post to Siteminder login.fcc to retrieve a cookie using java


My application needs to access some SiteMinder protected URLs and therefore need the SMSession cookie provided by the Siteminder agent.

I want to acquire a SMSession cookie by posting my login credentials to the Siteminder login form.

I tried many different ways to access and post the needed data (target, smauthreason, smagentname, username, password) to the login.fcc. I can post it like this in Postman / Fiddler and retrieve a cookie.

try {
        URL requestURL = new URL("HTTPS_URL_TO_THE/login-captcha.fcc");
        HttpsURLConnection conn = (HttpsURLConnection) requestURL.openConnection();
        conn.setDoOutput(true);
        //conn.setDoInput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Host", "HOST_FROM_ABOVE");
        conn.setRequestProperty("Connection", "keep-alive");
        conn.setRequestProperty("Content-Length","" + createBody().getBytes().length);
        conn.setRequestProperty("Cache-Control", "max-age=0");
        conn.setRequestProperty("Origin", "ORIGIN_HOST_FROM_WHERE_POSTED");
        conn.setRequestProperty("Upgrade-Insecure-Requests", "1");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");
        conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
        conn.setRequestProperty("DNT", "1");
        conn.setRequestProperty("Referer", "REFERER_TAKEN_FROM_FIDDLER");
        conn.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
        conn.setRequestProperty("Accept-Language", "de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7");


        OutputStream os = conn.getOutputStream();
        os.write(createBody().getBytes());

        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));               
        String in;
        while ((in = br.readLine()) != null){
            System.out.println(in);
        }

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

I will get a connection and can access the page when I provide the cookie before. But in this step I want to retrieve the cookie.

The body-data is 100% correct. The headers used in the example above are not all needed. And this was my last desperate try posting exactly the same as shown in fiddler. But I won't get a login or the 302 HTTP redirect.

Why doesn't it work? Any suggestions?


Solution

  • I got the solution for my issue. In fact I will have to handle the redirect manually. If I follow the redirect automatically the retrieved cookie will not be send with the next request. Posting to the targetURL without the cookie redirects automatically to the login page.

    URL protectedURL = new URL(protectedURLString);
            HttpsURLConnection conn = (HttpsURLConnection) protectedURL.openConnection();
            conn.setInstanceFollowRedirects(false);
    
            boolean redirect = false;
            System.out.println("Request URL: " + protectedURL);
    
            //Check for redirection
            int status = conn.getResponseCode();
            if(status != HttpURLConnection.HTTP_OK) {
                if(status == HttpURLConnection.HTTP_MOVED_TEMP 
                        || status == HttpURLConnection.HTTP_MOVED_PERM
                        || status == HttpURLConnection.HTTP_SEE_OTHER) {
                    redirect = true;
                }
            }
            System.out.println("Response Code: " + status);
    
            //If redirected
            if(redirect) {
                //get new redirect URL from Location header field
                String newURL = conn.getHeaderField("Location");
                URL tempURL = new URL(newURL);
                String query = tempURL.getQuery();
                //Read parameters from query
                String [] params = query.split("&");
                for (String param : params) {
                    String [] parts = param.split("=");
                    String key = parts[0].toLowerCase();
                    String value = "";
                    if(parts.length > 1)
                        value = parts[1];
                    updateVars(key, value);
                }
    
            }
            postToLogin(this.URL_LOGIN);
    

    This is some code used in my solution. updateVars(key, value) updates the class variables. postToLogin(this.URL_LOGIN) posts to the login URL containing a body generated using the class variables.