ACEGI (Spring) Security, HTTPS, and Grails

{ Dan Stieglitz // Groovy/Grails // May 30, 2008 }
I had a requirement in a recent project to have all logins handled by HTTPS, and I wanted to implement this using Grails 1.0.2 with the acegi-plugin. There seemed to be a number of issues with the plugin, specifically with some package names and configuring the ACEGI channel selectors. Of note are that the package names have changed in the ACEGI-Spring migration, for example, packages org.acegisecurity.util... and org.acegisecurity.securechannel... have become org.springframework.security.util and org.springframework.security.securechannel, respectively. I didn't find this reflected in the online documentation for either Spring Security or Grails, at least not yet.

Steps to Configure HTTPS Channels

First, install the acegi plugin. Next, configure the channel filter in the web.xml file. This requires us to install the grails templates which will contain the web.xml template grails uses to produce the deployed web.xml.
grails install-templates
will do the trick. Navigate to the src/templates/war and add the filter to the web.xml template there:
    
  		Acegi Channel Processing Filter
  		org.springframework.security.util.FilterToBeanProxy
  		
    			targetClass
    			org.springframework.security.securechannel.ChannelProcessingFilter
  		
	
    
    
  		Acegi Channel Processing Filter
  		/*
	
Now, when we build our application, this filter will be configured in our deployed web.xml. The final step is to set up the spring beans, and this is done using the Grails DSL for configuring Spring beans (the SpringBuilder). A great reference on the SpringBuilder can be found on the Grails documentation online (http://grails.org/Spring+Bean+Builder). The code should be put into yout grails-app/conf/spring/resource.groovy file (the entire file is reproduced here):
import org.springframework.security.securechannel.ChannelProcessingFilter
import org.springframework.security.securechannel.ChannelDecisionManagerImpl
import org.springframework.security.securechannel.SecureChannelProcessor
import org.springframework.security.securechannel.InsecureChannelProcessor

beans = {
	secureChannelProcessor(SecureChannelProcessor)
	insecureChannelProcessor(InsecureChannelProcessor)

	channelDecisionManager(ChannelDecisionManagerImpl) {
		channelProcessors = [secureChannelProcessor, insecureChannelProcessor]
	}

	channelProcessingFilter(ChannelProcessingFilter) {
		channelDecisionManager=channelDecisionManager
		filterInvocationDefinitionSource='''
			  CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
			  PATTERN_TYPE_APACHE_ANT
			  /login/**=REQUIRES_SECURE_CHANNEL
		      '''
	}
}
Comments 0 comments


IPTV and the Next Generation Television Experience

{ Dan Stieglitz // New Media // April 27, 2008 }

At The National Association of Broadcasters (NAB) conference two weeks ago I attended a keynote and panel discussion about IPTV. “Where we are now and what we have learned” was the title. The Keynote speaker was Microsoft’s SVP of Microsoft TV and both his speech and the subsequent panel discussion touched on several topics, including defining what that next-generation television experience really is, and how all of the supporting industries will be affected by the shift to whatever that viewer experience will be. His speech was quite Microsoft-centric, although he can’t really be faulted for that. All of the panelists agreed that it’s not clear what this experience will look and feel like although it will be two-way, not one-way as it is today and it will no longer be only about the best picture and sound quality. The experience itself; the interactivity (and therefore also the content) will be paramount. In fact, I’d venture to say that if the content was compelling enough, viewers will endure a weaker visual and audible experience.

The challenges to this new experience are many, including:

  • Lack of standards for getting video to viewers over the IP network, and also for getting information back from them
  • The need for a more scalable internet, larger address space, and cheaper bandwidth
  • New creative ideas about what two-way television feels like

IPTV today is the same television experience we’ve been used to, just delivered over IP networks. It’s prepackaged, completely closed and tightly controlled by industry. So what will this new set of content experience consist of? What will two-way TV look like? How will open source play in this new world? In throwing the ball around with some friends and colleagues we came up with some ideas:

  • Newscasts where people report news from their homes
  • Game shows where people can play-- live, from their living rooms
  • Potential for great, interactive educational programming

I’m curious to hear your ideas on this topic of the next-generation TV experience… what will it feel like?

Comments 0 comments


Tech Note: Grails Custom One-To-Many Scaffolding

{ Dan Stieglitz // Groovy/Grails // April 10, 2008 }

One small issue we have with Grails is that out-of-the-box it doesn't scaffold a UI to deal with one-to-many (OTM) relationships for existing objects. You can add a new instance of an entity to a container object when editing it, but if you have pre-existing objects you can't add them to the container. When you're in the early phases of an application and are tweaking your domain model this can be a big help. Here I'm going to present a quick way of modifying the scaffolding templates to allow you to generate a UI that can allow this behavior. There's a lot of value in knowing how to modify the Grails default behavior and this short tutorial should give you a little introduction into how Grails works under the covers.

Create the application

grails create-app OneToManyScaffolding

Create the domain model

In this example we create a Container and an Component object, where Container contains many Components.
grails create-domain-class Container
grails create-domain-class Component
Next, flesh out the domain objects:
class Component {
	
	String name
	
        String toString() {
		return name
	}
}
We implement the toString() method so that when the scaffold displays the objects in the UI, we'll get a value that has some meaning. We also build our Container domain class having a hasMany reference to our newly-created component class.
class Container {
	
        String name
	static hasMany = [ components : Component ]

        String toString() {
                return name
        }
}
Let's run the app to see what we get out-of-the-box. First we'll create a container using the UI (ContainerController -> New Container). When we attempt to edit our new container we get an edit screen with an "Add Component" link; however, clicking this link takes us to the "Create Component" screen. If we'd had some pre-created Components we wanted to add to this container the out-of-the-box UI would not allows us to do this. We can implement this behavior for the default UI by modifying the templates that generate these pages.

Install the scaffolding templates

First we'll need to install the templates themselves, and Grails makes this quite easy. You'll only need to issue:
grails install-templates
When this operation completes there will be a src/templates/scaffolding directory added to the application. This directory contains all of the Groovy templates that are used to generate the scaffolded pages when you issue a "generate-all ..." command. There is also a GSP that generates the "editor" for domain objects called "renderEditor.template" that contains logic we'll modify to get this working.

Modify the scaffolding templates

Open the renderEditor.template file and find the "renderOneToMany" method. The last line before the method returns generates the link we see that allows us to add (currently only new) objects to our container object. Add the following line below:
pw.println "
Associate ${property.referencedDomainClass.shortName}";
This will create an "Associate ..." link below the "Add ..." link on the Container edit page. Clicking on the link will call the "list" action of the component class and pass in 3 paramters: component_id, source, and callback. To complete the flow for associating the objects we'll need to create a new method, "choose," in the template that generates the controllers. This template is in the same scaffolding directory and is called Controller.groovy. Add the method definition to the end of the class:
    def choose = {
        redirect(controller:params.source,action:params.callback,params:params)
    }
We'll need to regenerate the controllers now since we've changed the scaffolding templates, so issue a "grails generate-all Container" and "grails generate-all Component."

Now we have to crack open the list template and modify it to produce links that know when we're trying to list instances and when we're trying to select an association. Each instance link is generated in an each closure near the bottom on the template. We'll add some code to generate a different link when a "callback" parameter is passed in, indicating we've come from an "Associate ..." link and not an "Add ..." link.

        
            \${${propertyName}.${p.name}?.encodeAsHTML()}
        
        
            \${${propertyName}.${p.name}?.encodeAsHTML()}
        
We've modified the behavior to call the "choose" method we implemented above on the Container class, which will in turn call the method specified in the "callback" parameter we've been passing around in the URLs. The callback method will be called on the "source" object also passed around. In this specific case, Grails expects to see an addComponent method in the Container controller, so let's go ahead and add that method:
    def addComponent = {
    	def container = Container.get(params["container_id"])
    	def component = Component.get(params["id"])
    	container.addToComponents(component)
    	render(view:'edit',model:[container:container])
    }
That completes the code for the flow, so now you should be able to add components to your model, and then associate them with a controller in your view. Be careful not to overwrite your custom controller methods when you regenerate controllers, or better yet, tweak this code so those methods can live in a service.

Comments 11 comments


Tech Note: Scaffolding JSON with Grails

{ Dan Stieglitz // Groovy/Grails // April 02, 2008 }

For the uninitiated, JSON “is a lightweight data-interchange format,” as humbly posted on JSON.org. It’s useful for architects in search of a lighter-than-XML transport or JavaScript developers who want service providers sending them easy to use objects for use in their pages. Grails has out-of-the-box JSON support via the JSONObject library, as well as through their converters “plugin” (which is now included in the core distribution). Converting grails domain objects to JSON (or XML, for the enthusiast) is as complicated as

render myDomainObject as JSON

and
render myDomainObject as XML

This is fantastic, and to include a JSON service in your app, you would simply add a method to your controller as such:
def json = {
    if(!params.max) params.max = 10
    render MyDomainObject.list( params ) as JSON
}

It doesn’t get better for the lazy developer, unless you want Grails to automatically add this method to each scaffolded controller class you generate. This is possible by customizing Grails’ scaffolding templates. First, install the templates by issuing
grails install-templates

at your project’s root. This will create the src/templates directory where the artifact and scaffold templates live. Crack open the src/templates/scaffolding/Controller.groovy file and add the following closure template:
def json = {
    if(!params.max) params.max = 10
    render ${className}.list( params ) as JSON
}

It’s essentially a copy of the list closure, except the controller will render a JSON string instead of passing a list to the view. You’ll also need to import the JSON converter so add this to the import section of the template:
import grails.converters.JSON;

That’s it, and the next time you generate a controller for one of your domain objects you can get a JSON list by hitting the /MyApp/MyDomainObject/json URL.

@see http://www.grails.org/Artifact+and+Scaffolding+Templates
@see http://www.json.org/

Comments 2 comments


Great article on Groovy DSLs

{ Dan Stieglitz // Groovy/Grails // March 12, 2008 }

Check out this article on writing domain-specific languages for Groovy

DSLs are a powerful feature of the language and for programming in general. It’s always advisable to give software users a language to interact with the software, rather than just a monolithic program that does very specific tasks.

Comments 0 comments


The launch of stainlesscode.com

{ Dan Stieglitz // Stainless Code // February 17, 2008 }

I’m finally happy to say we’re wrapping up the development of the new stainlesscode.com, and I’d like to give special thanks to the folks at Ripe Media (http://www.ripemedia.com) for doing a great job on the design and getting it all integrated on to our hardware. I hope that this new site is more than just a brochure for our company; I’d really like for it to be a better way for our team to communicate with our clients and the development community as a whole. We’ve been immersed in web 2.0 development for some time and have had little opportunity to actually leverage some of the great things about web 2.0 for ourselves. In some small way I hope the blogs on this site will positively impact development projects elsewhere through code examples, experiences and comments from readers.

I’m proud of our team and what they’ve done and I’m eager to have them share their expertise with others through this medium.

Comments 0 comments