Jboss 7 own authenticator - authentication

I am trying to write own authenticator which will read particular custom cookies and authenticate user based od token which is stored in that cookie. As an example I took this class: org.jboss.security.negotiation.NegotiationAuthenticator
So I start to writing my own authenticator:
public class SampleAuthenticator extends AuthenticatorBase{
#Override
protected boolean authenticate(Request arg0, Response arg1, LoginConfig arg2) throws IOException {
System.out.println("===CHECK===");
return false;
}
As you can see my class contains only needed method that must be implemented with default values.
I have installed this authenticator as module in Jboss "modules" directory.
Then I have added new security-domain in standalone.xml:
<security-domain name="sso" cache-type="default">
<authentication>
<login-module code="UsersRoles" flag="required" />
</authentication>
</security-domain>
I have made my module as global in standalone.xml as well (in jboss domain subsystem):
<global-modules>
<module name="com.myexample.authenticator"/>
</global-modules>
Now it seems that my authenticator is ready for use (just for output word "===CHECK===")
Into my example web application I have added jboss-web.xml descriptor:
<jboss-web>
<security-domain>sso</security-domain>
<valve>
<class-name>com.myexample.authenticator.SampleAuthenticator</class-name>
</valve>
</jboss-web>
My web.xml descriptor is following:
<security-constraint>
<web-resource-collection>
<web-resource-name>MyResourceName</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>My kinda secure web application</realm-name>
</login-config>
<security-role>
<role-name>user</role-name>
</security-role>
Finally when I am trying to deploy my web application it is throwing this exception:
12:41:28,554 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC000001: Failed to start service jboss.web.valve.myvalve: org.jboss.msc.service.StartException in service jboss.web.valve.myvalve: java.lang.ClassCastException: com.myexample.authenticator.SampleAuthenticator cannot be cast to org.apache.catalina.Valve
at org.jboss.as.web.WebValveService.start(WebValveService.java:92)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.4.GA-redhat-1.jar:1.0.4.GA-redhat-1]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.4.GA-redhat-1.jar:1.0.4.GA-redhat-1]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_55]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_55]
at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_55]
Caused by: java.lang.ClassCastException: com.myexample.authenticator.SampleAuthenticator cannot be cast to org.apache.catalina.Valve
at org.jboss.as.web.WebValveService.start(WebValveService.java:72)
... 5 more
I am stuck at this point. I tried to reimplement some authenticators but this ClassCastException is always there.
Can anybody help me with writing own authenticator?
I am using Jboss EAP 6.2 with Jboss 7.1.1

Check the classpath, but has repeatedly deploy your classes.
If you have already defined in the JBoss module with the autenticator, should not have this class in the war or ear

The problem was that I was using wrong lib. Problem was solved by using this maven dependency:
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-web</artifactId>
<version>7.2.0.Final</version>
<scope>provided</scope>
</dependency>

Related

Wildfly 17 Elytron: server side authentication with classes from EAR

We plan to migrate from Picketbox to Elytron and face the following problem:
With Picketbox a custom login module can use functionality of (or even can reside in) a deployment module (e.g. an EAR in wildfly/standalone/deployments) to implement authentication on the server side:
<subsystem xmlns="urn:jboss:domain:security:2.0">
<security-domains>
...
<security-domain name="MyDomain" cache-type="default">
<authentication>
<login-module name="MyLoginModule" code="de.example.wildfly.MyLoginModule" flag="required" module="deployment.de.example.wildfly.login"/>
</authentication>
</security-domain>
My first try was to use a custom realm in Elytron. But as far as I understand, a custom realm needs to be a "static" module (meaning it is located under wildfly/modules/...) and thus cannot access "dynamically" deployed modules (see https://developer.jboss.org/message/984198#984198).
<subsystem xmlns="urn:wildfly:elytron:7.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
...
<security-domains>
<security-domain name="MyDomain" default-realm="MyRealm" permission-mapper="default-permission-mapper">
<realm name="MyRealm" role-decoder="from-roles-attribute" />
</security-domain>
</security-domains>
<security-realms>
...
<custom-realm name="MyRealm" module="de.example.wildfly.login" class-name="de.example.wildfly.MyCustomRealm" />
(I omitted some more of the security domain configuration)
When I try to load a Spring context (that is located in an EAR in order to access some custom classes from the EAR) in MyCustomRealm, I get the following error:
org.springframework.beans.factory.access.BootstrapException: Unable to initialize group definition. Group resource name [classpath:applicationContext-appServerBase.xml], factory key [applicationContextEjb]; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext-appServerBase.xml]; nested exception is java.io.FileNotFoundException: class path resource [applicationContext-appServerBase.xml] cannot be opened because it does not exist
Which is no surprise, because my realm does not depend on the ear or any jar from therein, where the application context is located.
How can authentication (specifically for EJB calls) be customized on server side by using classes from a deployment module (EAR) in Elytron?
Maybe https://github.com/AntonYudin/wildfly-securityrealm-ejb is exactly what you are looking for.
It creates a SecurityRealm that can be configured with the address of an EJB that's deployed with your application.
The EJB has to be Stateless and must implement the method Map<String, Object> authenticate(String, String) which is called with a username and a password.
I guess you have to return a map that contains all roles and groups the user belongs to or null if the credentials are invalid.

How to disable ProgrammaticLogin authentication Netbeans/Glassfish

I'm trying to run a Netbeans/Glassfish application locally on Windows which is currently running in production on a Unix server. I've succeeded in getting the app up and running, but can't get past the login display due to an authorization exception. I have my name (email) and password set up in the app's database, and have been able to log in to the app running on the Unix server using my credentials. I have connected the Glassfish server to the database via a putty tunnel, and successfully pinged it via the Glassfish admin console. I've also modified the sun-resources.xml to use the tunneled port for database access.
The way the program is doing authentication is with this code:
boolean authenticateSucceeded=false;
try {
ProgrammaticLogin pl=new ProgrammaticLogin();
authenticateSucceeded=pl.login(user, getEncryptedPassword(password), "mycompany-security-realm", request, response, true);
String LOGIN_MSG="Login ok for user: "+user;
logger.info(LOGIN_MSG);
}
catch (javax.security.auth.login.LoginException e) {
logger.info("Login exception, user: "+user+", message ="+e.getMessage());
e.printStackTrace();
}
catch (Exception e) {
logger.info("Login exception, user: "+user+", message ="+e.getMessage());
e.printStackTrace();
}
String forward=null;
if (authenticateSucceeded)
{
forward=URL_HOME_PAGE;
}
else{
forward=LOGIN_ERROR_PAGE;
String loginComment="Login failed: user ="+user+", fwd ="+forward;
logger.info(loginComment);
}
forward(request,response,forward);
Here's a partial stack dump:
SEVERE: com.sun.enterprise.security.auth.login.common.LoginException: Login failed: javax.security.auth.login.LoginException: Failed file login for myname#mycompnay.com.
at com.sun.enterprise.security.auth.login.LoginContextDriver.doPasswordLogin(LoginContextDriver.java:353)
at com.sun.enterprise.security.auth.login.LoginContextDriver.login(LoginContextDriver.java:199)
at com.sun.enterprise.security.auth.login.LoginContextDriver.login(LoginContextDriver.java:152)
at com.sun.web.security.WebProgrammaticLoginImpl.login(WebProgrammaticLoginImpl.java:122)
at com.sun.appserv.security.ProgrammaticLogin$2.run(ProgrammaticLogin.java:259)
at java.security.AccessController.doPrivileged(Native Method)
Here's the web.xml configured for the login security:
<security-constraint>
<web-resource-collection>
<web-resource-name>MySecureResource</web-resource-name>
<url-pattern>/stage/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>mycompany-security-realm</realm-name>
<form-login-config>
<form-login-page>/login/login.jsp</form-login-page>
<form-error-page>/login/forgotPassword.jsp</form-error-page>
</form-login-config>
</login-config>
The "mycompany-security-realm" is contained in a generated file called "domain.xml"
<auth-realm classname="com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm" name="mycompany-security-realm">
<property name="jaas-context" value="jdbcRealm"/>
<property name="password-column" value="password"/>
<property name="group-table" value="grouptable"/>
<property name="datasource-jndi" value="jdbc/mycompany-sec"/>
<property name="user-table" value="usertable"/>
<property name="group-name-column" value="groupid"/>
<property name="jass-context" value="jdbcRealm"/>
<property name="db-password" value="xxxx"/>
<property name="digest-algorithm" value="none"/>
<property name="db-user" value="mycompanydbuser"/>
<property name="user-name-column" value="userid"/>
</auth-realm>
When I look at the jdbc specified in domain.xml, it differs from the production version, which is set up on the server to point to a different database. However, when I set it to point to the same database, I get the same exception.
This is a legacy application, and in a worst case scenario I can load it up to the test server and test it up there. However, I would like to run it locally just for form's sake. How can I get this thing working? Or is it better to disable the Authentication, and if so, how? I did try commenting out the auth-realm in web.xml, but had no luck with that either.
The message
LoginException: Failed file login for myname#mycompnay.com
indicates ("Failed file login") that your application is not using the JDBC realm you want to use but the default file realm.
The common cause for this is that either the JDBC realm is really not configured in Glassfish or that it is configured in the wrong config. There is a default-config section and a server-config section in the domain.xml. Make sure the JDBC realm is configured in the server-config.
To disable the authentication just comment out the security-constraint and the login-config.

Testing web service deployment with Arquillian: context root is null

I want to deploy an enterprise application with a web service facade to glassfish with Arquillian. I am not very experienced in this thema.
I send the WebService and Interface codes with annotiations.
WebService Implementation:
#Stateless
#WebService(endpointInterface = "ena.access.ticketsservices.facade.ITicketsRoleMappingsFacade")
#DeclareRoles({ "User", "Guest", "ProjectAdmin", "Admin" })
public class TicketsRoleMappingsFacade implements ITicketsRoleMappingsFacade {
...
}
Interface:
#WebService(name = "TicketsRoleMappingsFacade")
public interface ITicketsRoleMappingsFacade {
#WebMethod
#WebResult(name = "createProjectResult")
public Project createProject(#WebParam(name = "createproject") Project project);
}
And the following xml files are glassfish configuration files.
application.xml
<?xml version="1.0" encoding="UTF-8"?>
<application
version="6"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd">
<display-name>j2ee-ear</display-name>
<module>
<ejb>j2ee-ejb.jar</ejb>
</module>
<security-role>
<role-name>User</role-name>
</security-role>
<security-role>
<role-name>Guest</role-name>
</security-role>
<security-role>
<role-name>ProjectAdmin</role-name>
</security-role>
<security-role>
<role-name>Admin</role-name>
</security-role>
<library-directory>lib</library-directory>
</application>
glassfish-application.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-application PUBLIC -//GlassFish.org//DTD GlassFish Application Server 3.1 Java EE Application 6.0//EN http://glassfish.org/dtds/glassfish-application_6_0-1.dtd>
<glassfish-application>
<security-role-mapping>
<role-name>User</role-name>
<group-name>User</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>Guest</role-name>
<group-name>Guest</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>ProjectAdmin</role-name>
<group-name>ProjectAdmin</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>Admin</role-name>
<group-name>Admin</group-name>
</security-role-mapping>
<realm>someRealm</realm>
</glassfish-application>
glassfish-ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-ejb-jar PUBLIC -//GlassFish.org//DTD GlassFish Application Server 3.1 EJB 3.1//EN http://glassfish.org/dtds/glassfish-ejb-jar_3_1-1.dtd>
<glassfish-ejb-jar>
<security-role-mapping>
<role-name>User</role-name>
<group-name>User</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>Guest</role-name>
<group-name>Guest</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>ProjectAdmin</role-name>
<group-name>ProjectAdmin</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>Admin</role-name>
<group-name>Admin</group-name>
</security-role-mapping>
<enterprise-beans>
<ejb>
<ejb-name>TicketsRoleMappingsFacade</ejb-name>
<webservice-endpoint>
<port-component-name>TicketsRoleMappingsFacade</port-component-name>
<port-component-uri>/TicketsRoleMappingsFacade</port-component-uri>
</webservice-endpoint>
</ejb>
</enterprise-beans>
</glassfish-ejb-jar>
When I build ear file with ShrinkWrap and deploy get the following lines in log servers log, so I think a part of deployment was succesfull:
[#|2013-08-03T17:23:57.322+0200|INFO|glassfish3.1.1|javax.enterprise.webservices.org.glassfish.webservices|_ThreadID=17;_ThreadName=Thread-2;|WS00019: EJB Endpoint deployed j2ee-ear listening at address at http://localhost:9999/TicketsRoleMappingsFacadeService/TicketsRoleMappingsFacade|#]
But I also get the following exception in Arquillian:
java.lang.IllegalArgumentException: contextRoot must not be null
at org.jboss.arquillian.container.spi.client.protocol.metadata.Servlet.<init>(Servlet.java:48)
at org.jboss.arquillian.container.glassfish.clientutils.GlassFishClientService.resolveWebModuleSubComponents(GlassFishClientService.java:357)
at org.jboss.arquillian.container.glassfish.clientutils.GlassFishClientService.doDeploy(GlassFishClientService.java:227)
at org.jboss.arquillian.container.glassfish.CommonGlassFishManager.deploy(CommonGlassFishManager.java:101)
at org.jboss.arquillian.container.glassfish.remote_3_1.GlassFishRestDeployableContainer.deploy(GlassFishRestDeployableContainer.java:71)
at org.jboss.arquillian.container.impl.client.container.ContainerDeployController$3.call(ContainerDeployController.java:161)
at org.jboss.arquillian.container.impl.client.container.ContainerDeployController$3.call(ContainerDeployController.java:128)
at org.jboss.arquillian.container.impl.client.container.ContainerDeployController.executeOperation(ContainerDeployController.java:271)
at org.jboss.arquillian.container.impl.client.container.ContainerDeployController.deploy(ContainerDeployController.java:127)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:99)
at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:81)
at
....
I don't have any .war file for this test setup how can I specify the contextRoot for my web service?
If you don't have a WAR(web application) you theoretically would not need the application.xml. My suggestion, try to delete it.
The successful deployment of the application in glassfish does not mean it will work in Arquillian. Arquillian has some issues with file name and context-root (I had this issue with an WAR file)
An EAR, according to JavaEE 6 Documentation, usually is used to bind WARs and EJBs. So, in theory, if you do not have a WAR you don't exactly need an EAR. You can deploy the EJB directly.
After 8 years, it is nice to remember the problems of my master thesis...
As far as I remember there was no problem with the code above, but there was a bug in the old Arquillian version.
After a few weeks, my supervisor returned from holiday and just updated the Arquillian version in the parent project and tests started to work as expected.

OpenAM/OpenSSO agent for JBoss EAP 6 / JBoss AS 7

I'd like to add the OpenAM/OpenSSO SSO feature to JBoss EAP 6 or JBoss AS 7. This means I must install an SSO Java EE agent on JBoss. Forgerock's OpenAM download page gives the opportunity to get agents for previous versions of JBoss, but new JBoss EAP 6 / JBoss AS 7 are not supported (for the moment).
Do you know if such an agent is available somewhere, or will be available in short future? If not, do you know how to change JBoss configuration to make it work with OpenAM?
It seems there is no official agent for JBoss EAP 6 for the moment.
However, I could make it work with OpenAM SSO by configuring my JBoss instance manually. To do it, I started with existing jboss_v42_agent.zip available on forgerock download site. Using the jars agent.jar, openssoclientsdk.jar and agent configuration files, I could build a JBoss module using this module.xml:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="openam.agents">
<resources>
<resource-root path="agent.jar"/>
<resource-root path="openssoclientsdk.jar"/>
<resource-root path="."/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.servlet.api" />
<module name="org.picketbox"/>
</dependencies>
</module>
Then I must update standalone.xml by adding a security domain:
<security-domain name="AMRealm" cache-type="default">
<authentication>
<login-module code="com.sun.identity.agents.jboss.v40.AmJBossLoginModule" flag="required">
<module-option name="unauthenticatedIdentity" value="anonymous"/>
</login-module>
<login-module code="org.jboss.security.ClientLoginModule" flag="required">
<module-option name="restore-login-identity" value="true"/>
</login-module>
</authentication>
</security-domain>
Finaly I deployed the agentapp.war on JBoss after having modified the MANIFEST.MF by adding a line:
Dependencies: openam.agents
where openam.agents is the name of my module.
Now for the application I want to enable SSO for, I also must perform some updates:
web.xml: Add the and nodes:
<filter>
<filter-name>Agent</filter-name>
<display-name>Agent</display-name>
<description>OpenAM Tomcat Policy Agent Filter</description>
<filter-class>com.sun.identity.agents.filter.AmAgentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Agent</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
jboss-web.xml: Declare the security-domain to be used
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>AMRealm</security-domain>
</jboss-web>
MANIFEST.MF: Apply same modification than in agentapp.was (add "Dependencies: openam.agents" line)
I'm not sure if it's the best way to enable SSO on JBoss EAP 6 / AS 7 (I'm not a expert), but it seems to work well.
One idea is putting an Apache http server with the OpenAM policy agent installed getting the requests in front of Jboss 7.
This is known as the reverse proxy integration. You can find out more here:
http://developers.sun.com/identity/reference/techart/app-integration.html
and http://docs.oracle.com/cd/E19575-01/820-3746/gjbna/index.html
Using the reverse proxy aproach you don't have to care about the application's runtime environment.
I noticed some days ago that forgerock has now released a J2EE Agent for JBoss 7.x but I haven't tested it yet. See http://forgerock.org/openam.html

Authentication without authorization on Tomcat 7

I have an annoying error which I can't solve for quite a while. I recently was introduced to container-based security and try to implement it. I have configure the realm as following:
<Realm className="org.apache.catalina.realm.JDBCRealm"
debug="99"
driverName="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/identify"
connectionName="adm" connectionPassword="pw"
userTable="users" userNameCol="login"
userCredCol="password"
allRolesMode="authOnly" />
</Realm>
Unfortunately I can't login with this. The log error messages are:
SEVERE: Exception performing authentication
java.sql.SQLException: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version
for the right syntax to use near 'null WHERE login = 'user1'' at line 1
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2928)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1666)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2994)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:936)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1030)
at org.apache.catalina.realm.JDBCRealm.getRoles(JDBCRealm.java:640)
at org.apache.catalina.realm.JDBCRealm.authenticate(JDBCRealm.java:430)
at org.apache.catalina.realm.JDBCRealm.authenticate(JDBCRealm.java:355)
at org.apache.catalina.realm.CombinedRealm.authenticate(CombinedRealm.java:146)
at org.apache.catalina.realm.LockOutRealm.authenticate(LockOutRealm.java:180)
at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:282)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:440)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
Please notice the '' around the user name... Is this correct?
As you see I also use allRolesMode="authOnly", because I don't need this functionality and moreover the database doesn't have and won't ever have an additional column for user roles (it is quite pointless if won't use it than every user will have the same value in this column - big waste of recourses.).
The server is Tomcat 7.0.19
You have to set the userRoleTable and roleNameCol properties in case of allRolesMode="authOnly" too. Without them the SQL query will contain the String null (as you can see in the message of the exception). The value of userRoleTable could be the same as the value of userTable, and roleNameCol also could be same as userNameCol.
A simple workaround is creating an SQL view which emulates the roles table:
CREATE VIEW roles (username, role)
AS SELECT username, 'user' FROM users;
And a solution:
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/test"
connectionName="..." connectionPassword="..."
userTable="users" userNameCol="username" userCredCol="password"
userRoleTable="users" roleNameCol="username"
/>
(Surprisingly it works without any allRolesMode.)
The required web.xml snippets:
<security-constraint>
<web-resource-collection>
<web-resource-name>protected zone</web-resource-name>
<url-pattern>/prot/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>*</role-name>
</security-role>
(Note: Lets say you have 1 million users, a new attribute in the users table with one million user\0 string would cost only around 5 megabytes. I agree with that this is not a beautiful solution but it's not intolerable big nowadays.)
I have Tomcat 7.0.27.0 with JDK 1.6
I am using tomcat only for Authentication and not for authorization
Following is the setup
context.xml
<Realm className="org.apache.catalina.realm.JDBCRealm"
connectionName="login"
connectionPassword="password"
connectionURL="jdbc:oracle:thin:#127.0.0.1:1521:authdb"
driverName="oracle.jdbc.OracleDriver"
userTable="appusers"
userNameCol="username"
userCredCol="password"
allRolesMode="authOnly"/>
web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/modules/*</url-pattern>
<url-pattern>/index.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<!--
security-role>
<role-name>user</role-name>
security-role>
-->
I got it working by removing <security-role> block from web.xml &
putting auth-contraint with role-name as *
If you remove auth-contraint block from security-contraint then web context authentication itself will not be invoked !!