Skip login

Hi,

We have some clients that wants to embed our solution in their website. They have a login on their website and if a user is logged on there and access the servoy solution the login on servoy side should be skipped.

How can I show the solution, providing the username and password as parameters to the url, thus skiping the login page.

Thanks!

You can use a global method in your login solution( which can be called directly from an URL) to take care of the login. But be aware that passing usernames and password in an URL is not very secure !

Does servoy use ssl so the request will be encrypted?

I wouldn’t do that, the credentials would be logged in the webserver log in clear form.
I do it this way: I’ve created an html form to get username/pass, on submit I call an headless client that validates the credentials and creates a row in a table inserting a UUID token, when done the HC loads the solution in the web page passing the token as argument to the login module, the login module asks the auth module to check if the token is valid and proceeds with automatic login, if the token is not valid (tampered or just expired) the login form is shown instead.
In your case you just need to invoke the HC using the credentials that your user has already used to login to the website and you’re done.

This trick is also very nice because it helps you avoid people just sitting on your webclient login page doing nothing and eating 1 servoy license and some server memory.

BTW: this would also make it very easy to implement persistent login, you just need to set an expiry date on the token record and store it as a cookie in the user browser.

When sending the credentials to the headlessclient, as arguments I assume, would this be safe?

I think I can manage to make the request from the server side of the website and then on servoy side I can even check against the IP and allow only requests from a single IP.

The website belongs to a client so is not at the same hosting as servoy.

Yes, it’s safe the form data is encrypted before being sent, it’s a POST action not an URL with extra args.

Hi Nicola,

ngervasi:
I wouldn’t do that, the credentials would be logged in the webserver log in clear form.
I do it this way: I’ve created an html form to get username/pass, on submit I call an headless client that validates the credentials and creates a row in a table inserting a UUID token, when done the HC loads the solution in the web page passing the token as argument to the login module, the login module asks the auth module to check if the token is valid and proceeds with automatic login, if the token is not valid (tampered or just expired) the login form is shown instead.
In your case you just need to invoke the HC using the credentials that your user has already used to login to the website and you’re done.

This trick is also very nice because it helps you avoid people just sitting on your webclient login page doing nothing and eating 1 servoy license and some server memory.

Is there any chance that you could provide a sample solution of the HC with login/authentication and the HTML form etc. as I am trying to create a web client solution that is going to run on iOS (iTouch/iPad) but the client requires some authentication to happen & I need to be doing things using deep link URLs to activate web client, so using a UUID token would be a great way of doing that.
Thanks

Rafi

Here you are:
This is the html login page, I gather some extra info like solution, browser and ip address for logging using php, you can omit that:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>SintProSystem Login</title>
</head>

<body>
<form id="form1" name="form1" method="post" action="weblogin.jsp">
  <label>Username
  <input type="text" name="username" id="username" tabindex="1" />
  </label>
  <p>
    <label>Password
    <input type="password" name="password" id="password" tabindex="2" />
    </label>
  </p>
  <p>
    <label>Language
    <select name="language" >
  		<option value="it" selected="selected">Italiano</option>
  		<option value="en">English</option>
 	 </select>
    </label>
  </p>
  <p>
  	<input type="hidden" name="solution" id="solution" value="SintProSystem"/>
  	<input type="hidden" name="ipaddress" id="ipaddress" value="<?php echo $_SERVER['REMOTE_ADDR']?>"/>
  	<input type="hidden" name="browser" id="browser" value="<?php echo $_SERVER['HTTP_USER_AGENT']?>"/>
    <input type="submit" name="login" id="login" value="Login" tabindex="3" />
  </p>
</form>
</body>
</html>

This is the JSP page called by the html form:

<%@ page import = "java.util.*" %> 
<%@ page import = "com.servoy.j2db.server.headlessclient.*" %> 
<%@ page import = "com.servoy.j2db.dataprocessing.IDataSet" %> 
<%@ page errorPage="errorpage.jsp" %> 
<% 
   ISessionBean servoy_hc = (ISessionBean)session.getAttribute("servoy"); 
   if (servoy_hc == null) 
   { 
      servoy_hc = HeadlessClientFactory.createSessionBean(request,"sintpro_weblogin_mod",null,null); 
      session.setAttribute("servoy",servoy_hc); 
   } 
   boolean ok = servoy_hc.setMainForm("main");
   
   if (!ok)
	{
		out.print("error cannot work on required form");
		return;
	}

%>
<% 
	String user_name = request.getParameter("username"); 
	String passwd = request.getParameter("password");
	String language = request.getParameter("language");
	String solution = request.getParameter("solution");
	String ipaddress = request.getParameter("ipaddress");
	String browser = request.getParameter("browser");
	
    String result = "Cannot execute weblogin method!";
    
    result = (String)servoy_hc.executeMethod(null,"webLogin",new Object[]{user_name,passwd,language,solution,ipaddress,browser});
    
    out.println(result);
    
    session.setAttribute("servoy", null);
%>

this is the method called in the webLogin module, if authentication succeeds the solution is loaded and the UUID is passed as argument:

function webLogin(_username,_passwd,_language,_solution,_ipaddress,_browser)
{
	if(!_username || !_passwd || !_language || !_solution) return 'Missing parameters!';
	
	// Authentication
	var fs = databaseManager.getFoundSet('sintpro_mods','sintpro_weblogins')
	fs.newRecord()
	fs.session_uuid = application.getUUID()
	fs.username = _username
	fs.language_code = _language
	fs.solution_name = _solution
	if(_browser) fs.client_info = _browser
	if(_ipaddress) fs.ip_address = _ipaddress
	var _result = security.authenticate('sintpro_auth_mod', 'authenticate', [_username,utils.stringMD5HashBase64(_passwd)]);
	if(_result[0] == false)
	{
		// Login failed
		fs.login_success = 0
		databaseManager.saveData(fs)
		return _result[1];
	}
	else
	{
		// Login succeeded
		fs.login_success = 1
		databaseManager.saveData(fs)
		var url = '/servoy-webclient/ss/s/'+ _solution +'/a/'+ fs.session_uuid
		var html = '<HTML> \
			<HEAD> \
				<META http-equiv="REFRESH" content="0;url='+ url +'"></HEAD> \
				<BODY> \
					Logging in... \
				</BODY> \
			</HTML>'
		return html;
	}
}

and finally this is the onOpen method of the login module that receives the UUID:

function onOpen(sessionUUID,args)
{
	// Check if a sessionUUID has been provided
	if(sessionUUID)
	{
		// Try to authenticate straight ahead
		var _result = security.authenticate('sintpro_auth_mod', 'authenticateBySessionUUID', [sessionUUID]);
		if(_result[0] == false)
		{
			application.output('SessionUUID Login Failed: '+_result[1] +'('+sessionUUID+')',LOGGINGLEVEL.ERROR)
			application.exit()
		}
		else // login successful, proceed to main form...
...
}

Hi Nicola,

ngervasi:
Here you are:

Thank you so much!
I am going to try my best to put this into my system (somehow) and will let you know how I get on…
Thanks again
Rafi