<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4889069596572374242</id><updated>2012-01-03T13:30:20.951+01:00</updated><category term='rest'/><category term='spring-batch'/><category term='gridgain'/><category term='dispatch'/><category term='crowd'/><category term='scala'/><category term='java'/><category term='ntlm'/><category term='sso'/><category term='spring'/><category term='security'/><category term='spring-security'/><category term='vim'/><category term='text-mining'/><category term='json'/><category term='batch'/><category term='sjson'/><title type='text'>Alois Cochard's Blog</title><subtitle type='html'>Computer Development</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://aloiscochard.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://aloiscochard.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Alois Cochard</name><uri>http://www.blogger.com/profile/00906716915320183913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_t94Ly78JPSg/S6aEt2puBXI/AAAAAAAAAIc/JRSP4keuHgU/S220/avatar-popey-bw-transparent.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4889069596572374242.post-2366047173458092788</id><published>2011-05-16T15:28:00.000+02:00</published><updated>2011-05-16T15:28:39.166+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rest'/><category scheme='http://www.blogger.com/atom/ns#' term='sjson'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='dispatch'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>A simple (REST) web service client in Scala</title><content type='html'>For the purpose of creating a nice API for my new project &lt;a href="http://www.caligo-project.org/"&gt;Caligo&lt;/a&gt;&amp;nbsp;(more on this in a future blog post), I was looking for a simple solution to access REST web service in &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;My&amp;nbsp;requirement&amp;nbsp;was simple: access an HTTP web service, and exchange&amp;nbsp;data with him using the &lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt;&amp;nbsp;format.&lt;br /&gt;&lt;br /&gt;During my experiment I came across theses two nice&amp;nbsp;&lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;&amp;nbsp;libraries:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://dispatch.databinder.net/"&gt;Dispatch&lt;/a&gt;: It's a Scala DSL build on the rock-solid &lt;a href="http://hc.apache.org/httpcomponents-client-ga/index.html"&gt;Apache HttpClient&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/debasishg/sjson"&gt;SJSON&lt;/a&gt;: A well designed JSON serializer with reflection support (created by &lt;a href="http://twitter.com/debasishg"&gt;Debasish Gosh&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;a href="http://dispatch.databinder.net/"&gt;Dispatch&lt;/a&gt;&amp;nbsp;seems to be the only available HTTP client for&amp;nbsp;&lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;&amp;nbsp;today, and since it's based on the Apache's one no need to worry about his reliability&amp;nbsp;or&amp;nbsp;compatibility.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/debasishg/sjson"&gt;SJSON&lt;/a&gt;&amp;nbsp;was choose against &lt;a href="https://github.com/lift/lift/tree/master/framework/lift-base/lift-json/"&gt;Lift-JSON&lt;/a&gt;&amp;nbsp;due to it's better handling of reflection on beans, both of them did a great job on case classes, but only&amp;nbsp;&lt;a href="https://github.com/debasishg/sjson"&gt;SJSON&lt;/a&gt;&amp;nbsp;was effective on beans (was mandatory for me since I must do polymorphism on my model and case classes do not support this).&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;a href="https://github.com/lift/lift/tree/master/framework/lift-base/lift-json/"&gt;Lift-JSON&lt;/a&gt;&amp;nbsp;support of beans (thru&amp;nbsp;reflection) must be improved on the version targeting&amp;nbsp;&lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;&amp;nbsp;2.9&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Here is a sample usage of the frameworks, both of them are easily integrated, and using the power of the&amp;nbsp;&lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;&amp;nbsp;syntax a full client request doesn't take that much code to be implemented (in this case 4 lines of code, model included):&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/970258.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4889069596572374242-2366047173458092788?l=aloiscochard.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aloiscochard.blogspot.com/feeds/2366047173458092788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://aloiscochard.blogspot.com/2011/05/simple-rest-web-service-client-in-scala.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/2366047173458092788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/2366047173458092788'/><link rel='alternate' type='text/html' href='http://aloiscochard.blogspot.com/2011/05/simple-rest-web-service-client-in-scala.html' title='A simple (REST) web service client in Scala'/><author><name>Alois Cochard</name><uri>http://www.blogger.com/profile/00906716915320183913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_t94Ly78JPSg/S6aEt2puBXI/AAAAAAAAAIc/JRSP4keuHgU/S220/avatar-popey-bw-transparent.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4889069596572374242.post-5880581238609503239</id><published>2010-06-30T19:19:00.000+02:00</published><updated>2010-06-30T19:19:19.665+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='text-mining'/><title type='text'>Bring Your Code: An algorithm for index translation</title><content type='html'>I'm actually working on a &lt;a href="http://en.wikipedia.org/wiki/Text_mining"&gt;text-mining&lt;/a&gt;/&lt;a href="http://en.wikipedia.org/wiki/Semantic_Web"&gt;semantic&lt;/a&gt;&amp;nbsp;web application focused (for the moment) on biomedical informations and developed in Java.&lt;br /&gt;We are using external tools for&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Text_mining"&gt;text-mining&lt;/a&gt;&amp;nbsp;analysis and unfortunatly theses tools don't handle HTML pretty well ...&lt;br /&gt;If we send raw HTML to the&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Text_mining"&gt;text-mining&lt;/a&gt;&amp;nbsp;service, he simply break.&lt;br /&gt;So we must convert HTML to plain-text before processing text, and because the tools return identified&amp;nbsp;words&amp;nbsp;by giving their positions,&amp;nbsp;we must translate theses position (or indexes) to find corresponding word in the original HTML.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Bring Your Code&lt;/span&gt;&lt;br /&gt;I've searched the web but didn't find any code that I can reuse, so I created a simple 'IndexTranslator' class.&lt;br /&gt;I'm sure that my implementation of this algorithm isn't the best (a bit under pressure due to production deployment), so I'm looking for a better one.&lt;br /&gt;Keep in mind &amp;nbsp;that this code is used in an&amp;nbsp;enterprise&amp;nbsp;application and must be relatively easy to maintain (even it's a bit less efficient) .&lt;br /&gt;&lt;br /&gt;I created a&amp;nbsp;&lt;a href="http://gist.github.com/458949"&gt;gist&lt;/a&gt;&amp;nbsp;with the implementation and the corresponding &lt;a href="http://www.junit.org/"&gt;JUnit&lt;/a&gt;&amp;nbsp;test case to let you fork the code and see if it work as I expect.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gist.github.com/458949#file_index_translator.java"&gt;&lt;b&gt;IndexTranslator.java&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/458949.js?file=IndexTranslator.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;a href="http://gist.github.com/458949#file_index_translator_test.java"&gt;&lt;b&gt;IndexTranslatorTest.java&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/458949.js?file=IndexTranslatorTest.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;a href="http://gist.github.com/458949"&gt;Let's fork !&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;By the way, if you are aware of a library implementing this, I'm ready to send this code to the garbage and use the library instead !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4889069596572374242-5880581238609503239?l=aloiscochard.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aloiscochard.blogspot.com/feeds/5880581238609503239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://aloiscochard.blogspot.com/2010/06/bring-your-code-algorithm-for-index.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/5880581238609503239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/5880581238609503239'/><link rel='alternate' type='text/html' href='http://aloiscochard.blogspot.com/2010/06/bring-your-code-algorithm-for-index.html' title='Bring Your Code: An algorithm for index translation'/><author><name>Alois Cochard</name><uri>http://www.blogger.com/profile/00906716915320183913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_t94Ly78JPSg/S6aEt2puBXI/AAAAAAAAAIc/JRSP4keuHgU/S220/avatar-popey-bw-transparent.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4889069596572374242.post-6139730567702131880</id><published>2010-06-22T13:03:00.003+02:00</published><updated>2010-06-22T13:08:20.926+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Vim is everywhere</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/aloiscochard/4723428183/" title="photo sharing"&gt;&lt;img alt="" src="http://farm2.static.flickr.com/1070/4723428183_f9f1aa7f90_m.jpg" style="border-bottom-color: rgb(0, 0, 0); border-bottom-style: solid; border-bottom-width: 2px; border-left-color: rgb(0, 0, 0); border-left-style: solid; border-left-width: 2px; border-right-color: rgb(0, 0, 0); border-right-style: solid; border-right-width: 2px; border-top-color: rgb(0, 0, 0); border-top-style: solid; border-top-width: 2px;" /&gt;&lt;/a&gt;&lt;/div&gt;I'm now sure that vim is the perfect tool to write *clean* code !&lt;br /&gt;&lt;br /&gt;And for vim fanatics, you can even get vim inside NetBeans (integration work much better than in Eclipse):&lt;br /&gt;&lt;a href="http://jvi.sourceforge.net/"&gt;http://jvi.sourceforge.net/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4889069596572374242-6139730567702131880?l=aloiscochard.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aloiscochard.blogspot.com/feeds/6139730567702131880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://aloiscochard.blogspot.com/2010/06/vim-is-everywhere.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/6139730567702131880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/6139730567702131880'/><link rel='alternate' type='text/html' href='http://aloiscochard.blogspot.com/2010/06/vim-is-everywhere.html' title='Vim is everywhere'/><author><name>Alois Cochard</name><uri>http://www.blogger.com/profile/00906716915320183913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_t94Ly78JPSg/S6aEt2puBXI/AAAAAAAAAIc/JRSP4keuHgU/S220/avatar-popey-bw-transparent.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1070/4723428183_f9f1aa7f90_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4889069596572374242.post-5107746231235991258</id><published>2010-04-30T23:15:00.005+02:00</published><updated>2010-04-30T23:23:57.656+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring-batch'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='batch'/><category scheme='http://www.blogger.com/atom/ns#' term='gridgain'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><title type='text'>Spring Batch integration module for GridGain</title><content type='html'>For the purpose of using &lt;a href="http://static.springsource.org/spring-batch/"&gt;Spring Batch&lt;/a&gt; in a scalable and distributed manner to process huge amount of data, I am actually developing some components to make integration of&amp;nbsp;&lt;a href="http://static.springsource.org/spring-batch/"&gt;Spring Batch&lt;/a&gt;&amp;nbsp;with compute/data grid easier.&lt;br /&gt;&lt;br /&gt;Different solutions is offered by&amp;nbsp;&lt;a href="http://static.springsource.org/spring-batch/"&gt;Spring Batch&lt;/a&gt;&amp;nbsp;to provide &lt;a href="http://static.springsource.org/spring-batch/reference/html/scalability.html"&gt;scalability&lt;/a&gt;, the one that best suit my needs is &lt;a href="http://static.springsource.org/spring-batch/reference/html/scalability.html#remoteChunking"&gt;remote chunking&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As I already done some investigation before using &lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt; I chose this framework to implement a distributed&amp;nbsp;&lt;a href="http://static.springsource.org/spring-batch/reference/html/scalability.html#remoteChunking"&gt;remote chunking&lt;/a&gt;&amp;nbsp;system that can be&amp;nbsp;easily&amp;nbsp;integrated into any existing&amp;nbsp;&lt;a href="http://static.springsource.org/spring-batch/"&gt;Spring Batch&lt;/a&gt;&amp;nbsp;systems.&lt;br /&gt;&lt;br /&gt;Using&amp;nbsp;&lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt;&amp;nbsp;is really straightforward, and setting up a grid on a development machine doesn't need so much configuration.&lt;br /&gt;&lt;br /&gt;The only issue I faced is due to the fact that&amp;nbsp;&lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt;&amp;nbsp;use serialization to deploy tasks on nodes, in order to be able to deploy a remote &lt;a href="http://static.springsource.org/spring-batch/apidocs/org/springframework/batch/core/step/item/ChunkProcessor.html"&gt;ChunkProcessor&lt;/a&gt;, it must&amp;nbsp;contains serializable ItemProcessor and ItemWriter, which unfortunately&amp;nbsp;is not the case by default.&lt;br /&gt;&lt;br /&gt;So instead of creating new interfaces, I made a&amp;nbsp;SerializableChunkProcessor which only accept serializable &lt;a href="http://static.springsource.org/spring-batch/apidocs/org/springframework/batch/item/ItemProcessor.html"&gt;ItemProcessor&lt;/a&gt; and &lt;a href="http://static.springsource.org/spring-batch/apidocs/org/springframework/batch/item/ItemWriter.html"&gt;ItemWriter&lt;/a&gt;. It's surely not the smarter solution, but since I can't modify default interfaces in&amp;nbsp;&lt;a href="http://static.springsource.org/spring-batch/"&gt;Spring Batch&lt;/a&gt;&amp;nbsp;and I don't want to create my own interfaces, this workaround will suffice.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Usage&lt;/span&gt;&lt;br /&gt;Here is the job application context used for the integration test, as you can see the 'real'&amp;nbsp;&lt;a href="http://static.springsource.org/spring-batch/apidocs/org/springframework/batch/item/ItemProcessor.html"&gt;ItemProcessor&lt;/a&gt;&amp;nbsp;/&amp;nbsp;&lt;a href="http://static.springsource.org/spring-batch/apidocs/org/springframework/batch/item/ItemWriter.html"&gt;ItemWriter&lt;/a&gt;&amp;nbsp;are injected into the&amp;nbsp;&lt;a href="http://www.gridgain.com/"&gt;GridGain&lt;/a&gt;&amp;nbsp;chunk writer:&lt;br /&gt;&lt;textarea class="xml" name="code"&gt; &amp;lt;!-- Standards items component --&amp;gt;&amp;lt;br/&amp;gt; &amp;lt;bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader"&amp;gt;&amp;lt;br/&amp;gt;  &amp;lt;property name="resource" value="classpath:sentences.txt"/&amp;gt;&amp;lt;br/&amp;gt;  &amp;lt;property name="lineMapper"&amp;gt;&amp;lt;br/&amp;gt;   &amp;lt;bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper"&amp;gt;&amp;lt;br/&amp;gt;    &amp;lt;property name="fieldSetMapper"&amp;gt;&amp;lt;br/&amp;gt;     &amp;lt;bean class="org.springframework.batch.integration.chunk.gridgain.SentenceFieldSetMapper"/&amp;gt;&amp;lt;br/&amp;gt;    &amp;lt;/property&amp;gt;&amp;lt;br/&amp;gt;    &amp;lt;property name="lineTokenizer"&amp;gt;&amp;lt;br/&amp;gt;     &amp;lt;bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"&amp;gt;&amp;lt;br/&amp;gt;      &amp;lt;property name="delimiter" value="\"/&amp;gt;&amp;lt;br/&amp;gt;     &amp;lt;/bean&amp;gt;&amp;lt;br/&amp;gt;    &amp;lt;/property&amp;gt;&amp;lt;br/&amp;gt;   &amp;lt;/bean&amp;gt;&amp;lt;br/&amp;gt;  &amp;lt;/property&amp;gt;&amp;lt;br/&amp;gt; &amp;lt;/bean&amp;gt;&amp;lt;br/&amp;gt; &amp;lt;br/&amp;gt; &amp;lt;bean id="processor" class="org.springframework.batch.integration.chunk.gridgain.WordCounterProcessor"/&amp;gt;&amp;lt;br/&amp;gt; &amp;lt;br/&amp;gt; &amp;lt;bean id="writer" class="org.springframework.batch.integration.chunk.gridgain.ConsoleWriter"/&amp;gt;&amp;lt;br/&amp;gt; &amp;lt;br/&amp;gt; &amp;lt;!-- Chunk Writer --&amp;gt;&amp;lt;br/&amp;gt; &amp;lt;bean id="chunkWriter" class="org.springframework.batch.integration.chunk.gridgain.ChunkGridGainItemWriter"&amp;gt;&amp;lt;br/&amp;gt;  &amp;lt;property name="chunkProcessor"&amp;gt;&amp;lt;br/&amp;gt;   &amp;lt;bean class="org.springframework.batch.integration.chunk.SerializableChunkProcessor"&amp;gt;&amp;lt;br/&amp;gt;    &amp;lt;property name="itemProcessor" ref="processor"/&amp;gt;&amp;lt;br/&amp;gt;    &amp;lt;property name="itemWriter" ref="writer"/&amp;gt;&amp;lt;br/&amp;gt;   &amp;lt;/bean&amp;gt;&amp;lt;br/&amp;gt;  &amp;lt;/property&amp;gt;&amp;lt;br/&amp;gt;  &amp;lt;property name="grid" ref="grid"/&amp;gt;&amp;lt;br/&amp;gt;  &amp;lt;property name="throttleLimit" value="16"/&amp;gt;&amp;lt;br/&amp;gt; &amp;lt;/bean&amp;gt;&amp;lt;br/&amp;gt; &amp;lt;br/&amp;gt; &amp;lt;!-- Job --&amp;gt;&amp;lt;br/&amp;gt; &amp;lt;job id="gridgainJob" xmlns="http://www.springframework.org/schema/batch"&amp;gt;&amp;lt;br/&amp;gt;  &amp;lt;step id="step1"&amp;gt;&amp;lt;br/&amp;gt;   &amp;lt;tasklet&amp;gt;&amp;lt;br/&amp;gt;    &amp;lt;chunk reader="reader" writer="chunkWriter" commit-interval="4"/&amp;gt;&amp;lt;br/&amp;gt;   &amp;lt;/tasklet&amp;gt;&amp;lt;br/&amp;gt;  &amp;lt;/step&amp;gt;&amp;lt;br/&amp;gt; &amp;lt;/job&amp;gt;&lt;/textarea&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Download&lt;/span&gt;&lt;br /&gt;You can download the spring-batch-integration-gridgain module here:&lt;br /&gt;&lt;a href="http://github.com/downloads/aloiscochard/spring-batch-integration-gridgain/spring-batch-integration-gridgain-0.0.1-SNAPSHOT.jar"&gt;http://github.com/downloads/aloiscochard/spring-batch-integration-gridgain/spring-batch-integration-gridgain-0.0.1-SNAPSHOT.jar&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you want to see a full working sample, take a look&amp;nbsp;at the integration test. The full project sources can be downloaded here:&lt;br /&gt;&lt;a href="http://github.com/aloiscochard/spring-batch-integration-gridgain"&gt;http://github.com/aloiscochard/spring-batch-integration-gridgain&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4889069596572374242-5107746231235991258?l=aloiscochard.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aloiscochard.blogspot.com/feeds/5107746231235991258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://aloiscochard.blogspot.com/2010/04/spring-batch-integration-module-for.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/5107746231235991258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/5107746231235991258'/><link rel='alternate' type='text/html' href='http://aloiscochard.blogspot.com/2010/04/spring-batch-integration-module-for.html' title='Spring Batch integration module for GridGain'/><author><name>Alois Cochard</name><uri>http://www.blogger.com/profile/00906716915320183913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_t94Ly78JPSg/S6aEt2puBXI/AAAAAAAAAIc/JRSP4keuHgU/S220/avatar-popey-bw-transparent.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4889069596572374242.post-681621465555720492</id><published>2010-03-25T21:41:00.006+01:00</published><updated>2010-03-25T21:49:49.762+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ntlm'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='spring-security'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Integrating failover strategy for Spring Security NTLM</title><content type='html'>During implementation of the &lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt; authentication into our application, I wanted to achieve failover to standard login page (html form) if&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&amp;nbsp;authentication fail.&lt;br /&gt;&lt;br /&gt;In order to obtain the wanted behavior I extended some &lt;a href="http://static.springsource.org/spring-security/site/"&gt;Spring Security&lt;/a&gt; classes and hack them a little bit, so I created:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;An AuthenticationEntryPoint strategy to switch between&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&amp;nbsp;or standard login&lt;/li&gt;&lt;li&gt;A custom AuthenticationProvider to prevent password checking when user authenticate with&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&lt;/li&gt;&lt;li&gt;A custom NtlmProcessingFilter to disable&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&amp;nbsp;authentication if a remember-me cookie is present&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The thing I was unable to do is detecting if the user client is&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&amp;nbsp;compliant before starting the&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&amp;nbsp;challenge. Due to the way the protocol is build (and certainly for security reasons) it's impossible to know if the client is&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&amp;nbsp;compliant before launching the challenge.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So let's took the scenario of a &lt;a href="http://www.google.com/chrome"&gt;Google Chrome&lt;/a&gt; user:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;A popup (HTTP realm) authentication window is shown to the user&lt;/li&gt;&lt;li&gt;He hit enter with invalid credentials (i.e. empty username/password)&lt;/li&gt;&lt;li&gt;The browser is redirected to the standard html login form&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;By using 'remember me' the&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&amp;nbsp;authentication won't be shown next time the user access the site due to the presence of the cookie.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If the user client is&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Internet_Explorer"&gt;Internet Explorer&lt;/a&gt; no authentication window is shown because the navigator use directly the information of the logged user. If the authentication fail, then the standard html login form is displayed letting him login with other credentials.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;This implementation was made using&amp;nbsp;&lt;a href="http://static.springsource.org/spring-security/site/"&gt;Spring Security&lt;/a&gt;&amp;nbsp;2.0.5, but can be easly converted to&amp;nbsp;&lt;a href="http://static.springsource.org/spring-security/site/"&gt;Spring Security&lt;/a&gt;&amp;nbsp;3.0 using the &lt;a href="http://aloiscochard.blogspot.com/2010/03/spring-security-ntlm-3.html"&gt;Spring Security NTLM 3&lt;/a&gt; module I recently created. Don't hesitate to ask me if you want that I publish an updated version.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Download&lt;/span&gt;&lt;br /&gt;You can download a sample application including hacked class here:&lt;br /&gt;&lt;a href="http://github.com/downloads/aloiscochard/spring-security-ntlm-samples/spring-security-ntlm-samples-2.0.5.SNAPSHOT.zip"&gt;http://github.com/downloads/aloiscochard/spring-security-ntlm-samples/spring-security-ntlm-samples-2.0.5.SNAPSHOT.zip&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4889069596572374242-681621465555720492?l=aloiscochard.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aloiscochard.blogspot.com/feeds/681621465555720492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://aloiscochard.blogspot.com/2010/03/integration-failover-strategy-for-ntlm.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/681621465555720492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/681621465555720492'/><link rel='alternate' type='text/html' href='http://aloiscochard.blogspot.com/2010/03/integration-failover-strategy-for-ntlm.html' title='Integrating failover strategy for Spring Security NTLM'/><author><name>Alois Cochard</name><uri>http://www.blogger.com/profile/00906716915320183913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_t94Ly78JPSg/S6aEt2puBXI/AAAAAAAAAIc/JRSP4keuHgU/S220/avatar-popey-bw-transparent.png'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4889069596572374242.post-1110617115099557864</id><published>2010-03-21T22:25:00.002+01:00</published><updated>2010-04-30T23:09:46.230+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ntlm'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='spring-security'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Spring Security NTLM 3</title><content type='html'>As of version 3.X &lt;a href="http://static.springsource.org/spring-security/site/"&gt;Spring Security&lt;/a&gt; doesn't include the&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&amp;nbsp;extension anymore.&lt;br /&gt;&lt;br /&gt;For the purpose of using&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt; authentication on &lt;a href="http://www.springsource.org/"&gt;Spring&lt;/a&gt; 3 projects, I migrated the 2.0.5&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&amp;nbsp;extension to the new version of&amp;nbsp;&lt;a href="http://static.springsource.org/spring-security/site/"&gt;Spring Security&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The full project sources are available here:&lt;br /&gt;&lt;a href="http://github.com/aloiscochard/spring-security-ntlm"&gt;http://github.com/aloiscochard/spring-security-ntlm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I haven't took time fixing&amp;nbsp;the following bugs found on version 2.0.5:&lt;br /&gt;&lt;a href="https://jira.springsource.org/browse/SEC-1003"&gt;https://jira.springsource.org/browse/SEC-1003&lt;/a&gt;&lt;br /&gt;&lt;a href="https://jira.springsource.org/browse/SEC-1003"&gt;&lt;/a&gt;&lt;a href="https://jira.springsource.org/browse/SEC-1087"&gt;https://jira.springsource.org/browse/SEC-1087&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If your are interested to help correcting this defects don't hesitate to get in touch.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Download&lt;/span&gt;&lt;br /&gt;You can download the spring-security-ntlm snapshot&amp;nbsp;here:&lt;br /&gt;&lt;a href="http://github.com/downloads/aloiscochard/spring-security-ntlm/spring-security-ntlm-3.0.2.SNAPSHOT.jar"&gt;http://github.com/downloads/aloiscochard/spring-security-ntlm/spring-security-ntlm-3.0.2.SNAPSHOT.jar&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Usage&lt;/span&gt;&lt;br /&gt;Due to the fact that NTLM isn't integrated in new version of spring-security-core, you need to add a custom filter.&lt;br /&gt;Here is a snippet describing briefly how to do that:&lt;br /&gt;&lt;textarea class="xml" name="code"&gt;&amp;lt;bean id="ntlmFilter" class="org.springframework.security.ui.ntlm.NtlmAuthenticationFilter"&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;property name="authenticationManager" ref="authenticationManager" /&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;property name="retryOnAuthFailure" value="false" /&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;/bean&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt; &amp;lt;bean id="nullRequestCacheAwareFilter" class="org.springframework.security.web.savedrequest.NullRequestCache"/&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt; &amp;lt;!-- HTTP configuration --&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;sec:http&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;sec:request-cache ref="nullRequestCacheAwareFilter"/&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;sec:custom-filter after="EXCEPTION_TRANSLATION_FILTER" ref="ntlmFilter"/&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt; &amp;lt;!-- ... your configuration here ...  --&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt; &amp;lt;/sec:http&amp;gt;&lt;/textarea&gt;Don't hesitate to ask if you need help, this extension work exactly as version 2.0.5. You can use an&amp;nbsp;example&amp;nbsp;from version 2.0.5 if you are starting from scratch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4889069596572374242-1110617115099557864?l=aloiscochard.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aloiscochard.blogspot.com/feeds/1110617115099557864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://aloiscochard.blogspot.com/2010/03/spring-security-ntlm-3.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/1110617115099557864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/1110617115099557864'/><link rel='alternate' type='text/html' href='http://aloiscochard.blogspot.com/2010/03/spring-security-ntlm-3.html' title='Spring Security NTLM 3'/><author><name>Alois Cochard</name><uri>http://www.blogger.com/profile/00906716915320183913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_t94Ly78JPSg/S6aEt2puBXI/AAAAAAAAAIc/JRSP4keuHgU/S220/avatar-popey-bw-transparent.png'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4889069596572374242.post-2726997190013416895</id><published>2009-12-19T11:55:00.003+01:00</published><updated>2010-04-30T22:37:44.524+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ntlm'/><category scheme='http://www.blogger.com/atom/ns#' term='crowd'/><category scheme='http://www.blogger.com/atom/ns#' term='sso'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='spring-security'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Integrating Spring Security with NTLM + Crowd</title><content type='html'>For the purpose of implementing a SSO (&lt;a href="http://en.wikipedia.org/wiki/Single_sign-on"&gt;Single Sign On&lt;/a&gt;) system into our application, I investigated the use of spring-security and successfully implemented it using &lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Crowd_%28software%29"&gt;Crowd&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sites.google.com/site/aloiscochard/development/20091217_spring-security-ntlm-crowd.zip"&gt;&lt;b&gt;Download Sample Project&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Technologies&lt;/span&gt;&lt;br /&gt;As most of our users are using Internet Explorer,&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt; seems to be the best solution. By the way, as developer we are using Firefox and fortunately Firefox can provide too &lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&amp;nbsp;credentials (see &lt;a href="http://pixiescorner.wordpress.com/2009/01/23/configure-ntlm-for-firefox-using-firefox-for-sharepoint-sites/"&gt;this&lt;/a&gt; to enable&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt; inside Firefox).&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt; is used for authentication only (giving windows credentials to the web application) then &lt;a href="http://en.wikipedia.org/wiki/Crowd_%28software%29"&gt;Crowd&lt;/a&gt; is used to store and retrieve user's authorizations.&lt;br /&gt;Atlassian&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Crowd_%28software%29"&gt;Crowd&lt;/a&gt; provide full spring-security integration, and a bunch of connector to communicate with most of directory services available.&lt;br /&gt;I first configured &lt;a href="http://en.wikipedia.org/wiki/Crowd_%28software%29"&gt;Crowd&lt;/a&gt; to use an internal directory to avoid being disrupted by communication with external directories. Then I added connection to our Microsoft Active Directory... but this go beyond the scope of this blog entry.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Prerequisites&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Add spring-security and spring-security-ntlm and theirs dependency in your project&lt;/li&gt;&lt;li&gt;Add crowd-integration-client and his dependency in your project&amp;nbsp;&lt;/li&gt;&lt;li&gt;Integrate &lt;a href="http://en.wikipedia.org/wiki/Crowd_%28software%29"&gt;Crowd&lt;/a&gt; integration client by following &lt;a href="http://confluence.atlassian.com/display/CROWD/Integrating+Crowd+with+Spring+Security"&gt;this documentation&lt;/a&gt; from step 1 to 3.0&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;Integration&lt;/span&gt;&lt;br /&gt;First of all, create a new spring application context (applicationContext-security.xml) with the following content :&lt;br /&gt;&lt;textarea class="xml:collapse" name="code"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  xmlns:sec="http://www.springframework.org/schema/security"  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd   http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd"&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;  &amp;lt;sec:authentication-manager alias="authenticationManager"/&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;  &amp;lt;!-- Custom authentication provider --&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;bean id="daoAuthenticationProvider" class="com.mycompany.security.UserDetailsAuthenticationProvider"&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;sec:custom-authentication-provider/&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;property name="userDetailsService"&amp;gt;&amp;lt;br /&amp;gt;    &amp;lt;ref local="crowdUserDetailsService" /&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;/property&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;/bean&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;  &amp;lt;!-- Crowd UserDetailsService --&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;bean id="crowdUserDetailsService" class="com.atlassian.crowd.integration.springsecurity.user.CrowdUserDetailsServiceImpl"&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;property name="authenticationManager" ref="crowdAuthenticationManager" /&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;property name="groupMembershipManager" ref="crowdGroupMembershipManager" /&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;property name="userManager" ref="crowdUserManager" /&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;property name="authorityPrefix" value="ROLE_" /&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;/bean&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;  &amp;lt;!-- NTLM Filter --&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;bean id="ntlmFilter" class="org.springframework.security.ui.ntlm.NtlmProcessingFilter"&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;sec:custom-filter position="NTLM_FILTER" /&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;property name="stripDomain" value="true" /&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;property name="defaultDomain" value="PMINTL.NET" /&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;property name="domainController" value="pmichneugc01.pmintl.net" /&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;property name="authenticationManager" ref="authenticationManager" /&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;/bean&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;bean id="ntlmEntryPoint" class="org.springframework.security.ui.ntlm.NtlmProcessingFilterEntryPoint"&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;property name="authenticationFailureUrl" value="/denied.jsp" /&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;/bean&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;bean id="exceptionTranslationFilter" class="org.springframework.security.ui.ExceptionTranslationFilter"&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;property name="authenticationEntryPoint" ref="ntlmEntryPoint" /&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;/bean&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;  &amp;lt;!-- HTTP configuration --&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;sec:http auto-config="true" entry-point-ref="ntlmEntryPoint" servlet-api-provision="false"&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;sec:intercept-url pattern="/secure.jsp" access="ROLE_myapp-users" /&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;sec:intercept-url pattern="/admin.jsp" access="ROLE_myapp-administrators" /&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;sec:intercept-url pattern="/**" filters="none" /&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;/sec:http&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;/beans&amp;gt;&lt;/textarea&gt;&lt;br /&gt;Then add it in your web application descriptor (web.xml) with the spring security filter, you must end with something like this :&lt;br /&gt;&lt;span style="font-family: monospace; font-size: small;"&gt;&lt;span style="font-size: 13px; white-space: pre-wrap;"&gt;&lt;textarea class="xml:collapse" name="code"&gt;&amp;lt;!DOCTYPE web-app PUBLIC&amp;lt;br /&amp;gt;  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"&amp;lt;br /&amp;gt;  "http://java.sun.com/dtd/web-app_2_3.dtd" &amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt; &amp;lt;web-app&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;display-name&amp;gt;Archetype Created Web Application&amp;lt;/display-name&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;  &amp;lt;context-param&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;param-value&amp;gt;&amp;lt;br /&amp;gt;    /WEB-INF/applicationContext-CrowdClient.xml,&amp;lt;br /&amp;gt;    /WEB-INF/applicationContext-security.xml&amp;lt;br /&amp;gt;     &amp;lt;/param-value&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;/context-param&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;  &amp;lt;filter&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;filter-name&amp;gt;springSecurityFilterChain&amp;lt;/filter-name&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;filter-class&amp;gt;org.springframework.web.filter.DelegatingFilterProxy&amp;lt;/filter-class&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;  &amp;lt;/filter&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;filter-mapping&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;filter-name&amp;gt;springSecurityFilterChain&amp;lt;/filter-name&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;/filter-mapping&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;  &amp;lt;listener&amp;gt;&amp;lt;br /&amp;gt;   &amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;/listener&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;/web-app&amp;gt;&lt;/textarea&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;And finally, create the custom UserDetailsAuthenticationProvider (unfortunally I was suprised to didn't find a provider that suit my needs...):&lt;br /&gt;&lt;textarea class="java:collapse" name="code"&gt;package com.mycompany.security;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt; import org.springframework.dao.DataAccessException;&amp;lt;br /&amp;gt; import org.springframework.security.AuthenticationException;&amp;lt;br /&amp;gt; import org.springframework.security.AuthenticationServiceException;&amp;lt;br /&amp;gt; import org.springframework.security.providers.UsernamePasswordAuthenticationToken;&amp;lt;br /&amp;gt; import org.springframework.security.providers.dao.AbstractUserDetailsAuthenticationProvider;&amp;lt;br /&amp;gt; import org.springframework.security.userdetails.UserDetails;&amp;lt;br /&amp;gt; import org.springframework.security.userdetails.UserDetailsService;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt; public class UserDetailsAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;     private UserDetailsService userDetailsService;&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;     @Override&amp;lt;br /&amp;gt;     protected void additionalAuthenticationChecks(final UserDetails userDetails, final UsernamePasswordAuthenticationToken authentication)&amp;lt;br /&amp;gt;             throws AuthenticationException {&amp;lt;br /&amp;gt;         // TODO Auto-generated method stub&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;     }&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;     public UserDetailsService getUserDetailsService() {&amp;lt;br /&amp;gt;         return userDetailsService;&amp;lt;br /&amp;gt;     }&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;     @Override&amp;lt;br /&amp;gt;     protected UserDetails retrieveUser(final String username, final UsernamePasswordAuthenticationToken authentication)&amp;lt;br /&amp;gt;             throws AuthenticationException {&amp;lt;br /&amp;gt;         UserDetails loadedUser;&amp;lt;br /&amp;gt;         try {&amp;lt;br /&amp;gt;             loadedUser = this.getUserDetailsService().loadUserByUsername(username);&amp;lt;br /&amp;gt;         } catch (final DataAccessException repositoryProblem) {&amp;lt;br /&amp;gt;             throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);&amp;lt;br /&amp;gt;         }&amp;lt;br /&amp;gt;         if (loadedUser == null)&amp;lt;br /&amp;gt;             throw new AuthenticationServiceException("User cannot be null");&amp;lt;br /&amp;gt;         return loadedUser;&amp;lt;br /&amp;gt;     }&amp;lt;br /&amp;gt; &amp;lt;br /&amp;gt;     public void setUserDetailsService(final UserDetailsService userDetailsService) {&amp;lt;br /&amp;gt;         this.userDetailsService = userDetailsService;&amp;lt;br /&amp;gt;     }&amp;lt;br /&amp;gt; }&lt;/textarea&gt;&lt;br /&gt;You're done !&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Creating test pages&lt;/span&gt;&lt;br /&gt;As you may have notified, the file applicationContext-security.xml defining three different level of security:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Anonymous access authorized by default to all page&lt;br /&gt;&lt;textarea class="xml" name="code"&gt;&amp;lt;sec:intercept-url pattern="/**" filters="none" /&amp;gt;&lt;/textarea&gt;&lt;/li&gt;&lt;li&gt;Standard users can access the 'secure.jsp' page&lt;br /&gt;&lt;textarea class="xml" name="code"&gt;&amp;lt;sec:intercept-url pattern="/secure.jsp" access="ROLE_myapp-users" /&amp;gt;&lt;/textarea&gt;&lt;/li&gt;&lt;li&gt;Administrators can access the 'admin.jsp' page&lt;br /&gt;&lt;textarea class="xml" name="code"&gt;&amp;lt;sec:intercept-url pattern="/admin.jsp" access="ROLE_myapp-administrators" /&amp;gt;&lt;/textarea&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;So create the pages index.jsp, secure.jsp and admin.jsp with the content you want or change the security context to suit your needs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Crowd configuration&lt;/span&gt;&lt;br /&gt;Open the&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Crowd_%28software%29"&gt;Crowd&lt;/a&gt;&amp;nbsp;administrator console, and create user corresponding to your Active Directory account name, add it to the application you created when you integrated&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Crowd_%28software%29"&gt;Crowd&lt;/a&gt;&amp;nbsp;(&lt;a href="http://confluence.atlassian.com/display/CROWD/Integrating+Crowd+with+Spring+Security"&gt;more informations&lt;/a&gt;).&lt;br /&gt;Create two groups (myapp-user and myapp-administrators, you can name it differently but you must then update your spring security context correspondingly) and add them to the user created before.&lt;br /&gt;Don't hesitate to read the&amp;nbsp;&lt;a href="http://confluence.atlassian.com/display/CROWD/Integrating+Crowd+with+Spring+Security"&gt;Crowd documentation&lt;/a&gt;&amp;nbsp;for further information. Specially if you want add a connector for your directory, but I strongly recommend you to first test your application using a&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Crowd_%28software%29"&gt;Crowd&lt;/a&gt;&amp;nbsp;integrated directory.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;Integrating spring-security into an existing web-application is relatively straight-forward, specially if you already using spring. Some specific configuration is needed to enable&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/NTLM"&gt;NTLM&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Crowd_%28software%29"&gt;Crowd&lt;/a&gt;&amp;nbsp;support but documentation can be easily find online.&lt;br /&gt;And best of all, if you want to change for &lt;a href="http://en.wikipedia.org/wiki/Kerberos_%28protocol%29"&gt;Kerberos&lt;/a&gt; in future you can do it simply and without changing the way your application works... thanks to Spring IoC :-D&lt;br /&gt;And thanks to&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Crowd_%28software%29"&gt;Crowd&lt;/a&gt;&amp;nbsp;you can change connection to different directory services without loosing user authorizations (of course user-name must be the same...).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;References&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.mediasoft.be/ntlm-with-spring-security-20/"&gt;http://blog.mediasoft.be/ntlm-with-spring-security-20/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.anorakgirl.co.uk/?p=68"&gt;http://blog.anorakgirl.co.uk/?p=68&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://confluence.atlassian.com/display/CROWD/Integrating+Crowd+with+Spring+Security"&gt;http://confluence.atlassian.com/display/CROWD/Integrating+Crowd+with+Spring+Security&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://static.springsource.org/spring-security/site/start-here.html"&gt;http://static.springsource.org/spring-security/site/start-here.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://confluence.atlassian.com/display/CROWD/Crowd+Documentation"&gt;http://confluence.atlassian.com/display/CROWD/Crowd+Documentation&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4889069596572374242-2726997190013416895?l=aloiscochard.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aloiscochard.blogspot.com/feeds/2726997190013416895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://aloiscochard.blogspot.com/2009/12/integrating-spring-security-with-ntlm_19.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/2726997190013416895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4889069596572374242/posts/default/2726997190013416895'/><link rel='alternate' type='text/html' href='http://aloiscochard.blogspot.com/2009/12/integrating-spring-security-with-ntlm_19.html' title='Integrating Spring Security with NTLM + Crowd'/><author><name>Alois Cochard</name><uri>http://www.blogger.com/profile/00906716915320183913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_t94Ly78JPSg/S6aEt2puBXI/AAAAAAAAAIc/JRSP4keuHgU/S220/avatar-popey-bw-transparent.png'/></author><thr:total>0</thr:total></entry></feed>
