1675 lines
96 KiB
XML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8"?>
<article version="5.0" xml:lang="en-US" xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink">
<info>
<title>Bootstrap a Web Application with Spring 4</title>
</info>
<anchor xml:id="wrapper"/>
<anchor xml:id="inner-wrapper"/>
<!--
/#side-nav
-->
<!--
/.menus
-->
<para><link linkend="top">Return to Content</link></para>
<!--
#content Starts
-->
<anchor xml:id="content"/>
<anchor xml:id="main-sidebar-container"/>
<!--
#main Starts
-->
<anchor xml:id="toc_container"/>
<para>Contents</para>
<itemizedlist>
<listitem>
<para><link linkend="Table_of_Contents">Table of Contents</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.1_Overview">1. Overview</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.2_The_Maven_pomxml">2. The Maven pom.xml</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.3_The_Java_based_Web_Configuration">3. The Java based Web Configuration</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.4_Conclusion">4. Conclusion</link></para>
</listitem>
</itemizedlist>
<para>If you&apos;re new here, <link xl:href="https://my.leadpages.net/leadbox/146382273f72a2%3A13a71ac76b46dc/5735865741475840/">you may want to get my &quot;REST APIs with Spring&quot; eBook</link>. Thanks for visiting!</para>
<para><link xl:href=""/></para>
<!--
Start Shortcoder content
-->
<!--
End Shortcoder content
-->
<section>
<title><anchor xml:id="Table_of_Contents"/><emphasis role="bold">Table of Contents</emphasis></title>
<itemizedlist>
<listitem>
<para><link linkend="overview"><emphasis role="bold">1. </emphasis>Overview</link></para>
</listitem>
<listitem>
<para><link linkend="maven"><emphasis role="bold">2. </emphasis>The Maven pom.xml</link></para>
</listitem>
<listitem>
<para><link linkend="cglib"><emphasis role="bold">    2.1. </emphasis>Justification of the <emphasis>cglib</emphasis> dependency</link></para>
</listitem>
<listitem>
<para><link linkend="cglib_gone"><emphasis role="bold">    2.2. </emphasis>The <emphasis>cglib</emphasis> dependency in Spring 3.2 and beyond</link></para>
</listitem>
<listitem>
<para><link linkend="java_config"><emphasis role="bold">3. </emphasis>The Java based web configuration</link></para>
</listitem>
<listitem>
<para><link linkend="web_xml"><emphasis role="bold">   3.1. </emphasis>The web.xml</link></para>
</listitem>
<listitem>
<para><link linkend="conclusion"><emphasis role="bold">4. </emphasis>Conclusion</link></para>
</listitem>
</itemizedlist>
<section xml:id="overview.1">
<title><anchor xml:id="dbdoclet.1_Overview"/><emphasis role="bold">1. Overview</emphasis></title>
<para>The tutorial illustrates how to <emphasis role="bold">Bootstrap a Web Application with Spring</emphasis> and also discusses how to make the jump <emphasis role="bold">from XML to Java</emphasis> without having to completely migrate the entire XML configuration.</para>
</section>
<section xml:id="maven.1">
<title><anchor xml:id="dbdoclet.2_The_Maven_pomxml"/><emphasis role="bold">2. The Maven pom.xml</emphasis></title>
<screen>&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xsi:schemaLocation=&quot;
http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;groupId&gt;org&lt;/groupId&gt;
&lt;artifactId&gt;rest&lt;/artifactId&gt;
&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
&lt;packaging&gt;war&lt;/packaging&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.springframework&lt;/groupId&gt;
&lt;artifactId&gt;spring-webmvc&lt;/artifactId&gt;
&lt;version&gt;${spring.version}&lt;/version&gt;
&lt;exclusions&gt;
&lt;exclusion&gt;
&lt;artifactId&gt;commons-logging&lt;/artifactId&gt;
&lt;groupId&gt;commons-logging&lt;/groupId&gt;
&lt;/exclusion&gt;
&lt;/exclusions&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;build&gt;
&lt;finalName&gt;rest&lt;/finalName&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
&lt;version&gt;3.1&lt;/version&gt;
&lt;configuration&gt;
&lt;source&gt;1.6&lt;/source&gt;
&lt;target&gt;1.6&lt;/target&gt;
&lt;encoding&gt;UTF-8&lt;/encoding&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;
&lt;properties&gt;
&lt;spring.version&gt;4.0.5.RELEASE&lt;/spring.version&gt;
&lt;/properties&gt;
&lt;/project&gt;</screen>
<section xml:id="cglib.1">
<title><emphasis role="bold">2.1. The cglib dependency before Spring 3.2</emphasis></title>
<para>You may wonder why <emphasis>cglib</emphasis> is a dependency it turns out there is a valid reason to include it the entire configuration cannot function without it. If removed, Spring will throw:</para>
<para><emphasis>Caused by: java.lang.IllegalStateException: CGLIB is required to process @Configuration classes. Either add CGLIB to the classpath or remove the following @Configuration bean definitions</emphasis></para>
<para>The reason this happens is explained by the way Spring deals with <emphasis>@Configuration</emphasis> classes. These classes are effectively beans, and because of this they need to be aware of the Context, and respect scope and other bean semantics. This is achieved by dynamically creating a cglib proxy with this awareness for each <emphasis>@Configuration</emphasis> class, hence the cglib dependency.</para>
<para>Also, because of this, there are a few restrictions for <emphasis>Configuration</emphasis> annotated classes:</para>
<itemizedlist>
<listitem>
<para> Configuration classes <emphasis role="bold">should not be final</emphasis></para>
</listitem>
<listitem>
<para> They should have a constructor with no arguments</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="cglib_gone.1">
<title><emphasis role="bold">2.2. The cglib dependency in Spring 3.2 and beyond</emphasis></title>
<para>Starting with Spring 3.2, it is <emphasis role="bold">no longer necessary to add cglib as an explicit dependency</emphasis>. This is because Spring is in now inlining <emphasis>cglib</emphasis> which will ensure that all class based proxying functionality will work out of the box with Spring 3.2.</para>
<para>The new cglib code is placed under the Spring package: <emphasis>org.springframework.cglib</emphasis> (replacing the original <emphasis>net.sf.cglib</emphasis>). The reason for the package change is to avoid conflicts with any <emphasis>cglib</emphasis> versions already existing on the classpath.</para>
<para>Also, the new cglib 3.0 is now used, upgraded from the older 2.2 dependency (see this <link xl:href="https://jira.springsource.org/browse/SPR-9669">JIRA issue</link> for more details).</para>
<para>Finally, now that Spring 4.0 is out in the wild, changes like this one (removing the cglib dependency) are to be expected with Java 8 just around the corner you can watch <link xl:href="https://jira.springsource.org/browse/SPR-9639">this Spring Jira</link> to keep track of the Spring support, and <link xl:href="http://www.baeldung.com/java8">the Java 8 Resources page</link> to keep tabs on the that.</para>
</section>
</section>
<section xml:id="java_config.1">
<title><anchor xml:id="dbdoclet.3_The_Java_based_Web_Configuration"/><emphasis role="bold">3. The Java based Web Configuration</emphasis></title>
<screen>@Configuration
@ImportResource( { &quot;classpath*:/rest_config.xml&quot; } )
@ComponentScan( basePackages = &quot;org.rest&quot; )
@PropertySource({ &quot;classpath:rest.properties&quot;, &quot;classpath:web.properties&quot; })
public class AppConfig{
@Bean
   public static PropertySourcesPlaceholderConfigurer properties() {
   return new PropertySourcesPlaceholderConfigurer();
   }
}</screen>
<para>First, the <emphasis role="bold">@Configuration</emphasis> annotation this is the main artifact used by the Java based Spring configuration; it is itself meta-annotated with <emphasis>@Component</emphasis>, which makes the annotated classes <emphasis role="bold">standard beans</emphasis> and as such, also candidates for component scanning. The main purpose of <emphasis>@Configuration</emphasis> classes is to be sources of bean definitions for the Spring IoC Container. For a more detailed description, see the <link xl:href="http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-java">official docs</link>.</para>
<para>Then, <emphasis role="bold">@ImportResource</emphasis> is used to import the existing XML based Spring configuration. This may be configuration which is still being migrated from XML to Java, or simply legacy configuration that you wish to keep. Either way, importing it into the Container is essential for a successful migration, allowing small steps without to much risk. The equivalent XML annotation that is replaced is:</para>
<para><emphasis>&lt;import resource=”classpath*:/rest_config.xml” /&gt;</emphasis></para>
<para>Moving on to <emphasis role="bold">@ComponentScan</emphasis> this configures the component scanning directive, effectively replacing the XML:</para>
<screen>&lt;context:component-scan base-package=&quot;org.rest&quot; /&gt;</screen>
<para>As of Spring 3.1, the <emphasis>@Configuration</emphasis> are excluded from classpath scanning by default see <link xl:href="https://jira.springsource.org/browse/SPR-8808">this JIRA issue</link>. Before Spring 3.1 though, these classes should have been excluded explicitly:</para>
<screen>excludeFilters = { @ComponentScan.Filter( Configuration.class ) }</screen>
<para>The <emphasis>@Configuration</emphasis> classes should not be autodiscovered because they are already specified and used by the Container allowing them to be rediscovered and introduced into the Spring context will result in the following error:</para>
<para><emphasis>Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name webConfig for bean class [org.rest.spring.AppConfig] conflicts with existing, non-compatible bean definition of same name and class [org.rest.spring.AppConfig]</emphasis></para>
<para>And finally, using the<emphasis role="bold"> @Bean</emphasis> annotation to configure the <emphasis role="bold">properties support</emphasis> – <emphasis>PropertySourcesPlaceholderConfigurer</emphasis> is initialized in a <emphasis>@Bean</emphasis> annotated method, indicating it will produce a Spring bean managed by the Container. This new configuration has replaced the following XML:</para>
<screen>&lt;context:property-placeholder
location=&quot;classpath:persistence.properties, classpath:web.properties&quot;
ignore-unresolvable=&quot;true&quot;/&gt;</screen>
<para>For a more in depth discussion on why it was necessary to manually register the <emphasis>PropertySourcesPlaceholderConfigurer</emphasis> bean, see the <link xl:href="http://www.baeldung.com/2012/02/06/properties-with-spring/">Properties with Spring Tutorial</link>.</para>
<section xml:id="web_xml.1">
<title><emphasis role="bold">3.1. The web.xml</emphasis></title>
<screen>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app xmlns=&quot;
http://java.sun.com/xml/ns/javaee&quot;
     xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&quot;
     xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&quot;
    id=&quot;rest&quot; version=&quot;3.0&quot;&gt;
&lt;context-param&gt;
&lt;param-name&gt;contextClass&lt;/param-name&gt;
&lt;param-value&gt;
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
&lt;/param-value&gt;
&lt;/context-param&gt;
&lt;context-param&gt;
&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
&lt;param-value&gt;org.rest.spring.root&lt;/param-value&gt;
&lt;/context-param&gt;
&lt;listener&gt;
&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
&lt;/listener&gt;
&lt;servlet&gt;
&lt;servlet-name&gt;rest&lt;/servlet-name&gt;
&lt;servlet-class&gt;
org.springframework.web.servlet.DispatcherServlet
&lt;/servlet-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;contextClass&lt;/param-name&gt;
&lt;param-value&gt;
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;init-param&gt;
&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
&lt;param-value&gt;org.rest.spring.rest&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;rest&lt;/servlet-name&gt;
&lt;url-pattern&gt;/api/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
&lt;welcome-file-list&gt;
&lt;welcome-file /&gt;
&lt;/welcome-file-list&gt;
&lt;/web-app&gt;</screen>
<para> First, the root context is defined and configured to use <emphasis>AnnotationConfigWebApplicationContext</emphasis> instead of the default <emphasis>XmlWebApplicationContext</emphasis>. The newer <emphasis>AnnotationConfigWebApplicationContext</emphasis> accepts <emphasis>@Configuration</emphasis> annotated classes as input for the Container configuration and is needed in order to set up the Java based context. Unlike <emphasis>XmlWebApplicationContext</emphasis>, it assumes no default configuration class locations, so the <emphasis>“contextConfigLocation”</emphasis><emphasis>init-param</emphasis> for the Servlet must be set. This will point to the java package where the <emphasis>@Configuration</emphasis> classes are located; the fully qualified name(s) of the classes are also supported.</para>
<para>Next, the <emphasis>DispatcherServlet</emphasis> is configured to use the same kind of context, with the only difference that its loading configuration classes out of a different package.</para>
<para>Other than this, the <emphasis>web.xml</emphasis> doesnt really change from a XML to a Java based configuration.</para>
</section>
</section>
<section xml:id="conclusion.1">
<title><anchor xml:id="dbdoclet.4_Conclusion"/><emphasis role="bold">4. Conclusion</emphasis></title>
<para>The presented approach allows for a smooth <emphasis role="bold">migration of the Spring configuration</emphasis> from XML to Java, mixing the old and the new. This is important for older projects, which may have a lot of XML based configuration that cannot be migrated all at once.</para>
<para>This way, in a migration, the XML beans can be ported in small increments.</para>
<para>In <link xl:href="http://www.baeldung.com/2011/10/25/building-a-restful-web-service-with-spring-3-1-and-java-based-configuration-part-2/">the next article on REST with Spring</link>, I cover setting up MVC in the project, configuration of the HTTP status codes, payload marshalling and content negotiation.</para>
<para><link xl:href="https://my.leadpages.net/leadbox/147e9e473f72a2%3A13a71ac76b46dc/5745710343389184/">The implementation of this <emphasis>Bootstrap a Spring Web App Tutorial</emphasis> can be downloaded as a working sample project.</link></para>
<para>This is an Eclipse based project, so it should be easy to import and run as it is.</para>
<!--
Start Shortcoder content
-->
<para>  </para>
<!--
End Shortcoder content
-->
<para><link xl:href=""/></para>
<anchor xml:id="dd_ajax_float"/>
<para><link xl:href="http://twitter.com/share"/></para>
<!--
OptinSkin
-->
<anchor xml:id="ois_12"/>
<!--
End OptinSkin
-->
<!--
/.entry
-->
<para><emphasis role="italic"/><link xl:href="http://www.baeldung.com/tag/java-2/">java</link>, <link xl:href="http://www.baeldung.com/tag/spring/">Spring</link></para>
<!--
/.post
-->
<!--
/#main
-->
<anchor xml:id="optinskin-widget-3"/>
<!--
OptinSkin
-->
<anchor xml:id="ois_5"/>
<!--
End OptinSkin
-->
<!--
/#sidebar
-->
<!--
/#main-sidebar-container
-->
<!--
/#content
-->
<anchor xml:id="copyright"/>
<para>© 2014 Baeldung. All Rights Reserved. </para>
<anchor xml:id="credit"/>
<!--
/#inner-wrapper
-->
<!--
/#wrapper
-->
<!--
/.fix
-->
<!--
ngg_resource_manager_marker
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 Begin
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 End
-->
</section>
</section>
</article>
<?xml version="1.0" encoding="UTF-8"?>
<article version="5.0" xml:lang="en-US" xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink">
<info>
<title>Build a REST API with Spring 4 and Java Config</title>
</info>
<anchor xml:id="wrapper"/>
<anchor xml:id="inner-wrapper"/>
<!--
/#side-nav
-->
<!--
/.menus
-->
<para><link linkend="top">Return to Content</link></para>
<!--
#content Starts
-->
<anchor xml:id="content"/>
<anchor xml:id="main-sidebar-container"/>
<!--
#main Starts
-->
<anchor xml:id="toc_container"/>
<para>Contents</para>
<itemizedlist>
<listitem>
<para><link linkend="Table_of_Contents">Table of Contents</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.1_Overview">1. Overview</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.2_Understanding_REST_in_Spring">2. Understanding REST in Spring </link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.3_The_Java_configuration">3. The Java configuration</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.4_Testing_the_Spring_context">4. Testing the Spring context</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.5_The_Controller">5. The Controller</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.6_Mapping_the_HTTP_response_codes">6. Mapping the HTTP response codes</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.7_Additional_Maven_dependencies">7. Additional Maven dependencies </link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.8_Conclusion">8. Conclusion</link></para>
</listitem>
</itemizedlist>
<para>If you&apos;re new here, <link xl:href="https://my.leadpages.net/leadbox/146382273f72a2%3A13a71ac76b46dc/5735865741475840/">you may want to get my &quot;REST APIs with Spring&quot; eBook</link>. Thanks for visiting!</para>
<para><link xl:href=""/></para>
<!--
Start Shortcoder content
-->
<para>  </para>
<!--
End Shortcoder content
-->
<section>
<title><anchor xml:id="Table_of_Contents"/><emphasis role="bold">Table of Contents</emphasis></title>
<itemizedlist>
<listitem>
<para><link linkend="overview"><emphasis role="bold">1. </emphasis>Overview</link></para>
</listitem>
<listitem>
<para><link linkend="rest"><emphasis role="bold">2. </emphasis>Understanding REST in Spring</link></para>
</listitem>
<listitem>
<para><link linkend="java-config"><emphasis role="bold">3. </emphasis>The Java configuration</link></para>
</listitem>
<listitem>
<para><link linkend="test"><emphasis role="bold">4. </emphasis>Testing the Spring context</link></para>
</listitem>
<listitem>
<para><link linkend="controller"><emphasis role="bold">5. </emphasis>The Controller</link></para>
</listitem>
<listitem>
<para><link linkend="http-codes"><emphasis role="bold">6. </emphasis>Mapping the HTTP response codes</link></para>
</listitem>
<listitem>
<para><link linkend="ch_6_1"><emphasis role="bold">    6.1. </emphasis>Unmapped requests</link></para>
</listitem>
<listitem>
<para><link linkend="ch_6_2"><emphasis role="bold">    6.2. </emphasis>Valid, mapped requests</link></para>
</listitem>
<listitem>
<para><link linkend="ch_6_3"><emphasis role="bold">    6.3. </emphasis>Client error</link></para>
</listitem>
<listitem>
<para><link linkend="ch_6_4"><emphasis role="bold">    6.4. </emphasis>Using <emphasis>@ExceptionHandler</emphasis></link></para>
</listitem>
<listitem>
<para><link linkend="maven"><emphasis role="bold">7. </emphasis>Additional Maven dependencies</link></para>
</listitem>
<listitem>
<para><link linkend="conclusion"><emphasis role="bold">8. </emphasis>Conclusion</link></para>
</listitem>
</itemizedlist>
<section xml:id="overview.1">
<title><anchor xml:id="dbdoclet.1_Overview"/><emphasis role="bold">1. Overview</emphasis></title>
<para>This article shows how to <emphasis role="bold">set up REST in Spring</emphasis> the Controller and HTTP response codes, configuration of payload marshalling and content negotiation.</para>
</section>
<section xml:id="rest.1">
<title><anchor xml:id="dbdoclet.2_Understanding_REST_in_Spring"/><emphasis role="bold">2. Understanding REST in Spring</emphasis> </title>
<para>The Spring framework supports 2 ways of creating RESTful services:</para>
<itemizedlist>
<listitem>
<para> using MVC with <emphasis>ModelAndView</emphasis></para>
</listitem>
<listitem>
<para> using HTTP message converters</para>
</listitem>
</itemizedlist>
<para>The <emphasis role="bold">ModelAndView</emphasis> approach is older and much better documented, but also more verbose and configuration heavy. It tries to shoehorn the REST paradigm into the old model, which is not without problems. The Spring team understood this and provided first-class REST support starting with <emphasis role="bold">Spring 3.0</emphasis>.</para>
<para>The new approach, based on <emphasis role="bold">HttpMessageConverter</emphasis>and<emphasis role="bold"> annotations</emphasis>, is much more lightweight and easy to implement. Configuration is minimal and it provides sensible defaults for what you would expect from a RESTful service. It is however newer and a a bit on the light side concerning documentation; whats , the reference doesnt go out of its way to make the distinction and the tradeoffs between the two approaches as clear as they should be. Nevertheless, this is the way RESTful services should be build after Spring 3.0.</para>
</section>
<section xml:id="java-config.1">
<title><anchor xml:id="dbdoclet.3_The_Java_configuration"/><emphasis role="bold">3. The Java configuration</emphasis></title>
<para><link xl:href="http://www.baeldung.com/wp-content/uploads/2013/11/SPRING-JAVA-CONFIGURATION.jpg"/></para>
<screen>@Configuration
@EnableWebMvc
public class WebConfig{
//
}</screen>
<para>The new <emphasis role="bold">@EnableWebMvc</emphasis> annotation does a number of useful things specifically, in the case of REST, it detect the existence of Jackson and JAXB 2 on the classpath and automatically creates and registers default <emphasis role="bold">JSON and XML converters</emphasis>. The functionality of the annotation is equivalent to the XML version:</para>
<para><emphasis>&lt;mvc:annotation-driven /&gt;</emphasis></para>
<para>This is a shortcut, and though it may be useful in many situations, its not perfect. When more complex configuration is needed, remove the annotation and extend <emphasis>WebMvcConfigurationSupport</emphasis> directly.</para>
</section>
<section xml:id="test.1">
<title><anchor xml:id="dbdoclet.4_Testing_the_Spring_context"/><emphasis role="bold">4. Testing the Spring context</emphasis></title>
<para>Starting with <emphasis role="bold">Spring 3.1</emphasis>, <link xl:href="http://spring.io/blog/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles/">we get</link> first-class testing support for <emphasis>@Configuration</emphasis> classes:</para>
<screen>@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( classes = { ApplicationConfig.class, PersistenceConfig.class },
loader = AnnotationConfigContextLoader.class )
public class SpringTest{
@Test
public void whenSpringContextIsInstantiated_thenNoExceptions(){
// When
}
}</screen>
<para>The Java configuration classes are simply specified with the <emphasis role="bold">@ContextConfiguration</emphasis> annotation and the new <emphasis>AnnotationConfigContextLoader</emphasis> loads the bean definitions from the <emphasis>@Configuration</emphasis> classes.</para>
<para>Notice that the <emphasis>WebConfig</emphasis> configuration class was not included in the test because it needs to run in a Servlet context, which is not provided.</para>
</section>
<section xml:id="controller.1">
<title><anchor xml:id="dbdoclet.5_The_Controller"/><emphasis role="bold">5. The Controller</emphasis></title>
<para>The <emphasis role="bold">@Controller</emphasis> is the central artifact in the entire Web Tier of the RESTful API. For the purpose of this post, the controller is modeling a simple REST resource <emphasis>Foo</emphasis>:</para>
<screen>@Controller
@RequestMapping( value = &quot;/foos&quot; )
class FooController{
@Autowired
IFooService service;
@RequestMapping( method = RequestMethod.GET )
@ResponseBody
public List&lt; Foo &gt; findAll(){
return service.findAll();
}
@RequestMapping( value = &quot;/{id}&quot;, method = RequestMethod.GET )
@ResponseBody
public Foo findOne( @PathVariable( &quot;id&quot; ) Long id ){
return RestPreconditions.checkFound( service.findOne( id ) );
}
@RequestMapping( method = RequestMethod.POST )
@ResponseStatus( HttpStatus.CREATED )
@ResponseBody
public Long create( @RequestBody Foo resource ){
Preconditions.checkNotNull( resource );
return service.create( resource );
}
@RequestMapping( value = &quot;/{id}&quot;, method = RequestMethod.PUT )
@ResponseStatus( HttpStatus.OK )
public void update( @PathVariable( &quot;id&quot; ) Long id, @RequestBody Foo resource ){
Preconditions.checkNotNull( resource );
RestPreconditions.checkNotNull( service.getById( resource.getId() ) );
service.update( resource );
}
@RequestMapping( value = &quot;/{id}&quot;, method = RequestMethod.DELETE )
@ResponseStatus( HttpStatus.OK )
public void delete( @PathVariable( &quot;id&quot; ) Long id ){
service.deleteById( id );
}
}</screen>
<para>You may have noticed Im using a very simple, guava style <emphasis>RestPreconditions</emphasis> utility:</para>
<screen>public class RestPreconditions {
public static &lt;T&gt; T checkFound(final T resource) {
if (resource == null) {
throw new MyResourceNotFoundException();
}
return resource;
}
}</screen>
<para>The Controller implementation is <emphasis role="bold">non-public</emphasis> this is because it doesnt need to be. Usually the controller is the last in the chain of dependencies it receives HTTP requests from the Spring front controller (the<emphasis> DispathcerServlet</emphasis>) and simply delegate them forward to a service layer. If there is no use case where the controller has to be injected or manipulated through a direct reference, then I prefer not to declare it as public.</para>
<para>The <emphasis role="bold">request mappings</emphasis> are straightforward as with any controller, the actual <emphasis>value</emphasis> of the mapping as well as the HTTP <emphasis>method</emphasis> are used to determine the target method for the request. <emphasis role="bold">@</emphasis><emphasis><emphasis role="bold">RequestBody</emphasis></emphasis> will bind the parameters of the method to the body of the HTTP request, whereas <emphasis role="bold">@ResponseBody</emphasis> does the same for the response and return type. They also ensure that the resource will be marshalled and unmarshalled using the correct HTTP converter. <emphasis role="bold">Content negotiation</emphasis> will take place to choose which one of the active converters will be used, based mostly on the <emphasis>Accept</emphasis> header, although other HTTP headers may be used to determine the representation as well.</para>
</section>
<section xml:id="http-codes.1">
<title><anchor xml:id="dbdoclet.6_Mapping_the_HTTP_response_codes"/><emphasis role="bold">6. Mapping the HTTP response codes</emphasis></title>
<para>The status codes of the HTTP response are one of the most important parts of the REST service, and the subject can quickly become very complex. Getting these right can be what makes or breaks the service.</para>
<section xml:id="ch_6_1.1">
<title><emphasis role="bold">6.1. Unmapped requests</emphasis></title>
<para>If Spring MVC receives a request which doesnt have a mapping, it considers the request not to be allowed and returns a <emphasis role="bold">405 METHOD NOT ALLOWED</emphasis> back to the client. It is also good practice to include the <emphasis role="bold">Allow HTTP header</emphasis> when returning a <emphasis>405</emphasis> to the client, in order to specify which operations <emphasis role="bold">are</emphasis> allowed. This is the standard behavior of Spring MVC and does not require any additional configuration.</para>
</section>
<section xml:id="ch_6_2.1">
<title><emphasis role="bold">6.2. Valid, mapped requests</emphasis></title>
<para>For any request that does have a mapping, Spring MVC considers the request valid and responds with <emphasis role="bold">200 OK</emphasis> if no other status code is specified otherwise. It is because of this that controller declares different <emphasis><emphasis role="bold">@ResponseStatus</emphasis></emphasis> for the <emphasis>create</emphasis>, <emphasis>update</emphasis> and <emphasis>delete</emphasis> actions but not for <emphasis>get</emphasis>, which should indeed return the default 200 OK.</para>
</section>
<section xml:id="ch_6_3.1">
<title><emphasis role="bold">6.3. Client error</emphasis></title>
<para>In case of a <emphasis role="bold">client error</emphasis>, custom exceptions are defined and mapped to the appropriate error codes. Simply throwing these exceptions from any of the layers of the web tier will ensure Spring maps the corresponding status code on the HTTP response.</para>
<screen>@ResponseStatus( value = HttpStatus.BAD_REQUEST )
public class BadRequestException extends RuntimeException{
//
}
@ResponseStatus( value = HttpStatus.NOT_FOUND )
public class ResourceNotFoundException extends RuntimeException{
//
}</screen>
<para>These exceptions are part of the REST API and, as such, should only be used in the appropriate layers corresponding to REST; if for instance a DAO/DAL layer exist, it should not use the exceptions directly. Note also that these are not <emphasis role="bold">checked exceptions</emphasis> but <emphasis role="bold">runtime exceptions</emphasis> in line with Spring practices and idioms.</para>
</section>
<section xml:id="ch_6_4.1">
<title><emphasis role="bold">6.4. Using @ExceptionHandler</emphasis></title>
<para>Another option to map custom exceptions on specific status codes is to use the <emphasis><emphasis role="bold">@ExceptionHandler</emphasis></emphasis> annotation in the controller. The problem with that approach is that the annotation only applies to the controller in which it is defined, not to the entire Spring Container, which means that it needs to be declared in each controller individually. This quickly becomes cumbersome, especially in more complex applications which many controllers. There are a few <emphasis role="bold">JIRA issues</emphasis> opened with Spring at this time to handle this and other related limitations: <link xl:href="https://jira.springsource.org/browse/SPR-8124">SPR-8124</link>, <link xl:href="https://jira.springsource.org/browse/SPR-7278">SPR-7278</link>, <link xl:href="https://jira.springsource.org/browse/SPR-8406">SPR-8406</link>.</para>
</section>
</section>
<section xml:id="maven.1">
<title><anchor xml:id="dbdoclet.7_Additional_Maven_dependencies"/><emphasis role="bold">7. Additional Maven dependencies</emphasis><emphasis role="bold"></emphasis></title>
<para>In addition to the <emphasis>spring-webmvc</emphasis> dependency <link xl:href="http://www.baeldung.com/spring-with-maven#mvc">required for the standard web application</link>, well need to set up content marshalling and unmarshalling for the REST API:</para>
<screen>&lt;dependencies&gt;
&lt;dependency&gt;
   &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
   &lt;artifactId&gt;jackson-databind&lt;/artifactId&gt;
   &lt;version&gt;${jackson.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;javax.xml.bind&lt;/groupId&gt;
&lt;artifactId&gt;jaxb-api&lt;/artifactId&gt;
&lt;version&gt;${jaxb-api.version}&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;properties&gt;
&lt;jackson.version&gt;2.4.0&lt;/jackson.version&gt;
&lt;jaxb-api.version&gt;2.2.11&lt;/jaxb-api.version&gt;
&lt;/properties&gt;</screen>
<para>These are the libraries used to convert the representation of the REST resource to either <emphasis role="bold">JSON</emphasis> or <emphasis role="bold">XML</emphasis>.</para>
</section>
<section xml:id="conclusion.1">
<title><anchor xml:id="dbdoclet.8_Conclusion"/><emphasis role="bold">8. Conclusion</emphasis></title>
<para>This tutorial illustrated how to implement and configure a REST Service using Spring 4 and Java based configuration, discussing HTTP response codes, basic Content Negotiation and marshaling.</para>
<para>In the next articles of the series I will focus on <link xl:href="http://www.baeldung.com/2011/11/06/restful-web-service-discoverability-part-4/">Discoverability of the API</link>, advanced <emphasis role="bold">content negotiation</emphasis> and working with <emphasis role="bold">additional representations</emphasis> of a Resource.</para>
<para><link xl:href="https://my.leadpages.net/leadbox/143ecbd73f72a2%3A13a71ac76b46dc/5762893836451840/">The implementation of this <emphasis>Spring REST API Tutorial</emphasis> can be downloaded as a working sample project.</link></para>
<para>This is an Eclipse based project, so it should be easy to import and run as it is.</para>
<!--
Start Shortcoder content
-->
<!--
End Shortcoder content
-->
<para><link xl:href=""/></para>
<anchor xml:id="dd_ajax_float"/>
<para><link xl:href="http://twitter.com/share"/></para>
<!--
OptinSkin
-->
<anchor xml:id="ois_12"/>
<!--
End OptinSkin
-->
<!--
/.entry
-->
<para><emphasis role="italic"/><link xl:href="http://www.baeldung.com/tag/java-2/">java</link>, <link xl:href="http://www.baeldung.com/tag/rest/">REST</link>, <link xl:href="http://www.baeldung.com/tag/spring/">Spring</link>, <link xl:href="http://www.baeldung.com/tag/testing/">testing</link></para>
<!--
/.post
-->
<!--
/#main
-->
<anchor xml:id="optinskin-widget-3"/>
<!--
OptinSkin
-->
<anchor xml:id="ois_5"/>
<!--
End OptinSkin
-->
<!--
/#sidebar
-->
<!--
/#main-sidebar-container
-->
<!--
/#content
-->
<anchor xml:id="copyright"/>
<para>© 2014 Baeldung. All Rights Reserved. </para>
<anchor xml:id="credit"/>
<!--
/#inner-wrapper
-->
<!--
/#wrapper
-->
<!--
/.fix
-->
<!--
ngg_resource_manager_marker
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 Begin
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 End
-->
<!--
Creater Script for Social Locker
Created by the Social Locker plugin (c) OnePress Ltd
http://sociallocker.org
-->
<!--
/
-->
</section>
</section>
</article>
<?xml version="1.0" encoding="UTF-8"?>
<article version="5.0" xml:lang="en-US" xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink">
<info>
<title>Spring Security for a REST API</title>
</info>
<anchor xml:id="wrapper"/>
<anchor xml:id="inner-wrapper"/>
<!--
/#side-nav
-->
<!--
/.menus
-->
<para><link linkend="top">Return to Content</link></para>
<!--
#content Starts
-->
<anchor xml:id="content"/>
<anchor xml:id="main-sidebar-container"/>
<!--
#main Starts
-->
<anchor xml:id="toc_container"/>
<para>Contents</para>
<itemizedlist>
<listitem>
<para><link linkend="Table_of_Contents">Table of Contents</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.1_Overview">1. Overview</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.2_Spring_Security_in_the_webxml">2. Spring Security in the web.xml</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.3_The_Security_Configuration">3. The Security Configuration</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.4_Maven_and_other_trouble">4. Maven and other trouble</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.5_Conclusion">5. Conclusion</link></para>
</listitem>
</itemizedlist>
<para><link xl:href=""/></para>
<!--
Start Shortcoder content
-->
<!--
End Shortcoder content
-->
<section>
<title><anchor xml:id="Table_of_Contents"/><emphasis role="bold">Table of Contents</emphasis></title>
<itemizedlist>
<listitem>
<para><link linkend="overview"><emphasis role="bold">1. </emphasis>Overview</link></para>
</listitem>
<listitem>
<para><link linkend="springsec"><emphasis role="bold">2. </emphasis>Introducing Spring Security in the <literal>web.xml</literal></link></para>
</listitem>
<listitem>
<para><link linkend="config"><emphasis role="bold">3. </emphasis>The Security Configuration</link></para>
</listitem>
<listitem>
<para><link linkend="ch_3_1"><emphasis role="bold">    3.1. </emphasis>The basics</link></para>
</listitem>
<listitem>
<para><link linkend="ch_3_2"><emphasis role="bold">    3.2. </emphasis>The Entry Point</link></para>
</listitem>
<listitem>
<para><link linkend="ch_3_3"><emphasis role="bold">    3.3. </emphasis>The Login</link></para>
</listitem>
<listitem>
<para><link linkend="ch_3_4"><emphasis role="bold">    3.4. </emphasis>Authentication should return <emphasis role="bold">200</emphasis> instead of <emphasis role="bold">301</emphasis></link></para>
</listitem>
<listitem>
<para><link linkend="ch_3_5"><emphasis role="bold">    3.5. </emphasis>Failed Authentication should return <emphasis role="bold">401</emphasis> instead of <emphasis role="bold">302</emphasis></link></para>
</listitem>
<listitem>
<para><link linkend="ch_3_6"><emphasis role="bold">    3.6. </emphasis>The Authentication Manager and Provider</link></para>
</listitem>
<listitem>
<para><link linkend="ch_3_7"><emphasis role="bold">    3.7. </emphasis>Finally – Authentication against the running REST Service</link></para>
</listitem>
<listitem>
<para><link linkend="maven"><emphasis role="bold">4. </emphasis>Maven and other trouble</link></para>
</listitem>
<listitem>
<para><link linkend="conclusion"><emphasis role="bold">5. </emphasis>Conclusion</link></para>
</listitem>
</itemizedlist>
<section xml:id="overview.1">
<title><anchor xml:id="dbdoclet.1_Overview"/><emphasis role="bold">1. Overview</emphasis></title>
<para>This tutorial shows how to <emphasis role="bold">Secure a REST Service using Spring and Spring Security 3.1</emphasis> with Java based configuration. The article will focus on how to set up the Security Configuration specifically for the REST API using a Login and Cookie approach.</para>
</section>
<section xml:id="springsec.1">
<title><anchor xml:id="dbdoclet.2_Spring_Security_in_the_webxml"/><emphasis role="bold">2. Spring Security in the web.xml</emphasis></title>
<para>The architecture of Spring Security is based entirely on Servlet Filters and, as such, comes before Spring MVC in regards to the processing of HTTP requests. Keeping this in mind, to begin with, a <emphasis role="bold">filter</emphasis> needs to be declared in the <emphasis>web.xml</emphasis> of the application:</para>
<screen>&lt;filter&gt;
&lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
&lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</screen>
<para>The filter must necessarily be named <emphasis>springSecurityFilterChain</emphasis>  to match the default bean created by Spring Security in the container.</para>
<para>Note that the defined filter is not the actual class implementing the security logic but a <emphasis>DelegatingFilterProxy</emphasis> with the purpose of delegating the Filters methods to an internal bean. This is done so that the target bean can still benefit from the Spring context lifecycle and flexibility.</para>
<para>The URL pattern used to configure the Filter is <emphasis role="bold">/*</emphasis> even though the entire web service is mapped to <emphasis role="bold">/api/*</emphasis> so that the security configuration has the option to secure other possible mappings as well, if required.</para>
</section>
<section xml:id="config.1">
<title><anchor xml:id="dbdoclet.3_The_Security_Configuration"/><emphasis role="bold">3. The Security Configuration</emphasis></title>
<screen>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans:beans
xmlns=&quot;http://www.springframework.org/schema/security&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
xmlns:sec=&quot;http://www.springframework.org/schema/security&quot;
xsi:schemaLocation=&quot;
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd&quot;&gt;
&lt;http entry-point-ref=&quot;restAuthenticationEntryPoint&quot;&gt;
&lt;intercept-url pattern=&quot;/api/admin/**&quot; access=&quot;ROLE_ADMIN&quot;/&gt;
&lt;form-login
authentication-success-handler-ref=&quot;mySuccessHandler&quot;
authentication-failure-handler-ref=&quot;myFailureHandler&quot;
/&gt;
&lt;logout /&gt;
&lt;/http&gt;
&lt;beans:bean id=&quot;mySuccessHandler&quot;
class=&quot;org.rest.security.MySavedRequestAwareAuthenticationSuccessHandler&quot;/&gt;
&lt;beans:bean id=&quot;myFailureHandler&quot;
class=&quot;org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler&quot;/&gt;
&lt;authentication-manager alias=&quot;authenticationManager&quot;&gt;
&lt;authentication-provider&gt;
&lt;user-service&gt;
&lt;user name=&quot;temporary&quot; password=&quot;temporary&quot; authorities=&quot;ROLE_ADMIN&quot;/&gt;
&lt;user name=&quot;user&quot; password=&quot;user&quot; authorities=&quot;ROLE_USER&quot;/&gt;
&lt;/user-service&gt;
&lt;/authentication-provider&gt;
&lt;/authentication-manager&gt;
&lt;/beans:beans&gt;</screen>
<para> Most of the configuration is done using the <emphasis role="bold">security namespace</emphasis> for this to be enabled, the schema locations must be defined and pointed to the correct 3.1 or 3.2 XSD versions. The namespace is designed so that it expresses the common uses of Spring Security while still providing hooks raw beans to accommodate more advanced scenarios. <link xl:href="http://products.baeldung.com/rest-api-with-spring"><emphasis role="bold">&gt;&gt; Signup for my upcoming Video Course on Building a REST API with Spring 4</emphasis></link></para>
<section xml:id="ch_3_1.1">
<title><emphasis role="bold">3.1. The &lt;http&gt; element</emphasis></title>
<para>The <emphasis>&lt;http&gt;</emphasis> element is the main container element for HTTP security configuration. In the current implementation, it only secured a single mapping: <emphasis>/api/admin/**</emphasis>. Note that the mapping is <emphasis role="bold">relative to the root context</emphasis> of the web application, not to the <emphasis>rest</emphasis> Servlet; this is because the entire security configuration lives in the root Spring context and not in the child context of the Servlet.</para>
</section>
<section xml:id="ch_3_2.1">
<title><emphasis role="bold">3.2. The Entry Point</emphasis></title>
<para>In a standard web application, the authentication process may be automatically triggered when the client tries to access a secured resource without being authenticated this is usually done by redirecting to a login page so that the user can enter credentials. However, for a <emphasis role="bold">REST Web Service </emphasis>this behavior doesnt make much sense Authentication should only be done by a request to the correct URI and all other requests should simply fail with a <emphasis role="bold">401 UNAUTHORIZED</emphasis> status code if the user is not authenticated.</para>
<para>Spring Security handles this automatic triggering of the authentication process with the concept of an <emphasis role="bold">Entry Point</emphasis> this is a required part of the configuration, and can be injected via the <emphasis>entry-point-ref</emphasis> attribute of the <emphasis>&lt;http&gt;</emphasis> element. Keeping in mind that this functionality doesnt make sense in the context of the REST Service, the new custom entry point is defined to simply return 401 whenever it is triggered:</para>
<screen>@Component( &quot;restAuthenticationEntryPoint&quot; )
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint{
@Override
public void commence( HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException ) throws IOException{
response.sendError( HttpServletResponse.SC_UNAUTHORIZED, &quot;Unauthorized&quot; );
}
}</screen>
<para>A quick sidenote here is that the 401 is sent without the <emphasis>WWW-Authenticate</emphasis> header, as required by the HTTP Spec we can of course set the value manually if we need to.</para>
</section>
<section xml:id="ch_3_3.1">
<title><emphasis role="bold">3.3. The Login Form for REST</emphasis></title>
<para>There are multiple ways to do Authentication for a REST API one of the default Spring Security provides is <emphasis role="bold">Form Login</emphasis> which uses an authentication processing filter <emphasis>org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter</emphasis>.</para>
<para>The <emphasis>&lt;form-login&gt;</emphasis> element will create this filter and will also allow us to set our custom authentication success handler on it. This can also be done manually by using the <emphasis>&lt;custom-filter&gt;</emphasis> element to register a filter at the position <emphasis>FORM_LOGIN_FILTER</emphasis> but the namespace support is flexible enough.</para>
<para>Note that for a standard web application, the <emphasis role="bold">auto-config </emphasis>attribute of the <emphasis>&lt;http&gt; element </emphasis>is shorthand syntax for some useful security configuration. While this may be appropriate for some very simple configurations, it doesnt fit and should not be used for a REST API.</para>
</section>
<section xml:id="ch_3_4.1">
<title><emphasis role="bold">3.4. Authentication should return 200 instead of 301</emphasis></title>
<para>By default, form login will answer a successful authentication request with a <emphasis role="bold">301 MOVED PERMANENTLY</emphasis> status code; this makes sense in the context of an actual login form which needs to redirect after login. For a RESTful web service however, the desired response for a successful authentication should be <emphasis role="bold">200 OK</emphasis>.</para>
<para>This is done by injecting a <emphasis role="bold">custom authentication success handler</emphasis> in the form login filter, to replace the default one. The new handler implements the exact same login as the default <emphasis>org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler</emphasis> with one notable difference the redirect logic is removed:</para>
<screen>public class MySavedRequestAwareAuthenticationSuccessHandler
extends SimpleUrlAuthenticationSuccessHandler {
private RequestCache requestCache = new HttpSessionRequestCache();
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest == null) {
clearAuthenticationAttributes(request);
return;
}
String targetUrlParam = getTargetUrlParameter();
if (isAlwaysUseDefaultTargetUrl() ||
(targetUrlParam != null &amp;&amp;
StringUtils.hasText(request.getParameter(targetUrlParam)))) {
requestCache.removeRequest(request, response);
clearAuthenticationAttributes(request);
return;
}
clearAuthenticationAttributes(request);
}
public void setRequestCache(RequestCache requestCache) {
this.requestCache = requestCache;
}
}</screen>
</section>
<section xml:id="ch_3_5.1">
<title><emphasis role="bold">3.5. Failed Authentication should return 401 instead of 302</emphasis></title>
<para>Similarly we configured the authentication failure handler same way we did with the success handler.</para>
<para>Luckily in this case, we dont need to actually define a new class for this handler the standard implementation <emphasis>SimpleUrlAuthenticationFailureHandler</emphasis> does just fine.</para>
<para>The only difference is that now that were defining this explicitly in our XML config its <emphasis role="bold">not going to get a default defaultFailureUrl from Spring</emphasis> and so it wont redirect.</para>
</section>
<section xml:id="ch_3_6.1">
<title><emphasis role="bold">3.6. The Authentication Manager and Provider</emphasis></title>
<para>The authentication process uses an <emphasis role="bold">in-memory provider</emphasis> to perform authentication this is meant to simplify the configuration as a production implementation of these artifacts is outside the scope of this post.</para>
</section>
<section xml:id="ch_3_7.1">
<title><emphasis role="bold">3.7 Finally Authentication against the running REST Service</emphasis></title>
<para>Now lets see how we can authenticate against the REST API the URL for login is <emphasis>/j_spring_security_check</emphasis> and a simple <emphasis>curl</emphasis> command performing login would be:</para>
<screen>curl -i -X POST -d j_username=user -d j_password=userPass
http://localhost:8080/spring-security-rest/j_spring_security_check</screen>
<para>This request will return the Cookie which will then be used by any subsequent request against the REST Service.</para>
<para>We can use <emphasis>curl</emphasis> to authentication and <emphasis role="bold">store the cookie it receives in a file</emphasis>:</para>
<screen>curl -i -X POST -d j_username=user -d j_password=userPass -c /opt/cookies.txt
http://localhost:8080/spring-security-rest/j_spring_security_check</screen>
<para>Then <emphasis role="bold">we can use the cookie from the file</emphasis> to do further authenticated requests:</para>
<screen>curl -i --header &quot;Accept:application/json&quot; -X GET -b /opt/cookies.txt
http://localhost:8080/spring-security-rest/api/foos</screen>
<para>This authenticated request will correctly <emphasis role="bold">result in a 200 OK</emphasis>:</para>
<screen>HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 24 Jul 2013 20:31:13 GMT
[{&quot;id&quot;:0,&quot;name&quot;:&quot;JbidXc&quot;}]</screen>
</section>
</section>
<section xml:id="maven.1">
<title><anchor xml:id="dbdoclet.4_Maven_and_other_trouble"/><emphasis role="bold">4. Maven and other trouble</emphasis></title>
<para>The Spring <link xl:href="http://www.baeldung.com/spring-with-maven#mvc">core dependencies</link> necessary for a web application and for the REST Service have been discussed in detail. For security, well need to add: <emphasis>spring-security-web</emphasis> and <emphasis>spring-security-config</emphasis> all of these have also been covered in the <link xl:href="http://www.baeldung.com/spring-security-with-maven">Maven for Spring Security</link> tutorial.</para>
<para>Its worth paying close attention to the way Maven will resolve the older Spring dependencies the resolution strategy will start <link xl:href="http://www.baeldung.com/spring-security-with-maven#maven_problem">causing problems</link> once the security artifacts are added to the pom. To address this problem, some of the core dependencies will need to be overridden in order to keep them at the right version.</para>
</section>
<section xml:id="conclusion.1">
<title><anchor xml:id="dbdoclet.5_Conclusion"/><emphasis role="bold">5. Conclusion</emphasis></title>
<para>This post covered the basic security configuration and implementation for a RESTful Service using <emphasis role="bold">Spring Security 3.1</emphasis>, discussing the <emphasis>web.xml</emphasis>, the security configuration, the HTTP status codes for the authentication process and the Maven resolution of the security artifacts.</para>
<para><link xl:href="https://my.leadpages.net/leadbox/14476c373f72a2%3A13a71ac76b46dc/5664530495438848/">The implementation of this Spring Security REST Tutorial can be downloaded as a working sample project.</link>This is an Eclipse based project, so it should be easy to import and run as it is.</para>
<!--
Start Shortcoder content
-->
<!--
End Shortcoder content
-->
<para><link xl:href=""/></para>
<anchor xml:id="dd_ajax_float"/>
<para><link xl:href="http://twitter.com/share"/></para>
<!--
OptinSkin
-->
<anchor xml:id="ois_12"/>
<!--
End OptinSkin
-->
<!--
/.entry
-->
<para><emphasis role="italic"/><link xl:href="http://www.baeldung.com/tag/rest/">REST</link>, <link xl:href="http://www.baeldung.com/tag/security/">security</link>, <link xl:href="http://www.baeldung.com/tag/spring/">Spring</link></para>
<!--
/.post
-->
<!--
/#main
-->
<anchor xml:id="optinskin-widget-3"/>
<!--
OptinSkin
-->
<anchor xml:id="ois_5"/>
<!--
End OptinSkin
-->
<!--
/#sidebar
-->
<!--
/#main-sidebar-container
-->
<!--
/#content
-->
<anchor xml:id="copyright"/>
<para>© 2014 Baeldung. All Rights Reserved. </para>
<anchor xml:id="credit"/>
<!--
/#inner-wrapper
-->
<!--
/#wrapper
-->
<!--
/.fix
-->
<!--
ngg_resource_manager_marker
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 Begin
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 End
-->
<!--
Creater Script for Social Locker
Created by the Social Locker plugin (c) OnePress Ltd
http://sociallocker.org
-->
<!--
/
-->
</section>
</section>
</article>
<?xml version="1.0" encoding="UTF-8"?>
<article version="5.0" xml:lang="en-US" xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink">
<info>
<title>Spring Security Basic Authentication</title>
</info>
<anchor xml:id="wrapper"/>
<anchor xml:id="inner-wrapper"/>
<!--
/#side-nav
-->
<!--
/.menus
-->
<para><link linkend="top">Return to Content</link></para>
<!--
#content Starts
-->
<anchor xml:id="content"/>
<anchor xml:id="main-sidebar-container"/>
<!--
#main Starts
-->
<anchor xml:id="toc_container"/>
<para>Contents</para>
<itemizedlist>
<listitem>
<para><link linkend="dbdoclet.1_Overview">1. Overview</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.2_The_Spring_Security_Configuration">2. The Spring Security Configuration</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.3_Consuming_The_Secured_Application">3. Consuming The Secured Application</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.4_Further_Configuration_8211_The_Entry_Point">4. Further Configuration The Entry Point</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.5_The_Maven_Dependencies">5. The Maven Dependencies</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.6_Conclusion">6. Conclusion</link></para>
</listitem>
</itemizedlist>
<para>If you&apos;re new here, <link xl:href="https://my.leadpages.net/leadbox/146382273f72a2%3A13a71ac76b46dc/5735865741475840/">you may want to get my &quot;REST APIs with Spring&quot; eBook</link>. Thanks for visiting!</para>
<para><link xl:href=""/></para>
<!--
Start Shortcoder content
-->
<!--
End Shortcoder content
-->
<section xml:id="overview.1">
<title><anchor xml:id="dbdoclet.1_Overview"/><emphasis role="bold">1. Overview</emphasis></title>
<para>This tutorial shows how to set up, configure and customize <emphasis role="bold">Basic Authentication with Spring</emphasis>. Were going to built on top of the simple <link xl:href="http://www.baeldung.com/spring-mvc-tutorial">Spring MVC example</link>, and secure the UI of the MVC application with the Basic Auth mechanism provided by Spring Security.</para>
<section xml:id="configuration.1">
<title><anchor xml:id="dbdoclet.2_The_Spring_Security_Configuration"/><emphasis role="bold">2. The Spring Security Configuration</emphasis></title>
<para>The Configuration for Spring Security is still XML:</para>
<screen>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/security&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
xsi:schemaLocation=&quot;
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd&quot;&gt;
&lt;http use-expressions=&quot;true&quot;&gt;
&lt;intercept-url pattern=&quot;/**&quot; access=&quot;isAuthenticated()&quot; /&gt;
&lt;http-basic /&gt;
&lt;/http&gt;
&lt;authentication-manager&gt;
&lt;authentication-provider&gt;
&lt;user-service&gt;
&lt;user name=&quot;user1&quot; password=&quot;user1Pass&quot; authorities=&quot;ROLE_USER&quot; /&gt;
&lt;/user-service&gt;
&lt;/authentication-provider&gt;
&lt;/authentication-manager&gt;
&lt;/beans:beans&gt;</screen>
<para>This is one of the last pieces of configuration in Spring that still need XML <link xl:href="https://github.com/SpringSource/spring-security-javaconfig">Java Configuration for Spring Security</link> is still a work in progress.</para>
<para>What is relevant here is the <emphasis>&lt;http-basic&gt;</emphasis> element inside the main <emphasis>&lt;http&gt;</emphasis> element of the configuration this is enough to enable Basic Authentication for the entire application. The Authentication Manager is not the focus of this tutorial, so we are using an in memory manager with the user and password defined in plaintext.</para>
<para>The <emphasis>web.xml</emphasis> of the web application enabling Spring Security has already been discussed in the <link xl:href="http://www.baeldung.com/spring-security-login#web_xml">Spring Logout tutorial</link>.</para>
</section>
<section xml:id="usage.1">
<title><anchor xml:id="dbdoclet.3_Consuming_The_Secured_Application"/><emphasis role="bold">3. Consuming The Secured Application</emphasis></title>
<para>The <emphasis>curl</emphasis> command is our go to tool for consuming the secured application.</para>
<para>First, lets try to request the <emphasis>/homepage.html</emphasis> without providing any security credentials:</para>
<screen>curl -i http://localhost:8080/spring-security-mvc-basic-auth/homepage.html</screen>
<para>We get back the expected <emphasis>401 Unauthorized</emphasis> and <link xl:href="http://tools.ietf.org/html/rfc1945#section-10.16">the Authentication Challenge</link>:</para>
<screen>HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=E5A8D3C16B65A0A007CFAACAEEE6916B; Path=/spring-security-mvc-basic-auth/; HttpOnly
WWW-Authenticate: Basic realm=&quot;Spring Security Application&quot;
Content-Type: text/html;charset=utf-8
Content-Length: 1061
Date: Wed, 29 May 2013 15:14:08 GMT</screen>
<para>The browser would interpret this challenge and prompt us for credentials with a simple dialog, but since were using <emphasis>curl</emphasis>, this isnt the case.</para>
<para>Now, lets request the same resource the homepage but <emphasis role="bold">provide the credentials</emphasis> to access it as well:</para>
<screen>curl -i --user user1:user1Pass http://localhost:8080/spring-security-mvc-basic-auth/homepage.html</screen>
<para>Now, the response from the server is <emphasis>200 OK</emphasis> along with a <emphasis>Cookie</emphasis>:</para>
<screen>HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=301225C7AE7C74B0892887389996785D; Path=/spring-security-mvc-basic-auth/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Content-Language: en-US
Content-Length: 90
Date: Wed, 29 May 2013 15:19:38 GMT</screen>
<para>From the browser, the application can be consumed normally the only difference is that a login page is no longer a hard requirement since all browsers support Basic Authentication and use a dialog to prompt the user for credentials.</para>
</section>
<section xml:id="advanced_config.1">
<title><anchor xml:id="dbdoclet.4_Further_Configuration_8211_The_Entry_Point"/><emphasis role="bold">4. Further Configuration </emphasis><emphasis role="bold">The Entry Point</emphasis></title>
<para>By default, the <emphasis>BasicAuthenticationEntryPoint</emphasis> provisioned by Spring Security returns a full html page for a <emphasis>401 Unauthorized</emphasis> response back to the client. This html representation of the error renders well in a browser, but it not well suited for other scenarios, such as a REST API where a json representation may be preferred.</para>
<para>The namespace is flexible enough for this new requirement as well to address this the entry point can be overridden:</para>
<screen>&lt;http-basic entry-point-ref=&quot;myBasicAuthenticationEntryPoint&quot; /&gt;</screen>
<para>The new entry point is defined as a standard bean:</para>
<screen>@Component
public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
@Override
public void commence
(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
throws IOException, ServletException {
response.addHeader(&quot;WWW-Authenticate&quot;, &quot;Basic realm=\&quot;&quot; + getRealmName() + &quot;\&quot;&quot;);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println(&quot;HTTP Status 401 - &quot; + authEx.getMessage());
}
@Override
public void afterPropertiesSet() throws Exception {
setRealmName(&quot;Baeldung&quot;);
super.afterPropertiesSet();
}
}</screen>
<para>By writing directly to the HTTP Response we now have full control over the format of the response body.</para>
</section>
<section xml:id="maven.1">
<title><anchor xml:id="dbdoclet.5_The_Maven_Dependencies"/><emphasis role="bold">5. The Maven Dependencies</emphasis></title>
<para>The Maven dependencies for Spring Security have been discussed before in the <link xl:href="http://www.baeldung.com/spring-security-with-maven">Spring Security with Maven article</link> we will need both <emphasis>spring-security-web</emphasis> and <emphasis>spring-security-config</emphasis> available at runtime.</para>
</section>
<section xml:id="conclusion.1">
<title><anchor xml:id="dbdoclet.6_Conclusion"/><emphasis role="bold">6. Conclusion</emphasis></title>
<para>In this example we secured an MVC application with Spring Security and Basic Authentication. We discussed the XML configuration and we consumed the application with simple curl commands. Finally took control of the exact error message format moving from the standard HTML error page to a custom text or json format.</para>
<para>The implementation of this Spring tutorial can be found in <link xl:href="https://github.com/eugenp/tutorials/tree/master/spring-security-basic-auth#readme">the github project</link> – this is an Eclipse based project, so it should be easy to import and run as it is. When the project runs locally, the sample html can be accessed at:</para>
<para><link xl:href="http://localhost:8080/spring-security-mvc-basic-auth/homepage.html">http://localhost:8080/spring-security-mvc-basic-auth/homepage.html</link></para>
<!--
Start Shortcoder content
-->
<!--
End Shortcoder content
-->
<para><link xl:href=""/></para>
<anchor xml:id="dd_ajax_float"/>
<para><link xl:href="http://twitter.com/share"/></para>
<!--
OptinSkin
-->
<anchor xml:id="ois_12"/>
<!--
End OptinSkin
-->
<!--
/.entry
-->
<para><emphasis role="italic"/><link xl:href="http://www.baeldung.com/tag/security/">security</link>, <link xl:href="http://www.baeldung.com/tag/spring/">Spring</link></para>
<!--
/.post
-->
<!--
/#main
-->
<anchor xml:id="optinskin-widget-3"/>
<!--
OptinSkin
-->
<anchor xml:id="ois_5"/>
<!--
End OptinSkin
-->
<!--
/#sidebar
-->
<!--
/#main-sidebar-container
-->
<!--
/#content
-->
<anchor xml:id="copyright"/>
<para>© 2014 Baeldung. All Rights Reserved. </para>
<anchor xml:id="credit"/>
<!--
/#inner-wrapper
-->
<!--
/#wrapper
-->
<!--
/.fix
-->
<!--
ngg_resource_manager_marker
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 Begin
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 End
-->
</section>
</section>
</article>
<?xml version="1.0" encoding="UTF-8"?>
<article version="5.0" xml:lang="en-US" xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink">
<info>
<title>Spring Security Digest Authentication</title>
</info>
<anchor xml:id="wrapper"/>
<anchor xml:id="inner-wrapper"/>
<!--
/#side-nav
-->
<!--
/.menus
-->
<para><link linkend="top">Return to Content</link></para>
<!--
#content Starts
-->
<anchor xml:id="content"/>
<anchor xml:id="main-sidebar-container"/>
<!--
#main Starts
-->
<anchor xml:id="toc_container"/>
<para>Contents</para>
<itemizedlist>
<listitem>
<para><link linkend="dbdoclet.1_Overview">1. Overview</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.2_The_Security_XML_Configuration">2. The Security XML Configuration</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.3_Consuming_the_Secured_Application">3. Consuming the Secured Application</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.4_The_Maven_Dependencies">4. The Maven Dependencies</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.5_Conclusion">5. Conclusion</link></para>
</listitem>
</itemizedlist>
<para>If you&apos;re new here, <link xl:href="https://my.leadpages.net/leadbox/146382273f72a2%3A13a71ac76b46dc/5735865741475840/">you may want to get my &quot;REST APIs with Spring&quot; eBook</link>. Thanks for visiting!</para>
<para><link xl:href=""/></para>
<!--
Start Shortcoder content
-->
<!--
End Shortcoder content
-->
<section xml:id="overview.1">
<title><anchor xml:id="dbdoclet.1_Overview"/><emphasis role="bold">1. Overview</emphasis></title>
<para>This tutorial shows how to set up, configure and customize Digest Authentication with Spring. Similar to the previous <link xl:href="http://www.baeldung.com/spring-security-basic-authentication">article covering Basic Authentication</link>, we’re going to built on top of the Spring MVC tutorial, and secure the application with the Digest Auth mechanism provided by Spring Security.</para>
<section xml:id="configuration.1">
<title><anchor xml:id="dbdoclet.2_The_Security_XML_Configuration"/><emphasis role="bold">2. The Security XML Configuration</emphasis></title>
<para>First thing to understand about the configuration is that, while Spring Security does have full out of the box support for the Digest authentication mechanism, this support is <emphasis role="bold">not as well integrated into the namespace</emphasis> as Basic Authentication was.</para>
<para>In this case, we need to manually <emphasis role="bold">define the raw beans</emphasis> that are going to make up the security configuration the <emphasis>DigestAuthenticationFilter</emphasis> and the <emphasis>DigestAuthenticationEntryPoint</emphasis>:</para>
<screen>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/security&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
xsi:schemaLocation=&quot;
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd&quot;&gt;
    &lt;beans:bean id=&quot;digestFilter&quot;
class=&quot;org.springframework.security.web.authentication.www.DigestAuthenticationFilter&quot;&gt;
        &lt;beans:property name=&quot;userDetailsService&quot; ref=&quot;userService&quot; /&gt;
        &lt;beans:property name=&quot;authenticationEntryPoint&quot; ref=&quot;digestEntryPoint&quot; /&gt;
    &lt;/beans:bean&gt;
    &lt;beans:bean id=&quot;digestEntryPoint&quot; 
class=&quot;org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint&quot;&gt;
        &lt;beans:property name=&quot;realmName&quot; value=&quot;Contacts Realm via Digest Authentication&quot; /&gt;
        &lt;beans:property name=&quot;key&quot; value=&quot;acegi&quot; /&gt;
    &lt;/beans:bean&gt;
&lt;!-- the security namespace configuration --&gt;
&lt;http use-expressions=&quot;true&quot; entry-point-ref=&quot;digestEntryPoint&quot;&gt;
&lt;intercept-url pattern=&quot;/**&quot; access=&quot;isAuthenticated()&quot; /&gt;
&lt;custom-filter ref=&quot;digestFilter&quot; after=&quot;BASIC_AUTH_FILTER&quot; /&gt;
&lt;/http&gt;
&lt;authentication-manager&gt;
&lt;authentication-provider&gt;
&lt;user-service id=&quot;userService&quot;&gt;
&lt;user name=&quot;user1&quot; password=&quot;user1Pass&quot; authorities=&quot;ROLE_USER&quot; /&gt;
&lt;/user-service&gt;
&lt;/authentication-provider&gt;
&lt;/authentication-manager&gt;
&lt;/beans:beans&gt;</screen>
<para>Next, we need to integrate these beans into the overall security configuration and in this case, the namespace is still flexible enough to allow us to do that.</para>
<para>The first part of this is pointing to the custom entry point bean, via the <emphasis>entry-point-ref</emphasis> attribute of the main <emphasis>&lt;http&gt;</emphasis> element.</para>
<para>The second part is <emphasis role="bold">adding the newly defined digest filter into the security filter chain</emphasis>. Since this filter is functionally equivalent to the <emphasis>BasicAuthenticationFilter</emphasis>, we are using the same relative position in the chain this is specified by the <emphasis>BASIC_AUTH_FILTER</emphasis> alias in the overall <link xl:href="http://static.springsource.org/spring-security/site/docs/3.1.x/reference/ns-config.html#ns-custom-filters">Spring Security Standard Filters</link>.</para>
<para>Finally, notice that the Digest Filter is configured to <emphasis role="bold">point to the user service bean</emphasis> and here, the namespace is again very useful as it allows us to specify a bean name for the default user service created by the <emphasis>&lt;user-service&gt;</emphasis> element:</para>
<screen>&lt;user-service id=&quot;userService&quot;&gt;</screen>
</section>
<section xml:id="usage.1">
<title><anchor xml:id="dbdoclet.3_Consuming_the_Secured_Application"/><emphasis role="bold">3. Consuming the Secured Application</emphasis></title>
<para>Were going to be using <emphasis role="bold">the curl command</emphasis> to consume the secured application and understand how a client can interact with it.</para>
<para>Lets start by requesting the homepage <emphasis role="bold">without providing security credentials</emphasis> in the request:</para>
<screen>curl -i http://localhost/spring-security-mvc-digest-auth/homepage.html</screen>
<para>As expected, we get back a response with a <emphasis>401 Unauthorized</emphasis> status code:</para>
<screen>HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=CF0233C...; Path=/spring-security-mvc-digest-auth/; HttpOnly
WWW-Authenticate: Digest realm=&quot;Contacts Realm via Digest Authentication&quot;, qop=&quot;auth&quot;,
nonce=&quot;MTM3MzYzODE2NTg3OTo3MmYxN2JkOWYxZTc4MzdmMzBiN2Q0YmY0ZTU0N2RkZg==&quot;
Content-Type: text/html;charset=utf-8
Content-Length: 1061
Date: Fri, 12 Jul 2013 14:04:25 GMT</screen>
<para>If this request were sent by the browser, the authentication challenge would prompt the user for credentials using a simple user/password dialog.</para>
<para>Lets now <emphasis role="bold">provide the correct credentials</emphasis> and send the request again:</para>
<screen>curl -i --digest --user
user1:user1Pass http://localhost/spring-security-mvc-digest-auth/homepage.html</screen>
<para>Notice that we are enabling Digest Authentication for the <emphasis>curl</emphasis> command via the <emphasis>digest</emphasis> flag.</para>
<para>The first response from the server will be the same the <emphasis>401 Unauthorized</emphasis> but the challenge will now be interpreted and acted upon by a second request which will succeed with a <emphasis>200 OK</emphasis>:</para>
<screen>HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=A961E0D...; Path=/spring-security-mvc-digest-auth/; HttpOnly
WWW-Authenticate: Digest realm=&quot;Contacts Realm via Digest Authentication&quot;, qop=&quot;auth&quot;,
nonce=&quot;MTM3MzYzODgyOTczMTo3YjM4OWQzMGU0YTgwZDg0YmYwZjRlZWJjMDQzZWZkOA==&quot;
Content-Type: text/html;charset=utf-8
Content-Length: 1061
Date: Fri, 12 Jul 2013 14:15:29 GMT
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=55F996B...; Path=/spring-security-mvc-digest-auth/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Content-Language: en-US
Content-Length: 90
Date: Fri, 12 Jul 2013 14:15:29 GMT
&lt;html&gt;
&lt;head&gt;&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;This is the homepage&lt;/h1&gt;
&lt;/body&gt;
&lt;/html&gt;</screen>
<para>A final note on this interaction is that a client can <emphasis role="bold">preemptively send the correct Authorization header</emphasis> with the first request, and thus entirely <emphasis role="bold">avoid the server security challenge</emphasis> and the second request.</para>
</section>
<section xml:id="maven.1">
<title><anchor xml:id="dbdoclet.4_The_Maven_Dependencies"/><emphasis role="bold">4. The Maven Dependencies</emphasis></title>
<para>The security dependencies are discussed in depth in the <link xl:href="http://www.baeldung.com/spring-security-with-maven">Spring Security Maven tutorial</link>. In short, we will need to define <emphasis>spring-security-web</emphasis> and <emphasis>spring-security-config</emphasis> as dependencies in our <emphasis>pom.xml</emphasis>.</para>
</section>
<section xml:id="conclusion.1">
<title><anchor xml:id="dbdoclet.5_Conclusion"/><emphasis role="bold">5. Conclusion</emphasis></title>
<para>In this tutorial we introduce security into a simple Spring MVC project by leveraging the Digest Authentication support in the framework.</para>
<para>The implementation of these examples can be found in <link xl:href="https://github.com/eugenp/tutorials/tree/master/spring-security-mvc-digest-auth#readme">the github project</link> – this is an Eclipse based project, so it should be easy to import and run as it is.</para>
<para>When the project runs locally, the homepage html can be accessed at (or, with minimal Tomcat configuration, on port 80):</para>
<para><link xl:href="http://localhost:8080/spring-security-mvc-digest-auth/homepage.html">http://localhost:8080/spring-security-mvc-digest-auth/homepage.html</link></para>
<para>Finally, there is no reason an application needs to <link xl:href="http://www.baeldung.com/2011/11/20/basic-and-digest-authentication-for-a-restful-service-with-spring-security-3-1/">choose between Basic and Digest authentication</link> <emphasis role="bold">both can be set up simultaneously on the same URI structure</emphasis>, in such a way that the client can pick between the two mechanisms when consuming the web application.</para>
<!--
Start Shortcoder content
-->
<!--
End Shortcoder content
-->
<para><link xl:href=""/></para>
<anchor xml:id="dd_ajax_float"/>
<para><link xl:href="http://twitter.com/share"/></para>
<!--
OptinSkin
-->
<anchor xml:id="ois_12"/>
<!--
End OptinSkin
-->
<!--
/.entry
-->
<para><emphasis role="italic"/><link xl:href="http://www.baeldung.com/tag/security/">security</link>, <link xl:href="http://www.baeldung.com/tag/spring/">Spring</link></para>
<!--
/.post
-->
<!--
/#main
-->
<anchor xml:id="optinskin-widget-3"/>
<!--
OptinSkin
-->
<anchor xml:id="ois_5"/>
<!--
End OptinSkin
-->
<!--
/#sidebar
-->
<!--
/#main-sidebar-container
-->
<!--
/#content
-->
<anchor xml:id="copyright"/>
<para>© 2014 Baeldung. All Rights Reserved. </para>
<anchor xml:id="credit"/>
<!--
/#inner-wrapper
-->
<!--
/#wrapper
-->
<!--
/.fix
-->
<!--
ngg_resource_manager_marker
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 Begin
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 End
-->
</section>
</section>
</article>
<?xml version="1.0" encoding="UTF-8"?>
<article version="5.0" xml:lang="en-US" xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink">
<info>
<title>Basic and Digest Authentication for a REST Service with Spring Security</title>
</info>
<anchor xml:id="wrapper"/>
<anchor xml:id="inner-wrapper"/>
<!--
/#side-nav
-->
<!--
/.menus
-->
<para><link linkend="top">Return to Content</link></para>
<!--
#content Starts
-->
<anchor xml:id="content"/>
<anchor xml:id="main-sidebar-container"/>
<!--
#main Starts
-->
<anchor xml:id="toc_container"/>
<para>Contents</para>
<itemizedlist>
<listitem>
<para><link linkend="Table_of_Contents">Table of Contents</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.1_Overview">1. Overview</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.2_Configuration_of_Basic_Authentication">2. Configuration of Basic Authentication</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.3_Configuration_of_Digest_Authentication">3. Configuration of Digest Authentication</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.4_Supporting_both_authentication_protocols_in_the_same_RESTful_service">4. Supporting both authentication protocols in the same RESTful service</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.5_Testing_both_scenarios">5. Testing both scenarios</link></para>
</listitem>
<listitem>
<para><link linkend="dbdoclet.6_Conclusion">6. Conclusion</link></para>
</listitem>
</itemizedlist>
<para>If you&apos;re new here, <link xl:href="https://my.leadpages.net/leadbox/146382273f72a2%3A13a71ac76b46dc/5735865741475840/">you may want to get my &quot;REST APIs with Spring&quot; eBook</link>. Thanks for visiting!</para>
<para><link xl:href=""/></para>
<!--
Start Shortcoder content
-->
<!--
End Shortcoder content
-->
<section>
<title><anchor xml:id="Table_of_Contents"/><emphasis role="bold">Table of Contents</emphasis></title>
<itemizedlist>
<listitem>
<para><link linkend="overview"><emphasis role="bold">1. </emphasis>Overview</link></para>
</listitem>
<listitem>
<para><link linkend="basic"><emphasis role="bold">2. </emphasis>Configuration of Basic Authentication</link></para>
</listitem>
<listitem>
<para><link linkend="basic"><emphasis role="bold">    2.1. </emphasis>Satisfying the stateless constraint getting rid of sessions</link></para>
</listitem>
<listitem>
<para><link linkend="digest"><emphasis role="bold">3. </emphasis>Configuration of Digest Authentication</link></para>
</listitem>
<listitem>
<para><link linkend="both"><emphasis role="bold">4. </emphasis>Supporting both authentication protocols in the same RESTful service</link></para>
</listitem>
<listitem>
<para><link linkend="both"><emphasis role="bold">    4.1. </emphasis>Anonymous request</link></para>
</listitem>
<listitem>
<para><link linkend="both"><emphasis role="bold">    4.2. </emphasis>Request with authentication credentials</link></para>
</listitem>
<listitem>
<para><link linkend="testing"><emphasis role="bold">5. </emphasis>Testing both scenarios</link></para>
</listitem>
<listitem>
<para><link linkend="conclusion"><emphasis role="bold">6. </emphasis>Conclusion</link></para>
</listitem>
</itemizedlist>
<section xml:id="overview.1">
<title><anchor xml:id="dbdoclet.1_Overview"/><emphasis role="bold">1. Overview</emphasis></title>
<para>This article discusses how to <emphasis role="bold">set up both Basic and Digest Authentication on the same URI structure of a REST API</emphasis>. In a previous article, we discussed another method of securing the REST Service <link xl:href="http://www.baeldung.com/2011/10/31/securing-a-restful-web-service-with-spring-security-3-1-part-3/">form based authentication</link>, so Basic and Digest authentication is the natural alternative, as well as the more RESTful one.</para>
</section>
<section xml:id="basic.1">
<title><anchor xml:id="dbdoclet.2_Configuration_of_Basic_Authentication"/><emphasis role="bold">2. Configuration of Basic Authentication</emphasis></title>
<para>The main reason that form based authentication is not ideal for a RESTful Service is that Spring Security will <emphasis role="bold">make use of Sessions</emphasis> this is of course state on the server, so <emphasis role="bold">the statelessness constraints in REST</emphasis> is practically ignored.</para>
<para>Well start by setting up Basic Authentication first we remove the old custom entry point and filter from the main <emphasis>&lt;http&gt;</emphasis> security element:</para>
<screen>&lt;http create-session=&quot;stateless&quot;&gt;
&lt;intercept-url pattern=&quot;/api/admin/**&quot; access=&quot;ROLE_ADMIN&quot; /&gt;
&lt;http-basic /&gt;
&lt;/http&gt;</screen>
<para>Note how support for basic authentication has been added with a single configuration line <emphasis>&lt;http-basic /&gt;</emphasis> which handles the creation and wiring of both the <emphasis>BasicAuthenticationFilter</emphasis> and the <emphasis>BasicAuthenticationEntryPoint</emphasis>.</para>
<section xml:id="ch_2_1.1">
<title><emphasis role="bold">2.1. Satisfying the stateless constraint getting rid of sessions</emphasis></title>
<para>One of the main constraints of the RESTful architectural style is that the client-server communication is fully <emphasis role="bold">stateless</emphasis>, as the <link xl:href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">original dissertation</link> reads:</para>
<blockquote>
<para>     <emphasis role="bold">5.1.3 Stateless</emphasis></para>
<para>We next add a constraint to the client-server interaction: communication must be stateless in nature, as in the client-stateless-server (CSS) style of Section 3.4.3 (Figure 5-3), such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. <emphasis role="bold">Session state is therefore kept entirely on the client</emphasis>.</para>
</blockquote>
<para>The concept of <emphasis role="bold">Session</emphasis> on the server is one with a long history in Spring Security, and removing it entirely has been difficult until now, especially when configuration was done by using the namespace. However, Spring Security 3.1 <link xl:href="https://jira.springsource.org/browse/SEC-1424">augments</link> the namespace configuration with a <emphasis role="bold">new stateless option</emphasis> for session creation, which effectively guarantees that no session will be created or used by Spring. What this new option does is completely removes all session related filters from the security filter chain, ensuring that authentication is performed for each request.</para>
</section>
</section>
<section xml:id="digest.1">
<title><anchor xml:id="dbdoclet.3_Configuration_of_Digest_Authentication"/><emphasis role="bold">3. Configuration of Digest Authentication</emphasis></title>
<para>Starting with the previous configuration, the filter and entry point necessary to set up digest authentication will be defined as beans. Then, the <emphasis role="bold">digest entry point</emphasis> will override the one created by <emphasis>&lt;http-basic&gt;</emphasis> behind the scenes. Finally, the custom <emphasis role="bold">digest filter</emphasis> will be introduced in the security filter chain using the <emphasis>after</emphasis> semantics of the security namespace to position it directly after the basic authentication filter.</para>
<screen>&lt;http create-session=&quot;stateless&quot; entry-point-ref=&quot;digestEntryPoint&quot;&gt;
&lt;intercept-url pattern=&quot;/api/admin/**&quot; access=&quot;ROLE_ADMIN&quot; /&gt;
&lt;http-basic /&gt;
&lt;custom-filter ref=&quot;digestFilter&quot; after=&quot;BASIC_AUTH_FILTER&quot; /&gt;
&lt;/http&gt;
&lt;beans:bean id=&quot;digestFilter&quot; class=
&quot;org.springframework.security.web.authentication.www.DigestAuthenticationFilter&quot;&gt;
&lt;beans:property name=&quot;userDetailsService&quot; ref=&quot;userService&quot; /&gt;
&lt;beans:property name=&quot;authenticationEntryPoint&quot; ref=&quot;digestEntryPoint&quot; /&gt;
&lt;/beans:bean&gt;
&lt;beans:bean id=&quot;digestEntryPoint&quot; class=
&quot;org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint&quot;&gt;
&lt;beans:property name=&quot;realmName&quot; value=&quot;Contacts Realm via Digest Authentication&quot;/&gt;
&lt;beans:property name=&quot;key&quot; value=&quot;acegi&quot; /&gt;
&lt;/beans:bean&gt;
&lt;authentication-manager&gt;
&lt;authentication-provider&gt;
&lt;user-service id=&quot;userService&quot;&gt;
&lt;user name=&quot;eparaschiv&quot; password=&quot;eparaschiv&quot; authorities=&quot;ROLE_ADMIN&quot; /&gt;
&lt;user name=&quot;user&quot; password=&quot;user&quot; authorities=&quot;ROLE_USER&quot; /&gt;
&lt;/user-service&gt;
&lt;/authentication-provider&gt;
&lt;/authentication-manager&gt;</screen>
<para>Unfortunately there is no <link xl:href="https://jira.springsource.org/browse/SEC-1860">support</link> in the security namespace to automatically configure the digest authentication the way basic authentication can be configured with <emphasis>&lt;http-basic&gt;</emphasis>. Because of that, the necessary beans had to be defined and wired manually into the security configuration.</para>
</section>
<section xml:id="both.1">
<title><anchor xml:id="dbdoclet.4_Supporting_both_authentication_protocols_in_the_same_RESTful_service"/><emphasis role="bold">4. Supporting both authentication protocols in the same RESTful service</emphasis></title>
<para>Basic or Digest authentication alone can be easily implemented in Spring Security 3.x; it is supporting both of them for the same RESTful web service, on the same URI mappings that introduces a new level of complexity into the configuration and testing of the service.</para>
<section xml:id="ch_4_1.1">
<title><emphasis role="bold">4.1. Anonymous request</emphasis></title>
<para>With both basic and digest filters in the security chain, the way a <emphasis role="bold">anonymous request</emphasis> a request containing no authentication credentials (<emphasis>Authorization</emphasis> HTTP header) is processed by Spring Security is the two authentication filters will find <emphasis role="bold">no credentials</emphasis> and will continue execution of the filter chain. Then, seeing how the request wasnt authenticated, an <emphasis>AccessDeniedException</emphasis> is thrown and caught in the <emphasis>ExceptionTranslationFilter</emphasis>, which commences the digest entry point, prompting the client for credentials.</para>
<para>The responsibilities of both the basic and digest filters are very narrow they will continue to execute the security filter chain if they are unable to identify the type of authentication credentials in the request. It is because of this that Spring Security can have the flexibility to be configured with support for multiple authentication protocols on the same URI.</para>
<para>When a request is made containing the correct authentication credentials either basic or digest that protocol will be rightly used. However, for an anonymous request, the client will get prompted only for digest authentication credentials. This is because the digest entry point is configured as the main and single entry point of the Spring Security chain; as such <emphasis role="bold">digest authentication can be considered the default</emphasis>.</para>
</section>
<section xml:id="ch_4_2.1">
<title><emphasis role="bold">4.2. Request with authentication credentials</emphasis></title>
<para>A <emphasis role="bold">request with credentials</emphasis> for Basic authentication will be identified by the <emphasis>Authorization</emphasis> header starting with the prefix <emphasis>“Basic”</emphasis>. When processing such a request, the credentials will be decoded in the basic authentication filter and the request will be authorized. Similarly, a request with credentials for Digest authentication will use the prefix <emphasis>“Digest”</emphasis>  for its <emphasis>Authorization</emphasis> header.</para>
</section>
</section>
<section xml:id="testing.1">
<title><anchor xml:id="dbdoclet.5_Testing_both_scenarios"/><emphasis role="bold">5. Testing both scenarios</emphasis></title>
<para>The tests will consume the REST service by creating a new resource after authenticating with either basic or digest:</para>
<screen>@Test
public void givenAuthenticatedByBasicAuth_whenAResourceIsCreated_then201IsReceived(){
// Given
// When
Response response = given()
.auth().preemptive().basic( ADMIN_USERNAME, ADMIN_PASSWORD )
.contentType( HttpConstants.MIME_JSON ).body( new Foo( randomAlphabetic( 6 ) ) )
.post( paths.getFooURL() );
// Then
assertThat( response.getStatusCode(), is( 201 ) );
}
@Test
public void givenAuthenticatedByDigestAuth_whenAResourceIsCreated_then201IsReceived(){
// Given
// When
Response response = given()
.auth().digest( ADMIN_USERNAME, ADMIN_PASSWORD )
.contentType( HttpConstants.MIME_JSON ).body( new Foo( randomAlphabetic( 6 ) ) )
.post( paths.getFooURL() );
// Then
assertThat( response.getStatusCode(), is( 201 ) );
}</screen>
<para>Note that the test using basic authentication adds credentials to the request <emphasis role="bold">preemptively</emphasis>, regardless if the server has challenged for authentication or not. This is to ensure that the server doesnt need to challenge the client for credentials, because if it did, the challenge would be for Digest credentials, since that is the default.</para>
</section>
<section xml:id="conclusion.1">
<title><anchor xml:id="dbdoclet.6_Conclusion"/><emphasis role="bold">6. Conclusion</emphasis></title>
<para>This article covered the configuration and implementation of both Basic and Digest authentication for a RESTful service, using mostly Spring Security 3.0 namespace support as well as some new features added by Spring Security 3.1.</para>
<para>For the full implementation, check out the <link xl:href="https://github.com/eugenp/REST#readme">github project</link>.</para>
<!--
Start Shortcoder content
-->
<!--
End Shortcoder content
-->
<para><link xl:href=""/></para>
<anchor xml:id="dd_ajax_float"/>
<para><link xl:href="http://twitter.com/share"/></para>
<!--
OptinSkin
-->
<anchor xml:id="ois_12"/>
<!--
End OptinSkin
-->
<!--
/.entry
-->
<para><emphasis role="italic"/><link xl:href="http://www.baeldung.com/tag/rest/">REST</link>, <link xl:href="http://www.baeldung.com/tag/security/">security</link>, <link xl:href="http://www.baeldung.com/tag/spring/">Spring</link></para>
<!--
/.post
-->
<!--
/#main
-->
<anchor xml:id="optinskin-widget-3"/>
<!--
OptinSkin
-->
<anchor xml:id="ois_5"/>
<!--
End OptinSkin
-->
<!--
/#sidebar
-->
<!--
/#main-sidebar-container
-->
<!--
/#content
-->
<anchor xml:id="copyright"/>
<para>© 2014 Baeldung. All Rights Reserved. </para>
<anchor xml:id="credit"/>
<!--
/#inner-wrapper
-->
<!--
/#wrapper
-->
<!--
/.fix
-->
<!--
ngg_resource_manager_marker
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 Begin
-->
<!--
WP SyntaxHighlighter Ver.1.7.3 End
-->
</section>
</section>
</article>