OXSessionFormLogin: Difference between revisions

From Open-Xchange
No edit summary
m (Reverted edits by Choeger (talk) to last revision by WolfgangRosenauer)
Line 1: Line 1:
This article explains the optional OXSessionFormLogin servlet in detail. For a quick-start guide on using it, see [[Open-Xchange servlet for external login masks]]
= Form Login =
= Form Login =


The form login is a mechanism, that allows you to create a custom login form, by which way a user may enter the OX frontend. All you need to do, is have the form POST the necessary login information and the location of the OX frontend. The OX server will create a session, set all necessary cookies and forward the browser to the frontend.  
The form login is a mechanism, that allows you to create a custom login form, by which way a user may enter the OX frontend. All you need to do, is have the form POST the necessary login information and the location of the OX frontend. The OX server will create a session, set all necessary cookies and forward the browser to the frontend.  
== Requirements ==
The Open-Xchange [[HTTP_API#Form_Login_.28since_6.20.29|HTTP API]] has a function to
create a session from external.
In order for this mechanism to work, you need to set <tt>com.openexchange.sessiond.autologin=true</tt> in <tt>/opt/open-xchange/etc/sessiond.properties</tt>





Revision as of 07:09, 18 July 2013

This article explains the optional OXSessionFormLogin servlet in detail. For a quick-start guide on using it, see Open-Xchange servlet for external login masks

Form Login

The form login is a mechanism, that allows you to create a custom login form, by which way a user may enter the OX frontend. All you need to do, is have the form POST the necessary login information and the location of the OX frontend. The OX server will create a session, set all necessary cookies and forward the browser to the frontend.


Parameters

The parameters that the OX servers login process expects are:

login
The login name. This will usually be a text input.
password
The users password. This will usually be a password input field.
client
The client parameter used to distinguish between programs using the same cookie store. Since we want the new session to be used by the AJAX frontend, we'll set this to com.openexchange.ox.gui.dhtml for the OX6 frontend and to open-xchange-appsuite for App Suite. This is a hidden field. See also OXSessionGlossary
version
A version string. The content is not really relevant, but it will be logged, so we can later find out, where a login request came from. The UI will usually send its version, we'll send Form Login so we can see in the logfile when our spiffy new form was used to log in. This will also be a hidden field.
autologin
This tells the frontend whether to attempt to store the session data for a later autologin. This can only be true if server configuration parameter com.openexchange.sessiond.autologin is enabled as well, otherwise the UI will attempt to store the session and trigger a server error. See OXSessionAutologin for more details about the autologin process.
uiWebPath
Tells the server where to find the frontend, so it can redirect the browser there. This will usually be a relative URL, since the backend and frontend are usually accessible using the same host (they have to be to allow for the same source policy in javascript). Make sure to always send the browser to the index.html and NOT the ox.html. The index.html contains some browser checks that have to be done before entering the UI. You'll save yourself headaches by always sending the user to the index.html. Usually this will point to /ox6/index.html for the OX6 frontend or /appsuite/ (note the trailing slash) for App Suite. This also is a hidden field.
authId
A random string used for tracking a login requests way through your apache / OX setup.


Example

So, in essence, what we need is a form for POSTing to the backend with the above parameters. This is pretty basic HTML stuff:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="cache-control" content="no-cache">
<title>Login</title>
<script type="text/javascript">
function uuid() {
    function hex(len, x) {
        if (x === undefined) x = Math.random();
        var s = new Array(len);
        for (var i = 0; i < len; i++) {
            x *= 16;
            var digit = x & 15;
            s[i] = digit + (digit < 10 ? 48 : 87); // '0' and 'a' - 10
        }
        return String.fromCharCode.apply(String, s);
    }
    return [hex(8), "-", hex(4), "-4", hex(3), "-", hex(4, 0.5 + Math.random() / 4), "-", hex(12)].join("");
}
</script>
</head>
<body>
<form action="/ajax/login?action=formlogin&authId=" method="post" onSubmit="this.action += uuid();">
        <p>
            <label for="login">Username: </label>
            <input type="text" name="login" id="login"><br>
            <label for="password">Password:  </label>
            <input type="password" name="password" id="password"><br>
            <input type="submit" value="Login">
            <input type="hidden" name="version" value="Form Login">
            <input type="hidden" name="autologin" value="true">

            <!-- When using OX App Suite -->
            <input type="hidden" name="client" value="open-xchange-appsuite">
            <!-- Important: value of uiWebPath MUST be terminated by a trailing slash "/" -->
            <input type="hidden" name="uiWebPath" value="/appsuite/">
 
            <!-- When using OX6 -->
            <!-- <input type="hidden" name="client" value="com.openexchange.ox.gui.dhtml"> -->
            <!-- <input type="hidden" name="uiWebPath" value="/ox6/index.html"> -->
        </p>
    </form>
</body>
</html>

Notice the form sends its entries to /ajax/login?action=formlogin. This relative URL will only work if the form is accessed using the same host name as the OX server. If you want to send the user to the OX server from a different host, specify the whole address in the forms action attribute, e.g. https://ox.mydomain.com/ajax/login?action=formlogin. The uiWebPath though is always considered relative to the OX server (regardless of where the form resides), so you're usually good when using a relative link there.

Now back to the authId. In order to generate a unique String we'll define a javascript function in the head of the document.

We won't worry about the details here, only one thing matters to us at this point: This bit of javascript generates a random UUID that we can use for our authId parameter. Since we want to see that parameter in the apache log files, we have to pass this as part of the URL. This means, when the user submits the form, we'll append a generated authId to the URL.

If you're uncomfortable using javascript for this, you might opt for having the form page generated by a server side script and just include the random UUID in the form definition. The only thing to remember about this is: You need the authId parameter, it must be part of the URL, so it shows up in logfiles and it must be unique so that it makes sense when later tracking what happens to a login request. In total our form page looks like this:


Login Errors

What happens if an error occurs during the login process? For example, the user might have entered the wrong password? In that case the OX Server uses an error template, you may override, to display an error message. It's basic, but functional:

<html>
<script type="text/javascript">
// Display normal HTML for 5 seconds, then redirect via referrer.
setTimeout(redirect,5000);
function redirect(){
 var referrer=document.referrer;
 var redirect_url;
 // If referrer already contains failed parameter, we don't add a 2nd one.
 if(referrer.indexOf("login=failed")>=0){
  redirect_url=referrer;
 }else{
  // Check if referrer contains multiple parameter
  if(referrer.indexOf("?")<0){
   redirect_url=referrer+"?login=failed";
  }else{
   redirect_url=referrer+"&login=failed";
  }
 }
 // Redirect to referrer
 window.location.href=redirect_url;
}
</script>
<body>
<h1>ERROR_MESSAGE</h1>
</body>
</html>

What does it do? It displays the error message for 5 seconds and the redirects back to the referrer, meaning: Your form. It adds a login=failed parameter to the URL, so your form may react when something went wrong. If you think (like myself) this form lacks the, ah well, je-ne-sais-quoi of a nice error page, then fret not! You can provide your own custom template. To do that, open up the file /opt/openexchange/etc/groupware/login.properties and set the com.openexchange.ajax.login.errorPageTemplate to point to a file on the OX system that contains your template. For example:

 com.openexchange.ajax.login.errorPageTemplate=/opt/openexchange/local/loginErrors.html
 

Then write the template. Keep in mind, that ERROR_MESSAGE will be replaced by the actual error message of the login attempt (say "Your password was not valid" or somesuch). The template above might be a good starting point for you to start experimenting.