Monthly Archives: February 2013

MDA Approach for Card Scheme conversion

The idea is to use MDA approach for conversion of one card schema to the other one. The traditional way is to write java code field by field. What I suggested is to use MDA (Model Driven Approach) for the conversion. The idea is to define the model in a kind of object model, use XML to make the model and create the framework to execute the mode.

During the implementation I understood that usage of standard EL (Expression Language) would be very handy and I successfully tried Juel.

In this way, the conversion rules are much more meaningful and understandable. It is also possible to change them dynamically without recompiling.

There is only one important negative point and that one is type safety. Not all expression in Juel are checked against syntax in type of loading. My next task on this subject is to find how can I guaranty type safety, at least at the same level as java code.

Default page in Tapestry

In the current release of Tapestry version 5.0, there is an odd behavior about default index page. Here is the problem. I have used Tynamo for enforcing security. The desired behavior is that all pages should be authenticated. If you access them, before logging you should be redirected to /login.tml page. Our main page is set as default /index.tml page.

you can configure tynamo on which pages to protect in AppModule.contributeSecurityConfiguration
[code lang=”java”]
configuration.add(factory.createChain(“/login”).add(factory.anon()).build());
configuration.add(factory.createChain(“/”).add(factory.authc()).build());
[/code]

this works fine, as you long as access the main page by directly accessing root at http://server.port/app/

But what happens if you try to access a non existent page, some thing like http://server.port/app/blahblah ? strange unchangeable behavior of tapestry, directs this url to default index page, after that it is checked by tynamo. So your protected page is revealed easily. Tynamo has also no way to protect wild pages with exception. Something like
[code lang=”java”]
configuration.add(factory.createChain(“/**”).add(factory.authc()).build());
[/code]

will also protect /login.tml and prohibits logging in.

The best I came to, was to move the index page to some other page, say /processlist and protect by tynamo. I changed the Index.java to:

[code lang=”java”]
public class Index {
Object onActivate() throws MalformedURLException {
return ProcessList.class;
}
}
[/code]

Now if you access your arbitary page, it is redirected to the main page, but this time before security checking and every thing works fine.

Activiti and Hibernate/tynamo integration

We are using Tapestry as MVC framework in the company and we needed to integrate a sample tapestry based with activiti security tables.

“Apache Shiro” and “Tynamo” are used. “Apache Shiro” is a Java security framework from Aapche. Tynamo  helps in using Shiro in Tapestry. In this post I am going to explain how Activiti security could be used in Tapestry web based applications.

 

Target:

Target is creating a web based application. The related page should be visible only after authentication. For authentication these conditions should be validated:

1. User should exist in “act_id_user” table

2. password should match to the password in the same table.

3. In “act_id_membership” table, user should be associated with “admin” group
 
Activiti realm:

In Shiro, different realms are foreseen. JDBC, LDAP, Active. So one way is to create a new “Activiti Realm” and configure Shiro to use it, and configure Tapestry to use Shiro.

Creating ActivitiRealm is simple. You have to extend AuthorizingRealm class and implement doGetAuthenticationInfo member and put the authentication logic in it. Something like this:

 

[code lang=”java”]
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
String username = usernamePasswordToken.getUsername();
char[] pswrd = usernamePasswordToken.getPassword();
String password = String.copyValueOf(pswrd);

// check if the username and password are correct
IdentityService identityService = processEngine.getIdentityService();
if (!identityService.checkPassword(username, password)) {
throw new IncorrectCredentialsException();
}

// check if the username ins member of “admin” role
GroupQuery query = identityService.createGroupQuery();
if (query.groupMember(username).groupName(ADMIN_ROLE).count() == 0) {
throw new IncorrectCredentialsException();
}
return buildAuthenticationInfo(username, password);
}
[/code]

 

Service Injection:

As you may have seen in the above code, processEngine is just used. It is injected by Tapestry Injection framework. It could be injected in Spring configuration file or in build method in AppModule. In this implementation Spring based configuration is used. This code snipplet in application-context.xml file will do the job:

[code lang=”xml”]

[/code]
 
Configure Shiro to use Activiti Realm
Now we have the realm and we have to make shiro use our new realm.
This method in AppModule.java will make shiro use the realm:

[code lang=”java”]
@Contribute(WebSecurityManager.class)
public static void addRealms(Configuration configuration, @Autobuild ActivitiRealm activitiRealm) {
configuration.add(activitiRealm);
}

[/code]
 
Login page
Shiro is configured and can be used for checking security. Now we need a login page. It is possible to use default login page, but here I prefer to have my own login page.
The page is a normal login page, like in any other one. Just in validation, such a code uses Shiro for authentication:

[code lang=”java”]
public Object onActionFromJsecLoginForm()
{

Subject currentUser = securityService.getSubject();

if (currentUser == null) {
throw new IllegalStateException(“Subject can`t be null”);
}

UsernamePasswordToken token = new UsernamePasswordToken(jsecLogin, jsecPassword);
token.setRememberMe(jsecRememberMe);

try {
currentUser.login(token);
} catch (UnknownAccountException e) {
loginMessage = “Account not exists”;
return null;
} catch (IncorrectCredentialsException e) {
loginMessage = “Wrong password”;
return null;
} catch (LockedAccountException e) {
loginMessage = “Account locked”;
return null;
} catch (AuthenticationException e) {
loginMessage = “Authentication Error”;
return null;
}

SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(requestGlobals.getHTTPServletRequest());

if (savedRequest != null && savedRequest.getMethod().equalsIgnoreCase(“GET”)) {
try {
response.sendRedirect(savedRequest.getRequestUrl());
return null;
} catch (IOException e) {
logger.warn(“Can’t redirect to saved request.”);
return Index.class;
}
} else {
return Index.class;
}
}
[/code]
 
Configure Tapestry to use Shiro for security
Ok, everything is there. Now we have to configure Tapestry to use Shiro for security and secure desired pages.
First we have to introduce our login page. Shiro will redirect user to this page, whenever he wants to access to a secured page and he is not logged in. This code in AppModule does this task:

[code lang=”java”]
@Contribute(SymbolProvider.class)
@ApplicationDefaults
public static void applicationDefaults(
MappedConfiguration<String, String> configuration) {
// Tynamo’s tapestry-security (Shiro) module configuration
configuration.add(SecuritySymbols.LOGIN_URL, “/login”);
}
[/code]

and the last thing is to let Shiro know which pages should be protected:

[code lang=”java”]
public static void contributeSecurityConfiguration(Configuration configuration,
SecurityFilterChainFactory factory) {
// /authc/** rule covers /authc , /authc?q=name /authc#anchor urls as well
configuration.add(factory.createChain(“/login”).add(factory.anon()).build());

configuration.add(factory.createChain(“/assets/**”).add(factory.anon()).build());
configuration.add(factory.createChain(“/myPage”).add(factory.authc()).build());
configuration.add(factory.createChain(“/”).add(factory.authc()).build());
}
[/code]
this configuration make the “/login” accessible without authentication and put protection on “/assets/”, “/myPage” and “/” pages.

Done, Done.