Sometimes no single login module is enough to meet our needs. Imagine the case of using an external LDAP server to provide the user authentication and a database server to provide the user authorization. A user would be in one repository or the other, and login should succeed if the user is found in either repository.
JBoss allows you to specify multiple login modules for a single security domain. But simple module stacking doesn’t resolve the problem on its own. For that, you need to use password stacking.
Password stacking allows modules to skip the actual authentication and to provide supplemental roles. The modules require the password-stacking option to useFirstPass for this to work.
<application-policy name="myRealm">
<authentication>
<login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="optional">
<module-option name="password-stacking">useFirstPass</module-option>
<module-option name="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</module-option>
<module-option name="java.naming.provider.url">ldap://LDAP_SERVER:LDAP_PORT/</module-option>
<module-option name="java.naming.security.authentication">simple</module-option>
<module-option name="principalDNPrefix">MY_DOMAIN\</module-option>
</login-module>
<login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
<module-option name="password-stacking">useFirstPass</module-option>
<module-option name="dsJndiName">java:myDS</module-option>
<module-option name="principalsQuery">SELECT passwd FROM user WHERE login = ?</module-option>
<module-option name="rolesQuery">SELECT role, 'Roles' FROM user_roles r, user u WHERE u.userid = r.userid AND u.login = ?</module-option>
</login-module>
</authentication>
</application-policy> |
The option principals query is optional; it’s a fallback in the case the authentication fails in the LDAP server. Notice that the LDAP configuration omits the roles query option set so the authorization is only provided by the database server module.
I’ve just created the project Secure JSP Taglibs at Google Code Project Hosting with the ambition to fill some gaps in the security of the presentation layer in a Java web application.
For now it doesn’t do too much, more features will be added in the future.
This Taglib allows you to evaluate the nested body content of the tag to test if the user has the specified roles.
This is equivalent to the isUserInRole() method, but you can evaluate multiple roles (comma separated) at the same time.
Examples:
<secure:one roles="role1toevaluate, role2toevaluate">
Show this content if the user has one of the specified roles.
</secure:one> |
<secure:all roles="role1toevaluate, role2toevaluate">
Show this content if the user has all the specified roles.
</secure:all> |
<secure:none roles="role1toevaluate, role2toevaluate">
Show this content if the user has none of the specified roles.
</secure:none> |
Feel free to use it, it’s licensed under Apache License 2.0 and can be found at http://code.google.com/p/secure-taglib/.
Data that is not validated or poorly validated is the root cause of a number of serious security vulnerabilities affecting applications, such as Cross Site Scripting and SQL Injection. A paper entitled “A Modular Approach to Data Validation in Web Applications” presents an approach to performing thorough data validation in modern web applications so that the benefits of modular component based design (extensibility, portability and re-use) can be realised.
It starts with an explanation of the vulnerabilities introduced through poor validation and then goes on to discuss the merits and drawbacks of a number of common data validation strategies such as:
- Validation in an external Web Application Firewall
- Validation performed in the web tier (e.g. Struts)
- Validation performed in the domain model
Finally, a modular approach is introduced together with practical examples of how to implement such a scheme in a web application, including such strategies as transformation of data to a canonical format, detecting attacks based on likely vectors, accepting only valid data (i.e., a name shouldn’t contain angle brackets), and escaping meta-characters that might have specific meaning for specific contexts (i.e., watching for characters that might execute something unexpected in a SQL engine or LDAP).