Thursday, June 26, 2014

Porting to Foundation: Handling HTML5

Introduction

This post will focus on extending the Spring form tag lib.  As I discussed in my prior post we need to enhance the attribute handling of this library to utilize HTML5 input facilities in our application.

Most of the HTML5 attributes are traditional name value pairs and with the dynamic attribute handling provided by the current tag library this is sufficient for most of the new attributes. However there are a couple of attributes, specifically 'required' and 'autofocus', that we need to omit from the rendering if not needed.  For example if we attach the 'required' attribute and set it to false on an input element (required="false") that field will still be required.  To correctly generate HTML5 requires that we extend the Spring WebMVC form tag library to handle these attribute.

Fortunately, we will only need to extend a limited subset of the tags from the current form tag library.  The 'required' and 'autofocus' attribute handling needs to be injected into input, textarea, checkbox and select tags.  Implementing this functionality is not exceeding difficult.  To implement we need to;
  • Define the new tag library definition file (TLD file) containing the definitions of the tags we are extending.
Then for each tag we must;
  • Provide an implementations of the extended behavior.
  • Modify the tag definition to reference the extended class and add the new attributes we are extending.
  • And finally modify the tagx file to use the extended tag.

Defining the Tag Library File

The first step is to get the newly custom tag library functional is the creation of the tag library file definition.  This piece ties the Java implementation that we need to provide later to the tags in the JSP.

The tag definition library must be placed in the WEB-INF folder.  For the purposes here we need to make a copy of the Spring form tag library definition file and edit it to fit our needs.  A complete explanation of custom tag libraries is out of our focus here.  As mentioned before only the input, checkbox, select and textarea tags need to be extended so the first edit on this file should be to remove all the other tags to reduce its size.

Provide the Extended Tag Behavior

Then for each of the remaining tags we need to change the tag-class to reference the extended Java implementation of that class.  For example here is the Java class for the input tag;;

package com.springsource.petclinic.tag;

package com.springsource.petclinic.tag;

import javax.servlet.jsp.JspException;

import org.springframework.web.servlet.tags.form.InputTag;
import org.springframework.web.servlet.tags.form.TagWriter;

public class HTML5InputTag extends InputTag {

 private static final long serialVersionUID = 1L;

 private String required;

 private String autofocus;

 private String min ;
 
 private String max ;
 
 public String getAutofocus() {
  return autofocus;
 }

 public String getMax() {
  return max;
 }

 public String getMin() {
  return min;
 }

 public String getRequired() {
  return required;
 }

 public void setAutofocus(String autofocus) {
  this.autofocus = autofocus;
 }

 public void setMax(String max) {
  this.max = max;
 }

 public void setMin(String min) {
  this.min = min;
 }

 public void setRequired(String required) {
  this.required = required;
 }

 @Override
 protected void writeOptionalAttributes(TagWriter tagWriter) throws JspException {
  if (TextUtils.isTrue(required)) {
   writeOptionalAttribute(tagWriter, "required", "true");
  }
  if (TextUtils.isTrue(autofocus)) {
   writeOptionalAttribute(tagWriter, "autofocus", "true");
  }

  if (!TextUtils.isEmpty(min)) {
   writeOptionalAttribute(tagWriter, "min", min.trim());
  }
  
  if (!TextUtils.isEmpty(autofocus)) {
   writeOptionalAttribute(tagWriter, "max", max.trim());
  }

  super.writeOptionalAttributes(tagWriter);
 }

}


Here the custom input extends the Spring provided implementation adding a collection of new attributes and exposing it by offering getter and setter methods.  To handle the rendering the class overrides the writeOptionalAttributes method.  This method is invoked during the rendering of the tag and allows the attributes to be optionally injected into the resulting markup.

With the extension of the input class I have also included handling of the 'min' and 'max' attributes.  Unlike the 'required' and 'autofocus' attributes these attributes are injected into the markup only if not null or empty strings.  Adding these attributes allows streamlining of those attributes in the input.tagx file.

Modify the Tag Definition

Now we need to modify the tags definition in the tag definition file (TLD) that we created earlier.  There are two updates to the tag that need to made.  First the tag-class element needs to reference our newly implemented tag extension class.  And second we need to add the attribute definitions for the new attributes being handled.

Here is the resulting tag definition for the input tag;

 <tag>
  <description>Renders an HTML 'input' tag with type 'text' using the bound value.</description>
  <name>input</name>
  <tag-class>com.springsource.petclinic.tag.HTML5InputTag</tag-class>
  <body-content>empty</body-content>

  <!-- a bunch of attribute definitions omitted here >

  <attribute>
   <description>HTML5 Attribute</description>
   <name>required</name>
   <required>false</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  <attribute>
   <description>HTML5 Attribute</description>
   <name>autofocus</name>
   <required>false</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  <attribute>
   <description>HTML5 Attribute</description>
   <name>min</name>
   <required>false</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  <attribute>
   <description>HTML5 Attribute</description>
   <name>max</name>
   <required>false</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  <dynamic-attributes>true</dynamic-attributes>
 </tag>


Modify the input.tagx File

The last part of the implementation is to modify the tagx file to use the extended tag.  Doing this requires that we change the 'form' namespace declaration to refer to the extended tag library definition rather then the Spring provided one.

Here is the root element definition from the input tagx file as generated by Roo;

<jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core" 
 xmlns:fn="http://java.sun.com/jsp/jstl/functions" 
 xmlns:spring="http://www.springframework.org/tags" 
 xmlns:form="http://www.springframework.org/tags/form" 
 xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">



And here is the modified element;

<jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core" 
 xmlns:fn="http://java.sun.com/jsp/jstl/functions" 
 xmlns:spring="http://www.springframework.org/tags" 
 xmlns:html5="urn:jsptld:/WEB-INF/html5-form.tld"
 xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">


Now in the input element we have to refactor the form namespace elements to use the new namespace.  It is also here where the new functionality of the tag library can now be utilized.  In the original application the form:input tag code has;

              <form:input id="_${sec_field}_id" path="${sec_field}" disabled="${disabled}" />

Now in that code we can write;

<html5:input id="_${sec_field}_id" type="${type}"
 path="${sec_field}" disabled="${disabled}"
 required="${required}" pattern="${validationRegex}"
 minLength="${min}" maxLength="${max}" min="${minDecimal}"
 max="${maxDecimal}" step="${step}" />


The application tagx files can now take full advantage of the new HTML5 goodies, including the 'required' attribute..  What remains to be done at this point is providing similar implementations for all the input controls that we identified earlier.  With mix-ins this would be a snap but unfortunately right now we have to maintain some similar code.

This leads us to the end of this section.  My next post will proceed from here and continue the implementation for HTML5 tags for the pet clinic application.

Connecting Spring Security Authentication to Domain Entities

Introduction

With about every consumer facing web application today the need to allow users to create and maintain accounts within the web application is a requirement.

Spring Roo provides the ability to integrate Spring Security into web applications readily via a simple installation command.  By default the scaffold-ed implementation provides a rudimentary authentication implementation configured in the applicationContext-security.xml file.  It looks like this;

    <!-- Configure Authentication mechanism -->
    <authentication-manager alias="authenticationManager">
        <!-- SHA-256 values can be produced using 'echo -n your_desired_password | sha256sum' (using normal *nix environments) -->
        <authentication-provider>
            <password-encoder hash="sha-256" />
            <user-service>
                <user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN" />
                <user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>

    

This of course is inadequate for production use, except for exceptional cases.  What we need is a convenient way to integrate the web applications entity model, again scaffold-ed by Roo, with the Spring Security infrastructure.

What we need is for Spring security to authenticate using our web application entity model.  Doing this is simple, there are two main parts of the solution.  First, we need to implement the user data interface that consumed by Spring security to access the application domain model.  And course we need to reconfigure the security application context to use that implementation.

Spring security uses a component that implements UserDetailService as the source of user information.  We need to provide an implementation that uses our web applications entity model as the source of user data.  Again there are two tasks needed to accomplish this.  First we need to provide a implementation of the expected component.  And we must design our application user entity (or AppUser) to provide the needed data.

The AppUser must provide minimal authentication data, username and password.  But there are additional features available like, account, credential locking, and expiration features that the application may want to integrate with.  Supporting a majority of these features can be done trivially utilizing Roo's scaffolding, with the exception of passwords.  But why should that be a surprise.

Encoding Passwords

Everybody knows clear text passwords should never be stored.  When authenticating Spring Security expects the password provided by our application to be encoded.  To encode passwords we need to use the same password encoder implementation that  the security infrastructure uses.  There are multiple implementations of encoders some more easily cracked then others.  But of course higher security usually translates in more computing and operating costs.  However keep in mind changing the algorithm used by the application will invalidate all existing passwords so careful up front selection is advised since changing this once in service will impact user experience.

When saving passwords in the AppUser object we need to encode the password.  Via Spring configuration we can set the encoder that the security infrastructure will utilize.  Additionally, that will allow auto wiring the encode into application code.  Using the encoder is simply just a matter of passing the clear text password to the encode method to obtain the encoded password.  From this point it is just a matter of including the encoding functionality when storing passwords.

Here is my controller handles the user registration.  Note there are two parts of the code that participate in the encoding password process.  First the auto wiring of the 'encoder' bean into the controller so it can be accessed.  Then later in the code when setting the password the encoder is utilized to do the encoding.

package com.repik.buddyframework.web;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.roo.addon.web.mvc.controller.scaffold.RooWebScaffold;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.repik.buddyframework.domain.AppUser;
import com.repik.buddyframework.domain.Profile;
import com.repik.buddyframework.domain.ProfilePreferences;

@RequestMapping("/appusers")
@Controller
@RooWebScaffold(path = "appusers", formBackingObject = AppUser.class)
public class AppUserController {

 @Autowired
 private PasswordEncoder encoder ;
 
 @RequestMapping(value = "/register", method = RequestMethod.POST, produces = "text/html")
    public String register(@Valid AppUser appUser, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
        if (! bindingResult.hasErrors()
          && appUser.getPassword().equals(appUser.getConfirmPassword())
          && appUser.getEmail().equals(appUser.getConfirmEmail())) {
         try {
             uiModel.asMap().clear();
             appUser.setAccountNotExpired(Boolean.TRUE);
             appUser.setAccountNotLocked(Boolean.TRUE);
             appUser.setAuthorities( "Guest");
             appUser.setCredentialsNotExpired(Boolean.TRUE);
             appUser.setEnabled(Boolean.TRUE);
             
             // set the password to the encoded hash value
             appUser.setPassword( encoder.encode( appUser.getPassword()));
             
             appUser.persist();
             return "redirect:/login" ;
         }
         catch ( JpaSystemException jse ) {
          Throwable cause = jse.getCause() ;
          boolean handled = false ;
          while ( cause != null ) {
           if ( cause instanceof ConstraintViolationException ) {
                  bindingResult.addError( new FieldError("appUser", "username", "username already taken" ));
                  cause = null ;
                  handled = true ;
           }
           else {
            cause = cause.getCause() ;
           }
          }
          
          if ( ! handled )
           throw jse ;
         }
        }

        populateEditForm(uiModel, appUser); 
        return "appusers/register";
    }
 
    @RequestMapping(value ="/register", params = "form", produces = "text/html")
    public String registerForm(Model uiModel) {
        populateEditForm(uiModel, new AppUser());
        return "appusers/register";
    }

    
}

Implementing the UserDetailsService

Next we need to provide an implementation of the UserDetailsService.  Spring Security uses this component to obtain user details.  We our implementation to access the application user domain object rather then the default implementation.

The implementation is pretty simple.  The UserDetailsService interface requires a single method, loadUserByUserName, where the usage is a user name is provided as a string and the component should return a UserDetails object for that user.  While is was tempting during implementation to allow the AppUser domain object itself implement this interface, instead to keep things simple this implementation uses a data transfer object instead.

The logic just involves finding the AppUser by username, then if found populate a User instance to return to the Spring Security infrastructure.  The first part of the implementation will be to create a finder to allow finding AppUsers by username.  This is done will in the Roo shell with the following command;

focus --class ~.domain.AppUser
finder add --finderName findAppUsersByUsernameEquals

Now the UserDetailsService implementation can be completed;

package com.repik.buddyframework.domain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.TypedQuery;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class AppUserDetailsService implements UserDetailsService {

 @Override
 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  
  TypedQuery<AppUser> appUsers = AppUser.findAppUsersByUsernameEquals(username);
  AppUser appUser = appUsers.getSingleResult() ;
  return appUser == null 
    ? null 
    : new User(appUser.getUsername(), 
      appUser.getPassword(), 
      appUser.getEnabled(), 
      appUser.getAccountNotExpired(),
      appUser.getCredentialsNotExpired(),
      appUser.getAccountNotLocked(),
      getAuthorities( appUser.getAuthorities())) ; 
 }
 
 private Collection<? extends GrantedAuthority> getAuthorities( String authorities ) {
  if ( authorities == null ) {
   return null ;
  }
  
  List<GrantedAuthority> result = new ArrayList<GrantedAuthority>() ;
  
  String[] tokens = authorities.split( "\\W" ) ;
  for ( int i = 0 ; i < tokens.length ; i++ ) {
   result.add( new SimpleGrantedAuthority(tokens[ i ])) ;
  }
  
  return result ;
  
 }


Configuring the Security Application Context

All now that remains is to configure Spring security to utilize the new implementation of the UserDetailService.  The configuration is contained in the 'applicationContext-security.xml' file.  Specifically towards the end of the file we need to configure the authentication provider to use our implementation of the UserDetailService.  Note also that the encoder bean is defined here allowing the use within the application context.

    <!-- Configure Authentication mechanism -->
    <authentication-manager alias="authenticationManager">
  <authentication-provider user-service-ref="customUserDetailsService">
   <password-encoder ref="encoder"/>
  </authentication-provider>
    </authentication-manager>

    <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/&gt
    
<beans:bean id="customUserDetailsService" class="com.repik.buddyframework.domain.AppUserDetailsService" />

Now the implementation is complete.  Most of our effort in the implementation here really centered around integrating our AppUser domain object to provide the user data conform to that required Spring Security.

Sunday, June 15, 2014

Revisiting the Design of Restful Service API's

As part of an on going side project, I've been building a couple of services into a web site that handles images provided by guests of the application.  For production we need to manage these images, involving cleaning them up and optimizing them for delivery to the presentation.

First during the upload service we will need to prepare the image for handling by the application.  Then during viewing the service layer will needs to provide different renderings of the image as required by the application presentation.

Subsequently the application will need a image service to provide this functionality.  This image service will need to allow the presentation layer of the image to request the size of the image.  Also in production it is almost certain that this service will be cached.

So the question arose what is the best practice for handling service arguments for RESTful services?  In our example here we have three arguments; the id of the image along with the width and height of the image.  With the id argument the decision is straight forward, it should be part of the URL.  However with the width and height arguments things are not so simple. Should it be a query parameter or a path segment in the URL?

There are pluses and minus's to either route.  Putting path segments in the URL presents problems when arguments are optional.  The nature of the services response changes for handling missing results depends also on how the argument is passed. When passing arguments as a path segment the service should return a 404 status, while with query parameters and empty result set should be returned.

This in turn leads to the question of 'What are the best practices for determining how to send service arguments to the service layer of the application'?

While seeking that answer I ran across this on Stacktrace.  This is a great response in the sense that it provides a framework for determining how data is passed to the service layer given the type of data.

Late answer but I'll add some additional insight to what has been shared, namely that there are several types of "parameters" to a request, and you should take this into account.
  1. Locators - E.g. resource identifiers such as IDs or action/view
  1. Filters - E.g. parameters that provide a search for, sorting or narrow down the set of results.
  1. State - E.g. session identification, api keys, whatevs.
  1. Content - E.g. data to be stored.
Now let's look at the different places where these parameters could go. 
  1. Request headers & cookies
  1. URL query string ("GET" vars)
  1. URL paths
  1. Body query string/multipart ("POST" vars)
Generally you want State to be set in headers or cookies, depending on what type of state information it is. I think we can all agree on this. Use custom http headers (X-My-Header) if you need to. 
Similarly, Content only has one place to belong, which is in the request body, either as query strings or as http multipart and/or JSON content. This is consistent with what you receive from the server when it sends you content. So you shouldn't be rude and do it differently. 
Locators such as "id=5" or "action=refresh" or "page=2" would make sense to have as a URL path, such as mysite.com/article/5/page=2 where partly you know what each part is supposed to mean (the basics such as article and 5 obviously mean get me the data of type article with id 5) and additional parameters are specified as part of the URI. They can be in the form of page=2, or page/2 if you know that after a certain point in the URI the "folders" are paired key-values. 
Filters always go in the query string, because while they are a part of finding the right data, they are only there to return a subset or modification of what the Locators return alone. The search in mysite.com/article/?query=Obama (subset) is a filter, and so is /article/5?order=backwards(modification). Think about what it does, not just what it's called! 
If "view" determines output format, then it is a filter (mysite.com/article/5?view=pdf) because it returns a modification of the found resource rather than homing in on which resource we want. If it instead decides which specific part of the article we get to see (mysite.com/article/5/view=summary) then it is a locator. 
Remember, narrowing down a set of resources is filtering. Locating something specific within a resource is locating... duh. Subset filtering may return any number of results (even 0). Locating will always find that specific instance of something (if it exists). Modification filtering will return the same data as the locator, except modified (if such a modification is allowed). 
Hope this helped give people some eureka moments if they've been lost about where to put stuff!


Here is the link to the original page;

http://stackoverflow.com/questions/4024271/rest-api-best-practices-where-to-put-parameters

Cheers!