Link to home
Start Free TrialLog in
Avatar of CipherIS
CipherISFlag for United States of America

asked on

Pass Login Information

I am developing a webpage.  The webpage is requesting login credentials.  I will get the UserName and Password and verify against a database.  This is the easy part.

After I verify the login what i want to do is use those credentials to login to another site.  Example lets say I want to loginto hotmail.  So - how do I pass the login credentials to my Hotmail page?  Lets say that hotmail is a functional website written in JSP.
Avatar of intlaqa
intlaqa
Flag of Egypt image

Do you have access to the external websites? do they can provide a page for you or a login service?
Avatar of ronney_leslie
ronney_leslie

You cannot just pass the login credentials to any page. The service provider (maybe hotmail) need to provide you with a web service or a similar interface to pass the credentials to them so that they can authenticate and send you to a page within their site. The process you are referring to is called Single Sign On (SSO). If you give me specifics I can help you out further.

Also here is an article that might help you understand further.

http://www.ibm.com/developerworks/web/library/wa-singlesign/

Ronney
Avatar of CipherIS

ASKER

Ronney
I have done this before - but its been such a long time since i've done this and don't remember or have the code on how I did this.  i have access to the code on the other website.  Yes, it is SSO but I have to handle it the way I described.  
My App
-  Verifyies Login
Other App
-  Login in is received from My App and uses the login to access the website.
Thx
I provided code snippets below for the .NET and JSP pages.  Let me know if more info is needed.
ASP.NET CODE

<td align="left" width="300" height="200" valign="top"><br><p>blah blah</p></td>
<td align="right" width="400"  height="200">
<!---form table--->
<table width="400" cellpadding="2" cellspacing="3" border="0">
<tr>
<td align="left" width="100" valign="middle"><span class="subtitle">Login:</span></td>
<td align="left" width="300" valign="middle">
<asp:TextBox ID="txtLogin" runat="server" MaxLength="50" Width="219px"></asp:TextBox>
</td>
</tr>
<tr>
<td align="left" width="100" valign="middle"><span class="subtitle">Password:</span></td>
<td align="left" width="300" valign="middle">
<asp:TextBox ID="txtPassword" runat="server" MaxLength="50" Width="219px" TextMode="Password"></asp:TextBox>
</td>
</tr>
<tr>
<td colspan="2" align="center" valign="middle"><br><br>
<asp:Button ID="cmdProceed" runat="server" onclick="cmdProceed_Click" 
Text="Proceed" />
</td>
</tr>
</table>

C# CODE
using (SqlConnection connection = new SqlConnection(source))
{
//Open the connection
connection.Open();
//Create the command
SqlCommand command = connection.CreateCommand();
command.Connection = connection;
//Execute Scalar
sSQL = "Select Top 1 Login ";
sSQL += "From Users ";
sSQL += "Where Login = '" + this.txtLogin + "'";
sSQL += "and password ='" + this.txtPassword + "'";
command.CommandText = sSQL;
try
{
sValue = command.ExecuteScalar().ToString();
}
catch (Exception ex)
{
string s = ex.Message.ToString();
}
connection.Close();
}

JSP CODE
<tr>
<td>
<h:outputText value="#{msg.username}"/>:
</td>
<td>
<%-- input text field, with an example of a nested validator tag --%>
<h:inputText id="user-name" value="#{LoginBean.username}" validator="#{LoginBean.validateUsername}" style="width:150px" />
</td>
</tr>

<tr>
<td>
<h:outputText value="#{msg.password}"/>:
</td>
<td>
<%-- password text field, with an example of a validation bean method --%>
<%-- the validation method adds a faces message to be displayed by a message tag --%>
<h:inputSecret id="user-password" value="#{LoginBean.password}" validator="#{LoginBean.validatePassword}" style="width:150px" />
</td>
</tr>

Open in new window

Hi,

Try to use HttpWebRequest to send HTTP POST requests to the external login PAGEs with all required data (Username, Password, Login Options.. etc). But this is not guaranteed to work with all websites.

For example:

HttpWebRequest myLoginRequest = (HttpWebRequest)HttpWebRequest.Create("http://www.website.com/login.jsp");

byte[] dataToPost = System.Text.Encoding.ASCII.GetBytes("Username=myUserName&Password=myPassword");

myLoginRequest.Method = "POST";
myLoginRequest.ContentType="application/x-www-form-urlencoded";
myLoginRequest.ContentLength = dataToPost.Length;

Stream loginRequestStream = myLoginRequest.GetRequestStream();
loginRequestStream.Write(dataToPost, 0, dataToPost.Length);
loginRequestStream.Close();
Ok, the above code did not cause an error.  Looks like its closer.  How do i navigate to the page of the JSP page?  Response.Redirect only brings me to the log in page and not logged in.  I need to go to the page and need to be logged in.
If you have access to the code on the other site (Site 2) then you need to create a page on that server that would
1. accept login credentials by http "POST" and validate it
or
2. be able to identify that the reauest is coming from the 1st trusted site and know the name of the user requesting the connection

Validate the passed information (either #1 or #2 above) and then redirect to the appropriate page directly.

You had stated that when you use response.redirect it is going to the site 2's login page. How does Site 2 process the login. It would be caling some methods internally to authenticate the user and will then set some session information (in client/server/DB etc). Since now you want to bypass the Site 2's login page your site 1 should be able to call another page (like the login page) but which would do all the validations internally and finally redirect the user to the correct page on site 2.

Ronney

Oh, I thought you will try to get some data from the external website after you login.

In my code and similar, when you login by sending the POST to the external page, the login cookies.. etc will be on your HttpWebRequest object's CookieContainer NOT in user browser, so when you Response.Redirect the user to the page, the user will be asked to login because he has no login cookies in his computer.

I think what you are trying to do is very hard if you do not want to touch the external website code, or if you do not control it.

But, I have a very dirty way to do a trick, here it is:

1) User types username and password in YOUR login page.
2) Verify them against the database.
3) If they are OK, dynamically render an invisible iFrame points to the external login page.
4) When the iFrame is loaded, access it with JavaScript to set the Username and Password textboxes there with the username and password which user typed in your page.
5) Access the external page to find the Login/Submit button and click on it with JavaScript!
6) When iframe/external page submitted, it reloads again, if it does not have the login form, it means the user successfully logged in.
7) Direct the user to the external landing page with JavaScript.

I know it is really very dirty solution, but this way we will be sure that the user has all cookies.. etc because we simulate the login process exactly as a human.

Here is some code to try, please try it on IE first, if this what you want and works for you let me know to fix the code to work with all browsers:

Your Login Page ASPX:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:TextBox ID="txtUsername" runat="server"></asp:TextBox>
        <asp:TextBox ID="txtPassword" runat="server"></asp:TextBox>
        <asp:Button ID="btnLogin" runat="server" Text="Login" onclick="btnLogin_Click"  />
    </div>
    </form>
</body>
</html>

And here is what happes in the btnLogin_Click:

protected void btnLogin_Click(object sender, EventArgs e)
{
HtmlGenericControl iframeControl = new HtmlGenericControl("iframe");

iframeControl.Attributes["id"] = "myExternalPageFrame";

iframeControl.Attributes["src"] = "http://externalwebsite.com/YourExternalPage.jsp";
iframeControl.Attributes["height"] = "0";
iframeControl.Attributes["width"] = "0";
iframeControl.Attributes["onload"] = "PassLogin();";

string javaScriptToPassLogin = "function PassLogin() { if(myExternalPageFrame.document.getElementById('txtPassword').value == '') {myExternalPageFrame.document.getElementById('txtUsername').value = '" + txtUsername.Text + "';myExternalPageFrame.document.getElementById('txtPassword').value = '" + txtPassword.Text + "'; myExternalPageFrame.document.getElementById('btnLogin').click(); } else {window.location = frames['myExternalPageFrame'].location;} }";

ClientScript.RegisterClientScriptBlock(this.GetType(), "PassLOGIN", javaScriptToPassLogin, true);

form1.Controls.Add(iframeControl);
}

NOTE: In the JavaScript code, please change the IDs of username, password and submit/login to match your external page ones.

I made a simple external login page to try it:
ExternalLogin.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ExternalPage.aspx.cs" Inherits="ExternalPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="txtUsername" runat="server"></asp:TextBox>
        <asp:TextBox ID="txtPassword" runat="server"></asp:TextBox>
        <asp:Button ID="btnLogin" runat="server" Text="Login"
            onclick="btnLogin_Click" />
    </div>
    </form>
</body>
</html>

ExternalPage.aspx.cs:

using System;
using System.Web;

public partial class ExternalPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        System.Threading.Thread.Sleep(3000); // simulate it is loadin...

        if (Request.Cookies["val"] != null)
        {
            Response.Write(Request.Cookies["val"].Value);
        }
    }
    protected void btnLogin_Click(object sender, EventArgs e)
    {
        Response.Cookies.Add(new HttpCookie("val","welcome " + txtUsername.Text));
    }
}
Ok, looks like the dirty trick is close.  I've attached the access denied image that I am receiving.  I am trying to login to Alfresco from .NET.  It is a requirement I was given.  I am attaching the code from the Alfresco page also.

<%--
* Copyright (C) 2005-2007 Alfresco Software Limited.

* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.

* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.

* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception.  You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
--%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>

<%@ page import="org.alfresco.web.app.servlet.BaseServlet" %>
<%@ page import="org.alfresco.web.app.servlet.AuthenticationHelper" %>
<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
<%@ page import="org.alfresco.web.ui.common.Utils" %>
<%@ page import="org.alfresco.web.app.Application" %>
<%@ page import="org.alfresco.web.bean.LoginBean" %>
<%@ page import="javax.faces.context.FacesContext" %>
<%@ page import="javax.servlet.http.Cookie" %>
<%@ page import="java.util.Locale" %>

<%@ page buffer="16kb" contentType="text/html;charset=UTF-8" %>
<%@ page isELIgnored="false" %>

<%
Cookie authCookie = AuthenticationHelper.getAuthCookie(request);

// remove the username cookie value if explicit logout was requested by the user
if (session.getAttribute(AuthenticationHelper.SESSION_INVALIDATED) != null)
{
if (authCookie != null)
{
authCookie.setMaxAge(0);
response.addCookie(authCookie);
}
}
else
{
// setup value used by JSF bean state ready for login page if we find the cookie
String authCookieValue;
if (authCookie != null && (authCookieValue = AuthenticationHelper.getAuthCookieValue(authCookie)) != null)
{
session.setAttribute(AuthenticationHelper.SESSION_USERNAME, authCookieValue);
}
}

// setup system locale from the Accept-Language header value
Locale locale = BaseServlet.setLanguageFromRequestHeader(request, application);
%>

<body bgcolor="#ffffff" style="background-image: url(<%=request.getContextPath()%>/images/logo/AlfrescoFadedBG.png); background-repeat: no-repeat; background-attachment: fixed">

<r:page titleId="title_login">

<f:view>
<%
FacesContext fc = FacesContext.getCurrentInstance();

// set locale for JSF framework usage
fc.getViewRoot().setLocale(locale);

// set permissions error if applicable
if (session.getAttribute(LoginBean.LOGIN_NOPERMISSIONS) != null)
{
Utils.addErrorMessage(Application.getMessage(fc, LoginBean.MSG_ERROR_LOGIN_NOPERMISSIONS));
session.setAttribute(LoginBean.LOGIN_NOPERMISSIONS, null);
}
%>

<%-- load a bundle of properties I18N strings here --%>
<r:loadBundle var="msg"/>

<h:form acceptcharset="UTF-8" id="loginForm" >

<table width=100% height=98% align=center>
<tr width=100% align=center>
<td valign=middle align=center width=100%>

<table cellspacing=0 cellpadding=0 border=0>
<tr><td width=7><img src='<%=request.getContextPath()%>/images/parts/white_01.gif' width=7 height=7 alt=''></td>
<td background='<%=request.getContextPath()%>/images/parts/white_02.gif'>
<img src='<%=request.getContextPath()%>/images/parts/white_02.gif' width=7 height=7 alt=''></td>
<td width=7><img src='<%=request.getContextPath()%>/images/parts/white_03.gif' width=7 height=7 alt=''></td>
</tr>
<tr><td background='<%=request.getContextPath()%>/images/parts/white_04.gif'>
<img src='<%=request.getContextPath()%>/images/parts/white_04.gif' width=7 height=7 alt=''></td><td bgcolor='white'>

<table border=0 cellspacing=4 cellpadding=2>
<tr>
<td colspan=2>
<img src='<%=request.getContextPath()%>/images/logo/AlfrescoLogo200.png' width=200 height=58 alt="Alfresco" title="Alfresco">
</td>
</tr>

<tr>
<td colspan=2>
<span class='mainSubTitle'><h:outputText value="#{msg.login_details}" />:</span>
</td>
</tr>

<tr>
<td>
<h:outputText value="#{msg.username}"/>:
</td>
<td>
<%-- input text field, with an example of a nested validator tag --%>
<h:inputText id="user-name" value="#{LoginBean.username}" validator="#{LoginBean.validateUsername}" style="width:150px" />
</td>
</tr>

<tr>
<td>
<h:outputText value="#{msg.password}"/>:
</td>
<td>
<%-- password text field, with an example of a validation bean method --%>
<%-- the validation method adds a faces message to be displayed by a message tag --%>
<h:inputSecret id="user-password" value="#{LoginBean.password}" validator="#{LoginBean.validatePassword}" style="width:150px" />
</td>
</tr>

<tr>
<td>
<h:outputText value="#{msg.language}:" rendered="#{LoginBean.languageSelect}" />
</td>
<td>
<%-- language selection drop-down --%>
<h:selectOneMenu id="language" value="#{UserPreferencesBean.language}" style="width:150px" onchange="document.forms['loginForm'].submit(); return true;" rendered="#{LoginBean.languageSelect}">
<f:selectItems value="#{UserPreferencesBean.languages}" />
</h:selectOneMenu>
</td>
</tr>

<tr>
<td colspan=2 align=right>
<h:commandButton id="submit" action="#{LoginBean.login}" value="#{msg.login}" />
</td>
</tr>

<tr>
<td colspan=2>
<%-- messages tag to show messages not handled by other specific message tags --%>
<h:messages style="padding-top:8px; color:red; font-size:10px" layout="table" />
</td>
</tr>
</table>

</td><td background='<%=request.getContextPath()%>/images/parts/white_06.gif'>
<img src='<%=request.getContextPath()%>/images/parts/white_06.gif' width=7 height=7 alt=''></td></tr>
<tr><td width=7><img src='<%=request.getContextPath()%>/images/parts/white_07.gif' width=7 height=7 alt=''></td>
<td background='<%=request.getContextPath()%>/images/parts/white_08.gif'>
<img src='<%=request.getContextPath()%>/images/parts/white_08.gif' width=7 height=7 alt=''></td>
<td width=7><img src='<%=request.getContextPath()%>/images/parts/white_09.gif' width=7 height=7 alt=''></td></tr>
</table>

<div id="no-cookies" style="display:none">
<table cellpadding="0" cellspacing="0" border="0" style="padding-top:16px;">
<tr>
<td>
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc"); %>
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td valign=top style="padding-top:2px" width=20><h:graphicImage url="/images/icons/info_icon.gif" width="16" height="16"/></td>
<td class="mainSubText">
<h:outputText value="#{msg.no_cookies}" />
</td>
</tr>
</table>
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner"); %>
</td>
</tr>
</table>
</div>
<script>
document.cookie="_alfTest=_alfTest"
var cookieEnabled = (document.cookie.indexOf("_alfTest") != -1);
if (cookieEnabled == false)
{
document.getElementById("no-cookies").style.display = 'inline';
}
</script>

</td>
</tr>

</table>

</h:form>
</f:view>

<script>

if (document.getElementById("loginForm:user-name").value.length == 0)
{
document.getElementById("loginForm:user-name").focus();
}
else
{
document.getElementById("loginForm:user-password").focus();
}

</script>

</r:page>

</body>

Open in new window

AccessDenied.JPG
I modified some code for readability.  Still receiving Denied access.  However, when i click on inore I am able to see the website in the iFrame but can't seem to be able to pass login info to that site.
iframeControl.Attributes["src"] = "http://localhost:8080/alfresco/faces/jsp/login.jsp";
iframeControl.Attributes["height"] = "500";
iframeControl.Attributes["width"] = "1500";
iframeControl.Attributes["onload"] = "PassLogin();";

StringBuilder sb = new StringBuilder();
sb.Append("<script language='javascript'>");
sb.Append("");
sb.Append("function PassLogin()");
sb.Append("{");
sb.Append("  if(myExternalPageFrame.document.getElementById('user-name').value == '')");
sb.Append("  {");
sb.Append("    myExternalPageFrame.document.getElementById('user-name').value = '" + this.txtLogin.Text.ToString()+"'; ");
sb.Append("    myExternalPageFrame.document.getElementById('user-password').value = '" + txtPassword.Text + "';");
sb.Append("    myExternalPageFrame.document.getElementById('submit').click();");
sb.Append("  }");
sb.Append("  else ");
sb.Append("  {");
sb.Append("    window.location = frames['myExternalPageFrame'].location;");
sb.Append("  }");
sb.Append("}");
sb.Append("</script>");

if (!ClientScript.IsClientScriptBlockRegistered("PassLogin"))
{
  ClientScript.RegisterClientScriptBlock(this.GetType(), "PassLogin", sb.ToString());
}

Open in new window

Here is more info.  I checked the values of myExternalPageFrame in .NET and below are the values.
?myExternalPageFrame
{...}
    clientInformation: Access is denied.
    clipboardData: Access is denied.
    closed: false
    constructor: Access is denied.
    defaultStatus: Access is denied.
    document: Access is denied.
    event: Access is denied.
    external: Access is denied.
    frameElement: Access is denied.
    frames: {...}
    history: Access is denied.
    length: 0
    localStorage: Access is denied.
    location: {...}
    maxConnectionsPerServer: Access is denied.
    name: Access is denied.
    navigator: Access is denied.
    offscreenBuffering: Access is denied.
    onhashchange: null
    onmessage: Access is denied.
    opener: undefined
    parent: {object}
    screen: Access is denied.
    screenLeft: Access is denied.
    screenTop: Access is denied.
    self: {...}
    sessionStorage: Access is denied.
    status: Access is denied.
    top: {object}
    window: {...}

Open in new window

Hi,

Can you please change the JavaScript code to be:

string javaScriptToPassLogin = "function PassLogin() { if(myExternalPageFrame.document.getElementById('user-password') != null) {myExternalPageFrame.document.getElementById('user-name').value = '" + txtUsername.Text + "';myExternalPageFrame.document.getElementById('user-password').value = '" + txtPassword.Text + "'; myExternalPageFrame.document.getElementById('submit').click(); } else {window.location = frames['myExternalPageFrame'].location;} }";

Try this until you please send me the rendered HTML of both the external login page and the external landing page which open when the user successfully logged-in:

1) Open the external page normally in the browser, View Source and paste the HTML here.
2) Login from the external page, when you are successfully loggedin, View Source and paste the HTML here.

This is gonna help me to know the exact IDs of the controls and in the conditional if statement which helps me to know whether it is the external login page or it is the external landing page.
Ok, I clicked on View Source and copied and pasted into a Text File.  I attached both the view source files.
Dot-Net-Source.txt
Alfresco-Source.txt

While in Break mode I ran the following - any ideas?
?myExternalPageFrame.document
Access is denied.
?myExternalPageFrame.document(0)
Permission denied
?myExternalPageFrame.document(0).text
Permission denied
?myExternalPageFrame.document(0).value
Permission denied
?myExternalPageFrame.document(1)
Permission denied
So dude it should be:

string javaScriptToPassLogin = "function PassLogin() { if(myExternalPageFrame.document.getElementById('loginForm:user-password') != null) {myExternalPageFrame.document.getElementById('loginForm:user-name').value = '" + txtUsername.Text + "';myExternalPageFrame.document.getElementById('loginForm:user-password').value = '" + txtPassword.Text + "'; myExternalPageFrame.document.getElementById('loginForm:submit').click(); } else {window.location = frames['myExternalPageFrame'].location;} }";

Tried it on IE8 & IE6 and works fine for me.
What browser are you working on? Please try it first on IE8 and 6 only for now, if it works we will write better javascript code.
I'm using IE8.
Oh, I am stupid, I am stupid, we can not access iFrame shows a page in a different domain. There are some workarounds, here: http://softwareas.com/cross-domain-communication-with-iframes , but the solution for your problem will be more and more dirtier.
It looks like you guys are sinking deeper and deeper in to mire.

The correct way to do this is to have a page hosted on Alfresco that will accept login parameters posted from your site page and set the login sessions appropriately and redirect you to the reauired page. All other solutions are not just dirty but unethical too.

Ronney

Ronney, What if he doesn't/can't control/have access to Alfresco?
Then it is unethical to access the site this way.

Ronney
ASKER CERTIFIED SOLUTION
Avatar of CipherIS
CipherIS
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial