Reputation: 468
I am currently in the process of writing a web app (a collection of RESTful web services) that has the potential to be deployed on multiple different application servers (JBoss
and WebSphere
are two different containers we want to support out of the box initially).
Whenever I look online for security examples for JBoss
, they reference JBoss specific authentication/authorization classes, which obviously wouldn't work on WebSphere.
Is there a good way (either a Java EE
standard or a 3rd party framework) to handle security in a container independent manner?
I was originally planning on having the container handle authentication then authentication would be handled with custom code on each of the REST methods. However, after setting up basic authentication in my web.xml
, JBoss seems to be doing some sort authorization on its own and gives me a 403 after a successful log in. In WebSphere, I am able to define an "All Authenticated" role that will authorize all authenticated users, but I am not sure how to do the equivalent in JBoss (and in a container independent method).
Here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>identify-service-web</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<security-constraint>
<web-resource-collection>
<web-resource-name>All resources</web-resource-name>
<description>Protects all resources</description>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>ApplicationRealm</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>ApplicationRealm</role-name>
</security-role>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
</web-app>
I am a Java EE security newbie, so please excuse the fact that I might have missed something extremely obvious. Hope someone can push me in the right direction!
Upvotes: 0
Views: 965
Reputation: 446
Maybe you can use spring-security as an common authentication mechanism... But in general mixing spring and Java EE is not a good idea.
You can use the standard Java EE security framework, if you want to deploy your application in some containers you will need to provide specific configuration for each container, this shouldn't be a problem because that configurations will not be too long and each container should ignore the specific configuration of other containers.
If you jboss gives you a 403 error even in a sucessful login sounds like a misconfiguration. Have you checked the security domain in WEB-INF/jboss-web.xml? In jboss if you doesn't define any auth-constraint in the security-constraint it will accept any user.
Upvotes: 0
Reputation: 18020
Just as kwart wrote, security settings defined in web.xml or by standard security annotations must be implemented by all containers, so its safe and portable to use them.
What is server specific, is how user to security role mapping is defined, what can be a user registry (e.g. ldap, file, database, custom), and additional authentication mechanisms supported by contaier (e.g. Kerberos, SAML, custom).
For general information on Java EE security, you can check Securing a Web application chapter in WebSphere Application Server V7.0 Security Guide (although saying about Java EE 5, most information is still valid in the latest release).
For example how to configure web.xml for JAX-RS application in WebSphere check this page:
Upvotes: 1
Reputation: 3164
By using the security-constraint
in the web.xml
you define authorization for the applicaiton. So your configuration means: Only authenticated users with the assigned role ApplicationRealm have access to this application.
You can use a role-mapping in security-domain in the JBoss AS7.1 / EAP 6.x / WildFly. For instance use CLI commands:
/subsystem=security/security-domain=other/mapping=classic:add
/subsystem=security/security-domain=other/mapping=classic/mapping-module=mapRoleToAllUsers:add(code="org.jboss.security.mapping.providers.role.DatabaseRolesMappingProvider", type="role", module-options=[("dsJndiName"=>"java:jboss/datasources/ExampleDS"), ("rolesQuery"=>"SELECT 'ApplicationRealm' FROM Dual WHERE ?!=''")])
reload
which result in following configuration in the standalone.xml
:
<security-domain name="other" cache-type="default">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="RealmDirect" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
</authentication>
<mapping>
<mapping-module name="mapRoleToAllUsers" code="org.jboss.security.mapping.providers.role.DatabaseRolesMappingProvider" type="role">
<module-option name="dsJndiName" value="java:jboss/datasources/ExampleDS"/>
<module-option name="rolesQuery" value="SELECT 'ApplicationRealm' FROM Dual WHERE ?!=''"/>
</mapping-module>
</mapping>
</security-domain>
Then all authenticated users get the ApllicationRealm
role automatically.
I strongly recommend to use jboss-web.xml
to define security domain for your application, even if the default one is used:
<jboss-web>
<security-domain>other</security-domain>
</jboss-web>
There is currently an issue, which causes the roles are not mapped correctly when the jboss-web.xml
is omitted.
Upvotes: 2