Spring security 3 – How to display login errors ?

Heres how we display different error messages for the different cases of authentication failures like bad credentials, credentials expired etc.

Step 1. Configure an authentication failure handler in the application context.

Step 2. Refer this handler in the form-login node of http namespace configuration.

Step3. Capture the different URL extensions configured in step 1 in the login controller. (The example below uses Spring MVC)

Step 4. Check the attribute error in the JSP and print appropriate message for each case.

Done !

Error: attribute property is mandatory for tag authentication

Bug: The exception thrown when migrating to spring 3.

Reason:  This exception thrown when migrating to spring-security 3 occurs due to spring 3 (authentication tag) using the attribute “properties” in place of “operation” used by previous versions.

Solution : Use <sec:authentication property=”principal.role”/> instead of <sec:authentication operation=”role”/>

Solve MySQL ERROR 1005: Can’t create table (errno: 150)

Bug: Above error occurs when rebuilding a database from the SQL script.

Reason: This error usually occurs when the table being created cannot fulfill a foreign key constraint. This often happens when importing from a previously exported database script as database export tools like SQL Yog export tables in alphabetical order of their names, irrespective of their inter-dependencies.

Solution: Recreate the DB script in “Turn off foreign key” mode. If this is not possible, in the current script, run the create query for independent tables first, followed by ones dependent on them, and so on.

How to enable CAS without SSL

This is a tiny tutorial on steps required to enable CAS (Jasig, v3.4x ) single-sign-out without SSL. These are the steps involved to remove dependency on SSL –

  1. Use HTTP urls (instead of HTTPS ones) in all client configurations.
  2. Edit [CAS-server-deployment-root]/ WEB-INF/ spring-configuration/ ticketGrantingTicketCookieGenerator.xml
    1. Change the value of attribute “p:cookieSecure” to false.
  3. Edit [CAS-server-deployment-root]/ WEB-INF /spring-configuration/ warnCookieGenerator.xml
    1. Change the value of attribute “p:cookieSecure” to false.

The CAS authentication and SSO should work without problems on plain HTTP now.

Apache : RewriteRule vs Alias

A small note on order of execution of a RewriteRule directive and a folder Alias on Apache HTTPD – RewriteRule is always executed before the Alias, thus making a rewrite shown in the listing below possible –

[sourcecode language=”php”]
Alias /assets/ "//contenthost/assets/"
<Directory "//contenthost/assets">
AllowOverride None
Options None
Order allow,deny
Allow from all
</Directory>

RewriteCond %{HTTP_REFERER} !^http://mydomain.com.*$ [NC]
RewriteRule (.*)/assets/* – [F]
[/sourcecode]

This will make sure that if calls to /assets/ are not coming from our domain, they are rejected; else they will be picked from the aliased folder “//contenthost/assets”

Enabling SSL on a Tomcat “devl” machine (Windows)

These are the steps involved to enable SSL on Tomcat on developer machine for test purposes.

1. Create a certificate key store

Run this command in the command prompt –

[sourcecode language=”bash”]

%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA

[/sourcecode]

An interactive console based program is launched –

  1. When asked for a password, provide one and confirm the same.
  2. The program then prompts for your first name and last name; here, enter the name of the host machine. eg. testserver1. (Do NO T enter the IP of the host here.)
  3. Provide proper values for further prompts like Company Name, State etc.
  4. Press enter when prompted for a tomcat password.

This will create a key repository file .keystore in the home folder of the (windows) user.

2. Edit the Server.xml (in [catalina-home]/conf)

1. Uncomment the node <Connector port=”8443″……/>.

2. Edit/Add the following attributes (colored) to the above node –

protocol=”org.apache.coyote.http11.Http11Protocol” SSLEnabled=”true” keystoreFile=”${user.home}/.keystore” keystorePass=”[the-password-you-provided]” maxThreads=”150″ scheme=”https” secure=”true” clientAuth=”false” sslProtocol=”TLS” />

3. Start tomcat. Run an application using  URL “http: //[ hostname]:8443/[appname]”.

4. The browser probably shows an “Untrusted Certificate” warning – Ignore and proceed.

Following are additional steps required to enable java based HTTP-clients  talk to this newly created secured server .

3. Install the Host Certificate as Trusted

  1. Download and unzip this file to desktop.
  2. In the folder InstallCert run this in command prompt – [sourcecode language=”bash”] java -cp . InstallCert [above-host-name]:8443 [/sourcecode]
  3. When done, the program creates a file “jssecacerts” in the same folder. Copy this file to folder (java-home)/jre/lib/security.

Done !

You should now  be able to run services requiring sercured connection on this host like CAS server and clients.

Installing PHP5.3.3 on Apache 2.2x (Windows)

List of steps involved in getting PHP5 to work with a pre-installed Apache server on Windows.

  1. Download the file “php-5.3.3-Win32-VC6-x86.zip” from “http://windows.php.net/download/”
  2. Extract contents of this file to C:/PHP/
  3. Copy C:/PHP/php.ini.development to a new file  php.ini in the same folder
  4. In the httpd.conf file of Apache, add the following lines after the LoadModule block.
    [sourcecode language=”bash”]
    LoadModule php5_module "C:/PHP/php5apache2_2.dll"
    AddHandler application/x-httpd-php .php<
    # configure the path to php.ini
    PHPIniDir "C:/PHP"
    [/sourcecode]
  5. Restart Apache.

Thats it ! PHP pages should now be processed and displayed by apache. To test, create a file PHPTest.php in folder “[Apache-root]/htdocs/” with following content.


[sourcecode language=”php”]
<?php
phpinfo();
?>;
[/sourcecode]

In the browser open the URL “http://localhost/PHPTest.php”. This should now display the PHP engine details.

Now, as required the document root, extensions folder, available extension etc for PHP can be configured in the file C:/PHP/php.ini.

Apache mod_rewrite: How to use a Java RewriteMap?

This example shows how to use a Java program as a RewriteMap in Apache Httpd server.

Prerequisites on the server box:

  1. Apache HTTPD 2.2x.
  2. JDK/JRE.

What does the program do ?

Allows all URLs of form “*/secure/” to go ahead, and reject others.

Java Program

Java program for the above is pretty simple – like the one displayed below.

[sourcecode language=”java”]

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class SimpleApacheMap
{
static String SECURED_URL = "/secured/";
static String SECUREDASSETS_FOLDER = "/assets/";
static String REJECT = "/rejected/";
BufferedReader inputReader;
OutputStreamWriter outputWriter;
boolean processed;

private void startMapper() throws IOException
{
String inputToken;
inputReader = new BufferedReader( new InputStreamReader(System.in));
outputWriter = new OutputStreamWriter(System.out);
while(true)
{
inputToken = inputReader.readLine();
if(inputToken!=null && inputToken.indexOf(SECURED_URL)>0)
{
outputWriter.write(inputToken.replace(SECURED_URL, SECUREDASSETS_FOLDER));
}else
{
outputWriter.write(REJECT);
}
outputWriter.flush();
}
}

public static void main(String s[]) throws Exception
{
new SimpleApacheMap().startMapper();
}
}

[/sourcecode]

Jar file

Compile this program, create a jar file (java-apache-map.jar) from the compiled classes. (creating a jar simplifies the call to this program, especially so when complex mapping involving more dependency classes are done.) Add a manifest file pointing to the main class to make this jar runnable.

Paste this jar file in the “bin” folder in Apache root folder.

Create a file “map.sub.lock” in the bin folder. We will provide this file to Apache for using as a synchronization lock on our map program.

Edits in Httpd.conf

In the file httpd.conf, add the following lines –

[sourcecode language=”bash”]

#Define rewriteMap program and set a synchronization lock
RewriteMap forwardURL "prg:\"C:/Program Files/Java/jdk1.6.0_01/bin/java.exe\" -jar \"C:/Program Files/Apache Software Foundation/Apache2.2/bin/java-apache-map.jar\""
RewriteLock bin/map.sub.lock

[/sourcecode]

Note that we have to give the complete path to java.exe as well as the jar file having the map program. “forwardURL” is the name of our map so created.

Now append these line httpd.conf:

[sourcecode language=”bash”]

# Rewrite according to map output.
RewriteRule (.*) ${forwardURL:%1} [C]
RewriteRule (.*)/rejected/(.*) – [F]

[/sourcecode]

The first line tells apache to replace all URLs with the value returned from the map. (the whole URL is passed to the map). The [C] flag makes sure that the next rewrite rule is executed too.
The second rewrite rule checks if the map had returned a URL having the text “/rejected/” in between- in which case a “Forbidden” message is sent back to the browser.

Restart Apache – The rewrites should be working fine now.

Additional tips on using a java map program –

  1. Any debug message can be printed to System.err stream. These messages would appear in [Apache-root]/logs/errors.log.
  2. The program is started as a daemon on server startup, and executes till shutdown/any critical error.
  3. As the program has life time of the server, instance variables defined in the map program has application life time too.
  4. Complex rewrite rules involving multiple requests can be easily implemented by giving a different prefix (to the key passed to the map) for each type of requests.

Eg. A login request could pass a key like login_<sessionId>, a logout request would similarly pass logout_<seesionId>, and the mapper program can update a database (using JDBC) the time taken by each session, or count active sessions, or act as an application-context etc etc.

Apache RewriteRule : Set a session cookie on localhost

Here are the 2  (often left out) requirements to set a cookie using httpd’s rewrite rule (mod_rewrite), while working on localhost:

  1. Use the IP 127.0.0.1 instead of localhost/machine-name as the domain; e.g. [CO=someCookie:someValue:127.0.0.1:2:/], which says create a cookie “someCookie” with value “someValue” for the domain “127.0.0.1” having a life time of 2 mins, for any path in the domain (path=/). (Obviously you will have to run the application with this value in the URL)
  2. To make a session cookie, limit the flag statement to just three attributes: name, value and domain. e.g [CO=someCookie:someValue:127.0.0.1] – Any further settings, apache writes an” expires” attribute for the set-cookie header, which makes the cookie a persistent one (not really persistent, as the expires value set is the current server time – so you don’t even get to see your cookie!)