Tuesday, 22 December 2009

Logger template for Eclipse

As always, my blog dies rather quickly with lack of posts. Main reason for that is lack of time to write a nice, long blog entry. I was recently advised by a colleague that a good place to start is to jot down things that are easily forgotten and require googling later on.
So here comes the first one: how to create a template that will save me a bit of typing every time I need to add a logger to a class.

Preferences -> java -> editor -> templates, "new...".

name: log
description: Logger definition
context: java
automatically insert: yes
pattern:
private static final ${typeLogger:newType(org.slf4j.Logger)}
${name:newName(log)} =
${typeFactory:newType(org.slf4j.LoggerFactory)}.getLogger(${enclosing_type}.class);


All that you need to type in your code afterwards is "log" & ctrl+space. Of course it will work just as nicely with any other log library.

Sunday, 6 September 2009

Simplest HTTPService connection on Flex4

I tried to follow one of the examples in "Getting Started with Flex 3" (create Flickr browser) and faced a couple of issues. This is a working solution, however instead of Flickr RSS it is using Picasa and is using some Flex 4-specific stuff (mainly for data-access). Flickr at the moment is sending an RSS with one of the tags invalid for Flex 4 XML parser (or to be more precise: you cannot generate AS classes from it).


The mxml starts as in the original example (except for colour values, that is):



<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo"
minWidth="1024" minHeight="768"
xmlns:photoservice="services.photoservice.*"
backgroundGradientColors="[#BB78D7, #75637C]">

The next part is a bit simpler than in the original example, since we have nice service generation in Flex 4 (more about this later).



<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.controls.Alert;

import services.photoservice.PhotoService;
import mx.rpc.AsyncToken;
import mx.rpc.CallResponder;
import services.photoservice.PicasaPhotos;

private var callResponder:CallResponder;

protected function search():void
{
fetchResult.token = photoService.fetch("rss","photo","en_US");
}

protected function tileList_creationCompleteHandler(event:FlexEvent):void
{
fetchResult.token = photoService.fetch("rss","photo","en_US");
}

]]>
</fx:Script>

Last part is the actual design part, which also is mostly as in original example, except for the service-related part:



<mx:HBox>
<mx:Label text="Picasa tags or search terms:"/>
<mx:Text id="searchTerms" width="150"/>
<s:Button label="Search" click="search()"/>
</mx:HBox>

<mx:TileList width="100%" height="100%" id="tileList"
creationComplete="tileList_creationCompleteHandler(event)"
dataProvider="{fetchResult.lastResult.item}" labelField="title"
itemRenderer="PicasaThumbnail">
</mx:TileList>

<fx:Declarations>
<s:CallResponder id="fetchResult"/>
<photoservice:PhotoService id="photoService" fault="Alert.show(event.fault.faultString)" showBusyCursor="true" />
</fx:Declarations>
</mx:Application>

The PicasaThumbnail.mxml class looks as follows:



<?xml version="1.0" encoding="utf-8"?>
<mx:VBox
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo"
width="250" height="250"
paddingBottom="10" paddingLeft="15" paddingRight="15" paddingTop="10"
alpha="1"
>

<mx:Image width="200" height="200" source="{data.enclosure.url}" alpha="1"/>
<mx:Text text="{data.title}"/>

</mx:VBox>


The main reason all this works is a very nice addition coming in Flash Builder 4 - Data/Services wizard. It's enough to select menu Data -> Connect to HTTP... and on presented wizard provide a few details (URL, required parameters, service name - and that's it). This will generate a service class. After this is done you can "Configure return type" - the tool will connect to your service, parse example XML and try to prepare a set of classes representing it nicely. Works very well and allows all the nice tools of Eclipse (autocompletion) to be much more helpful.


Overall I am very pleasantly surprised how easy the whole task was and I can see great potential to simplify my work with the data wizard tool.

Flex4, here I come

It's time to resurrect this blog since I've started learning Flex4 and I hope my journey from-Java-to-Flex4 may be helpful for all those other lost souls out there.
My first impression is that I may actually like it - but Flash Builder system requirements are even worse than those of Eclipse 3.5, meaning I probably should get a new laptop. Oh dear...

Monday, 29 December 2008

Spring Security with controllers - part 2

Turns out applying Spring Security on annotated controllers is working perfectly fine and what's also important, is also happy to work with mixed (old- and new-style) controllers.

First step is to add new controller class that looks like this:


@Controller
@RequestMapping(value = "/s2/*")
public class SimpleController2 {

@Autowired
private Command command;

@RequestMapping(method = RequestMethod.GET)
@Secured("administrator")
@Permissioned(action = "View", resource = "Video")
public ModelAndView doSomething2(HttpServletRequest request,
HttpServletResponse response) {
System.out.println("Doing something 2");
command.doSomething();
return new ModelAndView(new RedirectView(
"http://www.google.com/search?q=done+something"));

}
}


Then add the following into Spring context file:

<context:annotation-config />
<bean
class="org.springframework.web.servlet.mvc.annotation.
DefaultAnnotationHandlerMapping" />
<bean id="simpleController2" class="controllers.SimpleController2" />


And that's it really. URLs with /s1 should go to SimpleController and SimpleController2 will take care about /s2 - important thing is that the security interception will happen already on the controller level which you can easily observe by removing the annotations from commands - you will still get access denied error.

Tuesday, 23 December 2008

Spring Security - part 1

Probably most of us - developers - at least once in their life (and some "lucky" ones many more times than that...) spend long minutes or even hours trying to solve a problem. Usually in the end you find such a trivial mistake or misconception that it becomes almost physically painful to see how much time you lost. One of those situations became an inspiration for the first entry on this blog.

In my current project we decided to use Spring security to replace somewhat hacky authorization we use now. All controllers inherit from AbstractController, that overrides handleRequestInternal:

@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
String methodName = getMethodNameResolver().getHandlerMethodName(request);
Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
Permissioned annotation = method.getAnnotation(Permissioned.class);
if (annotation != null) {
String action = annotation.action();
String resource = annotation.resource();
String userName = request.getHeader("USERNAME");
if (!userService.isAllowed(userName, resource, action)) {
throw new ControllerAccessDenied("User not allowed");
}
}
return invokeNamedMethod(methodName, request, response);
} catch (NoSuchRequestHandlingMethodException ex) {
return handleNoSuchRequestHandlingMethod(ex, request, response);
}
}


It is of course not a true code taken from the project but gives you the idea of the approach. All methods on the controller that are supposed to be secured are annotated like this:

@Secured("administrator")
@Permissioned(action = "View", resource = "Video")
public ModelAndView doSomething(HttpServletRequest request, HttpServletResponse response) {
command.doSomething();
return new ModelAndView(...);
}

This is the authorization part. As for authentication, it is handled externally and at the point of reaching the controller we only care about the USERNAME header.

Implementing similar thing using spring security seemed relatively easy. The plan was to add @Secured annotation where our @Permissioned was used and then handle the logic in a voter.

First we needed to add standard stuff to web.xml:

<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


Then we created security-context.xml with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.4.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">

<security:global-method-security secured-annotations="enabled" access-decision-manager-ref="accessDecisionManager" />

<bean id="accessDecisionManager" class="org.springframework.security.vote.UnanimousBased">
<property name="decisionVoters">
<list>
<ref bean="simpleVoter" />
</list>
</property>
<property name="allowIfAllAbstainDecisions" value="true" />
</bean>

<security:http entry-point-ref="preAuthenticatedProcessingFilterEntryPoint">
<security:intercept-url pattern="/*" access="IS_AUTHENTICATED_FULLY" />
</security:http>

<bean id="preAuthenticatedProcessingFilterEntryPoint" class="org.springframework.security.ui.preauth.PreAuthenticatedProcessingFilterEntryPoint" />

<bean id="requestHeaderProcessingFilter" class="org.springframework.security.ui.preauth.header.RequestHeaderPreAuthenticatedProcessingFilter">
<security:custom-filter position="PRE_AUTH_FILTER" />
<property name="principalRequestHeader" value="USERNAME" />
<property name="authenticationManager" ref="authenticationManager" />
</bean>

<bean id="preAuthenticatedAuthenticationProvider" class="org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider">
<security:custom-authentication-provider />
<property name="preAuthenticatedUserDetailsService" ref="userService" />
</bean>

<bean id="simpleVoter" class="security.Voter" />
<security:authentication-manager alias="authenticationManager" />
</beans>


A little explanation: security:global-method-security makes spring pick up @Secured annotations and... well.. secure annottated methods. Access decision manager contains the list of voters that will make a decision on access, security:http is the usual stuff explained on 100 different websites. The only other interesting bit is the *PreAuthenticated* thing, which allows us to ignore the authentication phase assuming that we've done it in other place. Our userService only provides UserDetails object which will be injected into security context and then used e.g. by voters.

Controllers context looked like this:

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<bean id="simpleController" class="controllers.SimpleController" />
<bean id="simpleCommand" class="commands.SimpleCommand" />
<bean id="userService" class="security.UserServiceImpl" />
</beans>

Additionally we needed dispatcher-servlet.xml which contained just urls mappings:

<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/s1/*">simpleController</prop>
</props>
</property>
</bean>


I've put @Security annotation on controller, removed the old overridden method. Tomcat started fine but I was still allowed to enter the method even though every call should be rejected.
(An hour later...) The reason for that was simple. We annotated controllers methods. Since they are written in the 'old style', extending spring controllers, every call reaches our code through handleRequest method. Thus it becomes an internal call and obviously in Spring Aop such calls are no longer intercepted (they don't go through a proxy). The solution in this case was simply to use spring security on the service level rather than controller. However, it does not completely replace our previous solution and therefore I will investigate if there is a workaround.