1) Defining the Domain
(model.groovy)
Entity ('User') {
string_32 'login', mandatory:true, unicityScope:'scope_login'
password 'password'
enumeration 'language', enumName:'language', values:['fr', 'en']
set 'roles', ref:'Role', reverse:'Role-users'
}
Entity ('Role') {
string_32 'roleId'
set 'users', ref:'User', composition:false, reverse:'User-roles'
}
2) Update Jaas.config to use the new org.jspresso.framework.security.auth.spi.DatabaseLoginModule (3.5 +). This login module extends the Jboss security DatabaseServerLoginModule, so configuration apply.
(take care to setup java.security.auth.login.config parameter into your tomcat launcher as described in the startup tutorial)
myproject {
org.jspresso.framework.security.auth.spi.DatabaseLoginModule required
dsJndiName="java:comp/env/jdbc/MyProjectDS"
principalsQuery="SELECT PASSWORD, LANGUAGE language FROM USER WHERE LOGIN=?"
rolesQuery="SELECT ROLE.ROLE_ID, 'Roles' FROM ROLE, USER, USER_ROLES \
WHERE USER.LOGIN=? AND USER_ROLES.ROLE_ID=ROLE.ID AND USER_ROLES.USER_ID=USER.ID"
principalClass=org.jspresso.framework.security.UserPrincipal
suspendResume=false;
};
3) For TOMCAT :
Define a jndi name for your database context.xml into tomcat conf directory
<Context>
<Resource name="jdbc/MyProjectDS" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="root" password="pwd" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://10.61.168.88:3306/myproject"/>
</Context>
NB : Take care that tomcat lib contains the jdbc lib library (for example mysql-connector-java-x.x.x.jar )
Setup your datasource project : use the jndi name above
(myproject/webapp/src/main/dev/resources/fr/gefco/myproject/config.xml)
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
default-lazy-init="true">
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/MyProjectDS"/>
</bean>
</beans>
4) For SWING:
4.a) Define the datasource directly into /myproject/core/src/main/resources/fr/gefco/weather/config.xml
<bean
id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property
name="driverClassName"
value="com.mysql.jdbc.Driver" />
<property
name="url"
value="jdbc:mysql://localhost:3306/myproject" />
<property
name="username"
value="root" />
<property
name="password"
value="pwd" />
</bean>
4.b) Update your SwingApplicationStartup class to setup the jndi name for your database :
@Override
public void start() {
DataSource dataSource = (DataSource) getApplicationContext().getBean("dataSource", DataSource.class);
try {
InitialContext ic = new InitialContext();
Context compSubContext = ic.createSubcontext("java:comp");
Context envSubContext = compSubContext.createSubcontext("env");
Context jdbcSubContext = envSubContext.createSubcontext("jdbc");
jdbcSubContext.rebind("MyProjectDS", dataSource);
} catch (NamingException ex) {
throw new NestedRuntimeException(ex);
}
super.start();
}
4.c) Add a JNDI library to your Jspresso application Launcher.
For my own i'm using Simple-JNDI : you have to add following VM arguments :
-Djava.naming.factory.initial=org.osjava.sj.SimpleContextFactory
-Dorg.osjava.sj.delimiter=/
-Dorg.osjava.sj.jndi.shared=true
-Dorg.osjava.sj.root=conf
5) This step is optional. The Jspresso database login module will store all extra column you put into the principals query (e.g. language in our case) into the session user principal custom properties. However, you might want to keep the user entity instance itself into the application session (also as a custom property). Here is how you would do it using a simple startup action.
a. Add a startup application
(frontend.groovy)
controller (myproject.name', startup:'startupBackAction')
(backend.groovy)
action ('startupBackAction', class:'org.mycompany.myproject.backend.StartupBackAction')
b. Code your startup action
public class StartupBackAction extends AbstractHibernateAction {
public final static String USER_ENTITY_KEY = "session.userEntity";
@SuppressWarnings("unchecked")
@Override
public boolean execute(IActionHandler actionHandler, final Map<String, Object> context) {
final UserPrincipal userPrincipal = getBackendController(context).getApplicationSession().getPrincipal();
User user = (User)getTransactionTemplate(context).execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus txStatus) {
User user = null;
DetachedCriteria userCriteria = DetachedCriteria.forClass(User.class);
userCriteria.add(Restrictions.eq("login", userPrincipal.getName()));
List<User> users = getHibernateTemplate(context).findByCriteria(userCriteria);
if (users!=null && !users.isEmpty()) {
user = users.get(0);
}
txStatus.setRollbackOnly();
return user;
}
});
// merge hibernate instance into session
user = (User)getController(context).merge(user, EMergeMode.MERGE_KEEP);
// set custom property
userPrincipal.putCustomProperty(USER_ENTITY_KEY, user);
return super.execute(actionHandler, context);
}
}
6) Code an administration workspace for User and Role entity
That will not take a while using Jspresso ;)
You should be done !