<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>Gridshore software engineering weblog - acegi</title>
    <link>http://www.gridshore.nl/blog/</link>
    <description>This weblog is about everything that has to do with software engineering. It will focus on items like Springframework, acegi, hibernate and other tools to help creating good software</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.2.1 - http://www.s9y.org/</generator>
    <pubDate>Tue, 29 Jan 2008 10:27:03 GMT</pubDate>

    <image>
        <url>http://www.gridshore.nl/blog/templates/gridshore/img/s9y_banner_small.png</url>
        <title>RSS: Gridshore software engineering weblog - acegi - This weblog is about everything that has to do with software engineering. It will focus on items like Springframework, acegi, hibernate and other tools to help creating good software</title>
        <link>http://www.gridshore.nl/blog/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Last entry ...</title>
    <link>http://www.gridshore.nl/blog/index.php?/archives/74-Last-entry-....html</link>
            <category>acegi</category>
            <category>ajax</category>
            <category>Announcements</category>
            <category>Books</category>
            <category>gridshore</category>
            <category>Java</category>
            <category>News</category>
            <category>spring-osgi</category>
            <category>Springframework</category>
            <category>Technology</category>
            <category>Webservices</category>
            <category>Websites&amp;products</category>
    
    <comments>http://www.gridshore.nl/blog/index.php?/archives/74-Last-entry-....html#comments</comments>
    <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=74</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=2.0&amp;type=comments&amp;cid=74</wfw:commentRss>
    

    <author>nospam@example.com (Jettro Coenradie)</author>
    <content:encoded>
    Welcome to the last entry of this blog. No I am not quitting, I am just moving. I just installed a new blog software framework. I was starting to dislike the way to interact and I wanted something that contained more out of the box. I am in the middle of moving to wordpress software. There is a very good reason to do this. I had found a great tool on the mac called MarsEdit. And again this could not be used with serendipity. I hope I did make a good choice. Since there is a lot of information in the old blog, I did not take this blog offline. It will stay to exist, but I will not make changes there anymore.&lt;br /&gt;
&lt;br /&gt;
I hope to see you at the new version of the blog (check the page at http://www.gridshore.nl). You can attach you feedreader to the following url: feed://www.gridshore.nl/feed/ 
    </content:encoded>

    <pubDate>Sat, 19 Jan 2008 20:58:56 +0100</pubDate>
    <guid isPermaLink="false">http://www.gridshore.nl/blog/index.php?/archives/74-guid.html</guid>
    
</item>
<item>
    <title>Creating a maven archetype for acegi and springframework</title>
    <link>http://www.gridshore.nl/blog/index.php?/archives/55-Creating-a-maven-archetype-for-acegi-and-springframework.html</link>
            <category>acegi</category>
            <category>Springframework</category>
    
    <comments>http://www.gridshore.nl/blog/index.php?/archives/55-Creating-a-maven-archetype-for-acegi-and-springframework.html#comments</comments>
    <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=55</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=2.0&amp;type=comments&amp;cid=55</wfw:commentRss>
    

    <author>nospam@example.com (Jettro Coenradie)</author>
    <content:encoded>
    I have created a lot of small applications that include spring and acegi. Most of the time I copy most of the resources from another project. Some time ago I learned about the maven archetypes. An easy way to create the project structure. That was the time I decided that I wanted to have my acegi springframework archetype. Last weeks I found some time to create this archetype. You can download the files here:&lt;br /&gt;
&lt;a href=&quot;http://code.google.com/p/gridshore/&quot;  title=&quot;http://code.google.com/p/gridshore/&quot;&gt;http://code.google.com/p/gridshore/&lt;/a&gt;&lt;br /&gt;
And the generated maven site here:&lt;br /&gt;
&lt;a href=&quot;http://www.gridshore.nl/projects/springframeworkarchetype/index.html&quot;  title=&quot;http://www.gridshore.nl/projects/springframeworkarchetype/index.html&quot;&gt;http://www.gridshore.nl/projects/springframeworkarchetype/index.html&lt;/a&gt;&lt;br /&gt;
Ofcourse there is also a maven website about creating an archetype, this is not a very extensive website. In this blog item I will explain more about the archetype I created.&lt;br /&gt;
&lt;br /&gt;
First thing to know, well surprise, the archetype is just a maven project. You can start you new archetype by using a &lt;a href=&quot;http://maven.apache.org/plugins/maven-archetype-plugin/create-mojo.html&quot;  title=&quot;http://maven.apache.org/plugins/maven-archetype-plugin/create-mojo.html&quot;&gt;maven archetype&lt;/a&gt;:&lt;br /&gt;
mvn archetype:create &lt;br /&gt;
	-DgroupId=nl.gridshore.samples.archetype &lt;br /&gt;
	-DartifactId=SpringframeworkArchetype &lt;br /&gt;
	-DarchetypeArtifactId=maven-archetype-quickstart&lt;br /&gt;
Have a look at the pom for the other properties; scm, distributionManagement, etc.&lt;br /&gt;
&lt;br /&gt;
The project itself contains an src\main\resources\META-INF\maven\archetype.xml file that defines all the resources that need to be copied.&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
&amp;lt;archetype&gt;&lt;br /&gt;
  &amp;lt;id&gt;SpringframeworkArchetype&amp;lt;/id&gt;&lt;br /&gt;
  &amp;lt;sources&gt;&lt;br /&gt;
    &amp;lt;source&gt;src/main/java/App.java&amp;lt;/source&gt;&lt;br /&gt;
  &amp;lt;/sources&gt;&lt;br /&gt;
  &amp;lt;testSources&gt;&lt;br /&gt;
    &amp;lt;source&gt;src/test/java/AppTest.java&amp;lt;/source&gt;&lt;br /&gt;
  &amp;lt;/testSources&gt;&lt;br /&gt;
  &amp;lt;resources&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/webapp/index.jsp&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/webapp/WEB-INF/web.xml&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/webapp/WEB-INF/action-servlet.xml&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/webapp/WEB-INF/jsps/welcome.jsp&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/webapp/WEB-INF/jsps/adminwelcome.jsp&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/webapp/WEB-INF/jsps/accessdenied.jsp&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/webapp/WEB-INF/jsps/login.jsp&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/webapp/WEB-INF/jsps/loginerror.jsp&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/resources/security-springConfig.xml&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/resources/views.properties&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/resources/errormessages.properties&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/resources/sitetext.properties&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/resources/log4j.dtd&amp;lt;/resource&gt;&lt;br /&gt;
      &amp;lt;resource&gt;src/main/resources/log4j.xml&amp;lt;/resource&gt;&lt;br /&gt;
  &amp;lt;/resources&gt;&lt;br /&gt;
&amp;lt;/archetype&gt;&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
The structure is pretty easy, you can find all the resources under the directory:&lt;br /&gt;
src\main\resources\archetype-resources&lt;br /&gt;
&lt;br /&gt;
You can use the following parameters in your file as placeholders:&lt;br /&gt;
&lt;a href=&quot;http://maven.apache.org/plugins/maven-archetype-plugin/create-mojo.html&quot;  title=&quot;http://maven.apache.org/plugins/maven-archetype-plugin/create-mojo.html&quot;&gt;http://maven.apache.org/plugins/maven-archetype-plugin/create-mojo.html&lt;/a&gt;. Have a look at the src\main\resources\archetype-resources\pom.xml for an example:&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
  &amp;lt;groupId&gt;$groupId&amp;lt;/groupId&gt;&lt;br /&gt;
  &amp;lt;artifactId&gt;$artifactId&amp;lt;/artifactId&gt;&lt;br /&gt;
  &amp;lt;version&gt;$version&amp;lt;/version&gt;&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Hope that helps you on your way to your own archetype. If you just want to use mine:&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
mvn install&lt;br /&gt;
mvn archetype:create&lt;br /&gt;
	-DgroupId=your.groupid&lt;br /&gt;
	-DartifactId=your.artifactId&lt;br /&gt;
	-DarchetypeArtifactId=SpringframeworkArchetype&lt;br /&gt;
	-DarchetypeGroupId=nl.gridshore.samples.archetype&lt;br /&gt;
	-DarchetypeVersion=1.0.0-SNAPSHOT&lt;br /&gt;
&lt;/pre&gt; 
    </content:encoded>

    <pubDate>Thu, 31 Aug 2006 20:51:15 +0200</pubDate>
    <guid isPermaLink="false">http://www.gridshore.nl/blog/index.php?/archives/55-guid.html</guid>
    
</item>
<item>
    <title>Updated the sample to acegi version 1.0.0 RC1</title>
    <link>http://www.gridshore.nl/blog/index.php?/archives/39-Updated-the-sample-to-acegi-version-1.0.0-RC1.html</link>
            <category>acegi</category>
    
    <comments>http://www.gridshore.nl/blog/index.php?/archives/39-Updated-the-sample-to-acegi-version-1.0.0-RC1.html#comments</comments>
    <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=39</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=2.0&amp;type=comments&amp;cid=39</wfw:commentRss>
    

    <author>nospam@example.com (Jettro Coenradie)</author>
    <content:encoded>
    Today I upgraded the acegi library to version 1.0.0 RC1. It was a quick process, but you do need to make a few changes. The complete package structure is changed, JdbcDaoImpl class has been moved and some other changes as well. Have a look at the release notes in the downloaded acegi package. There was a nice addentum on the spring forum that you need to change the inclusion of the taglibrary as well.&lt;br /&gt;
&lt;br /&gt;
&lt;%@ taglib uri=&quot;http://acegisecurity.org/authz&quot; prefix=&quot;authz&quot; %&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Have fun, I will start documening the sample within a few weeks now.&lt;br /&gt;
&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Mon, 05 Dec 2005 20:28:59 +0100</pubDate>
    <guid isPermaLink="false">http://www.gridshore.nl/blog/index.php?/archives/39-guid.html</guid>
    
</item>
<item>
    <title>problems while upgrading sample from acegi 0.8.3 to 0.9.0</title>
    <link>http://www.gridshore.nl/blog/index.php?/archives/35-problems-while-upgrading-sample-from-acegi-0.8.3-to-0.9.0.html</link>
            <category>acegi</category>
            <category>Technology</category>
    
    <comments>http://www.gridshore.nl/blog/index.php?/archives/35-problems-while-upgrading-sample-from-acegi-0.8.3-to-0.9.0.html#comments</comments>
    <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=35</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=2.0&amp;type=comments&amp;cid=35</wfw:commentRss>
    

    <author>nospam@example.com (Jettro Coenradie)</author>
    <content:encoded>
    Today I did an upgrade of acegi for my sample application. Ofcourse there are a lot of resources about upgrading. There is an entry on the homepage of &lt;a href=&quot;http://acegisecurity.sf.net&quot;  title=&quot;acegi&quot;&gt;acegi&lt;/a&gt; and the blog from &lt;a href=&quot;http://jroller.com/page/raible?entry=how_to_upgrade_from_acegi&quot;  title=&quot;Matt Raible ~ upgrading acegi&quot;&gt;Matt Raible&lt;/a&gt;. These are my findings.&lt;br /&gt;
&lt;br /&gt;
I have a CustomJdbcDaoImpl class, I used to obtain the granted authorities with the following lines of code:&lt;br /&gt;
&lt;br /&gt;
PersonDetails person = (PersonDetails) users.get(0);&lt;br /&gt;
List dbAuths = getAuthoritiesByUsernameMapping().execute(person.getUsername());&lt;br /&gt;
if (dbAuths.size() == 0) {&lt;br /&gt;
&amp;#160;   throw new UsernameNotFoundException(&quot;User has no GrantedAuthority&quot;);&lt;br /&gt;
}&lt;br /&gt;
GrantedAuthority[] arrayAuths = {};&lt;br /&gt;
addCustomAuthorities(person.getUsername(), dbAuths);&lt;br /&gt;
&lt;br /&gt;
There is however a problem with the method &#039; getAuthoritiesByUsernameMapping()&#039;, this does not exist anymore in the 0.9.0 acegi version.&lt;br /&gt;
&lt;b&gt;To be continued&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The following change is getting a secure context. With the new version we use the following code to obtain a secure context:&lt;br /&gt;
SecurityContextHolder.getContext()&lt;br /&gt;
&lt;br /&gt;
There is an issue with the events as well, there are now two main events, one for authentication and one for authorization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bean id=&quot;authenticationLoggerListener&quot; class=&quot;net.sf.acegisecurity.event.authentication.LoggerListener&quot;/&gt;&lt;br /&gt;
&amp;lt;bean id=&quot;authorizationLoggerListener&quot; class=&quot;net.sf.acegisecurity.event.authorization.LoggerListener&quot;/&gt;&lt;br /&gt;
&lt;br /&gt;
I also had to change my SecurityEventListener, the names of the events are changed, the code now looks like this:&lt;br /&gt;
public void onApplicationEvent(ApplicationEvent event) {&lt;br /&gt;
&amp;#160;        if (event instanceof AuthenticationFailureBadCredentialsEvent) {&lt;br /&gt;
&amp;#160;        	AuthenticationFailureBadCredentialsEvent authEvent = (AuthenticationFailureBadCredentialsEvent) event;&lt;br /&gt;
&amp;#160;          securityManager.disablePerson(((User)authEvent.getAuthentication().getPrincipal()).getUsername());&lt;br /&gt;
&amp;#160;        }&lt;br /&gt;
&amp;#160;        if (event instanceof AuthenticationSuccessEvent) {&lt;br /&gt;
&amp;#160;        	AuthenticationSuccessEvent authEvent = (AuthenticationSuccessEvent) event;&lt;br /&gt;
&amp;#160;        securityManager.savePersonLastLoggedOn(((User)authEvent.getAuthentication().getPrincipal()).getUsername());&lt;br /&gt;
&amp;#160;        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
And finally, since my tag for authentication is now within the project I removed all the customized code for my custom taglibrary. See earliar posts if you want to know what I am talking about.&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Mon, 21 Nov 2005 22:40:11 +0100</pubDate>
    <guid isPermaLink="false">http://www.gridshore.nl/blog/index.php?/archives/35-guid.html</guid>
    
</item>
<item>
    <title>taglibrary auth in acegi 0.9</title>
    <link>http://www.gridshore.nl/blog/index.php?/archives/27-taglibrary-auth-in-acegi-0.9.html</link>
            <category>acegi</category>
    
    <comments>http://www.gridshore.nl/blog/index.php?/archives/27-taglibrary-auth-in-acegi-0.9.html#comments</comments>
    <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=27</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=2.0&amp;type=comments&amp;cid=27</wfw:commentRss>
    

    <author>nospam@example.com (Jettro Coenradie)</author>
    <content:encoded>
    I have created a taglibrary for acegi, well not really created, more extended. In an earlier post you can see what I have created. I have also created a unit test and now my source is contributed to the framework. So the 0.9 release will contain my extensions to the tag library. I think that is pretty cool.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://acegisecurity.sf.net&quot;  title=&quot;acegi security sourceforge page&quot;&gt;acegi security sourceforge page&lt;/a&gt; 
    </content:encoded>

    <pubDate>Fri, 04 Nov 2005 00:17:58 +0100</pubDate>
    <guid isPermaLink="false">http://www.gridshore.nl/blog/index.php?/archives/27-guid.html</guid>
    
</item>
<item>
    <title>Acegi authentication tag library</title>
    <link>http://www.gridshore.nl/blog/index.php?/archives/25-Acegi-authentication-tag-library.html</link>
            <category>acegi</category>
    
    <comments>http://www.gridshore.nl/blog/index.php?/archives/25-Acegi-authentication-tag-library.html#comments</comments>
    <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=25</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=2.0&amp;type=comments&amp;cid=25</wfw:commentRss>
    

    <author>nospam@example.com (Jettro Coenradie)</author>
    <content:encoded>
    I am creating a sample application with the springframework. I use Acegi or Spring security as the security framework. On this blog I have multiple items that relate to acegi. I think more will come. This one is about a tag library I created. I wanted to be able to print more details from the UserDetails object that resides in the SecureContext. There are multiple ways to realize this. The most obvious is using a scriptled.&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&amp;lt;%=((PersonDetails)((SecureContext)net.sf.acegisecurity.context.ContextHolder.getContext())&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;.getAuthentication().getPrincipal()).getFirstName()%&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
But if you want to show multiple properties this is not very nice and I like to minimize the amount of scriptlets in jsp code. Therefore I wanted to use a tag library. You can ofcourse use the standard tag library from acegi&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&amp;lt;authz:authentication operation=&quot;principal&quot;/&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
This can only show the username. But the concept is good, and ready for extending. Therefore I created an extended version of the tag library. I introduced a second property called &quot;prefix&quot; and now you can call any &quot;get*&quot; method or &quot;is*&quot; method. If you want to call other methods as well, it is very easy to change the current implementation.&lt;br /&gt;
&lt;br /&gt;
Time to have a look at some parts of the code, I present the doStartTag method:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
1.&amp;#160;public int doStartTag() throws JspException {&lt;br /&gt;
2.&amp;#160;&amp;#160;&amp;#160;if ((null == operation) || &quot;&quot;.equals(operation)) {&lt;br /&gt;
3.&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;return Tag.SKIP_BODY;&lt;br /&gt;
4.&amp;#160;&amp;#160;&amp;#160;}&lt;br /&gt;
5. &lt;br /&gt;
6.&amp;#160;&amp;#160;&amp;#160;validateArguments();&lt;br /&gt;
7.         &lt;br /&gt;
8.&amp;#160;&amp;#160;&amp;#160;if ((ContextHolder.getContext() == null)&lt;br /&gt;
9.&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;|| !(ContextHolder.getContext() instanceof SecureContext)&lt;br /&gt;
10.&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;|| (((SecureContext) ContextHolder.getContext()).getAuthentication() == null)) {&lt;br /&gt;
11.&amp;#160;&amp;#160;&amp;#160;&amp;#160;return Tag.SKIP_BODY;&lt;br /&gt;
12.&amp;#160;&amp;#160;}&lt;br /&gt;
13.&lt;br /&gt;
14.&amp;#160;&amp;#160;Authentication auth = ((SecureContext) ContextHolder.getContext()).getAuthentication();&lt;br /&gt;
15.&lt;br /&gt;
16.&amp;#160;&amp;#160;if (auth.getPrincipal() == null) {&lt;br /&gt;
17.&amp;#160;&amp;#160;&amp;#160;&amp;#160;return Tag.SKIP_BODY;&lt;br /&gt;
18.&amp;#160;&amp;#160;} else if (auth.getPrincipal() instanceof UserDetails) {&lt;br /&gt;
19.&amp;#160;&amp;#160;&amp;#160;&amp;#160;writeMessage(invokeOperation(auth.getPrincipal()));&lt;br /&gt;
20.&lt;br /&gt;
21.&amp;#160;&amp;#160;&amp;#160;&amp;#160;return Tag.SKIP_BODY;&lt;br /&gt;
22.&amp;#160;&amp;#160;} else {&lt;br /&gt;
23.&amp;#160;&amp;#160;&amp;#160;&amp;#160;writeMessage(auth.getPrincipal().toString());&lt;br /&gt;
24.&lt;br /&gt;
25.&amp;#160;&amp;#160;&amp;#160;&amp;#160;return Tag.SKIP_BODY;&lt;br /&gt;
26.&amp;#160;&amp;#160;}&lt;br /&gt;
27.}&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Lines 1-12 are validation code, just trying your tag not to throw an unexpected exception. Line 14 obtains the Authentication object from the SecureContext. This object contains the principal which we are after. If the Principal is of type UserDetails (the interface your custom implementation should implement), we call the invokeOperation method.&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
1.&amp;#160;private String invokeOperation(Object obj) throws JspException {    	&lt;br /&gt;
2.&amp;#160;&amp;#160;&amp;#160;Class clazz = obj.getClass();&lt;br /&gt;
3.&amp;#160;&amp;#160;&amp;#160;String methodToInvoke = getOperation();&lt;br /&gt;
4.&amp;#160;&amp;#160;&amp;#160;StringBuffer methodName = new StringBuffer();&lt;br /&gt;
5.&amp;#160;&amp;#160;&amp;#160;methodName.append(getMethodPrefix());&lt;br /&gt;
6.&amp;#160;&amp;#160;&amp;#160;methodName.append(methodToInvoke.substring(0,1).toUpperCase());&lt;br /&gt;
7.&amp;#160;&amp;#160;&amp;#160;methodName.append(methodToInvoke.substring(1));&lt;br /&gt;
8.&amp;#160;    	&lt;br /&gt;
9.&amp;#160;&amp;#160;&amp;#160;Method method = null;&lt;br /&gt;
10.&amp;#160;&amp;#160;try {&lt;br /&gt;
11.&amp;#160;&amp;#160;&amp;#160;&amp;#160;method = clazz.getDeclaredMethod(methodName.toString(),null);&lt;br /&gt;
12.&amp;#160;&amp;#160;} catch (SecurityException se) {&lt;br /&gt;
13.&amp;#160;&amp;#160;&amp;#160;&amp;#160;throw new JspException(se);&lt;br /&gt;
14.&amp;#160;&amp;#160;} catch (NoSuchMethodException nsme) {&lt;br /&gt;
15.&amp;#160;&amp;#160;&amp;#160;&amp;#160;throw new JspException(nsme);&lt;br /&gt;
16.&amp;#160;&amp;#160;}&lt;br /&gt;
17.&amp;#160;&amp;#160;Object retVal =null;&lt;br /&gt;
18.    	&lt;br /&gt;
19.&amp;#160;&amp;#160;try {&lt;br /&gt;
20.&amp;#160;&amp;#160;&amp;#160;&amp;#160;retVal = method.invoke(obj,null);&lt;br /&gt;
21.&amp;#160;&amp;#160;} catch (IllegalArgumentException iae) {&lt;br /&gt;
22.&amp;#160;&amp;#160;&amp;#160;&amp;#160;throw new JspException(iae);&lt;br /&gt;
23.&amp;#160;&amp;#160;} catch (IllegalAccessException iae) {&lt;br /&gt;
24.&amp;#160;&amp;#160;&amp;#160;&amp;#160;throw new JspException(iae);&lt;br /&gt;
25.&amp;#160;&amp;#160;} catch (InvocationTargetException ite) {&lt;br /&gt;
26.&amp;#160;&amp;#160;&amp;#160;&amp;#160;throw new JspException(ite);&lt;br /&gt;
27.&amp;#160;&amp;#160;}&lt;br /&gt;
28.&amp;#160;&amp;#160;if (retVal == null) {&lt;br /&gt;
29.&amp;#160;&amp;#160;&amp;#160;&amp;#160;retVal = &quot;&quot;;&lt;br /&gt;
30.&amp;#160;&amp;#160;}&lt;br /&gt;
31.&amp;#160;&amp;#160;return retVal.toString();&lt;br /&gt;
32.}&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
lines 3-7 create the name of the method to call&lt;br /&gt;
lines 9 -16 create the Method instance to be invoked&lt;br /&gt;
lines 19-27 do the real invocation of the method.&lt;br /&gt;
&lt;br /&gt;
As you can see it is faily easy to create the extende taglib by using reflection to call the right methods on the UserDetails implementation. I have used this file and the tld file in my &lt;a href=&quot;http://www.javaforge.com/proj/summary.do?proj_id=71&quot;&gt;sample&lt;/a&gt; that can be found on &lt;a href=&quot;http://www.javaforge.com&quot;&gt;javaforge&lt;/a&gt;. You can also have a look at the files from this website, but then there is no working sample.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.gridshore.nl/blog/uploads/AuthenticationTag.java&quot; title=&quot;AuthenticationTag.java&quot; target=&quot;_blank&quot;&gt;AuthenticationTag.java&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.gridshore.nl/blog/uploads/CustomAuthenticationTag.tld&quot; title=&quot;CustomAuthenticationTag.tld&quot; target=&quot;_blank&quot;&gt;CustomAuthenticationTag.tld&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://acegisecurity.sourceforge.net/&quot;&gt;Acegi security&lt;/a&gt; 
    </content:encoded>

    <pubDate>Wed, 26 Oct 2005 20:49:05 +0200</pubDate>
    <guid isPermaLink="false">http://www.gridshore.nl/blog/index.php?/archives/25-guid.html</guid>
    
</item>
<item>
    <title>Springframework Acegi principal customization and events</title>
    <link>http://www.gridshore.nl/blog/index.php?/archives/3-Springframework-Acegi-principal-customization-and-events.html</link>
            <category>acegi</category>
    
    <comments>http://www.gridshore.nl/blog/index.php?/archives/3-Springframework-Acegi-principal-customization-and-events.html#comments</comments>
    <wfw:comment>http://www.gridshore.nl/blog/wfwcomment.php?cid=3</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://www.gridshore.nl/blog/rss.php?version=2.0&amp;type=comments&amp;cid=3</wfw:commentRss>
    

    <author>nospam@example.com (Jettro Coenradie)</author>
    <content:encoded>
    Acegi is the security component for springframework. Since Acegi works with interfaces, extending the framework is easy. There are some good abstract classes you can extend as well. Todays blog deals with customizing the UserDetails class. This is an interface with the following methods:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
public interface UserDetails {&lt;br /&gt;
&amp;#160;&amp;#160;public boolean isAccountNonExpired();&lt;br /&gt;
&amp;#160;&amp;#160;public boolean isAccountNonLocked();&lt;br /&gt;
&amp;#160;&amp;#160;public GrantedAuthority[] getAuthorities();&lt;br /&gt;
&amp;#160;&amp;#160;public boolean isCredentialsNonExpired();&lt;br /&gt;
&amp;#160;&amp;#160;public boolean isEnabled();&lt;br /&gt;
&amp;#160;&amp;#160;public String getPassword();&lt;br /&gt;
&amp;#160;&amp;#160;public String getUsername();&lt;br /&gt;
}&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
If you want a custom UserDetails implementation you need to implement this interface. I added two methods to the implementation:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&amp;#160;&amp;#160;public String getFullname();&lt;br /&gt;
&amp;#160;&amp;#160;public Date getLastLoggedIn();&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
I take it the names of the methods are self documenting. What other components do we need? We need a custom jdbcDaoImpl that has a mapper to map the query to the PersonDetails object. We also have to change the configuration of this custom component so that the custom properties are also loaded. Lets have a look at the xml part of the configuration first. Pay special attention to the queries.&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&amp;lt;bean id=&quot;jdbcDaoImpl&quot; class=&quot;org.appfuse.security.CustomJdbcDaoImpl&quot;&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;lt;property name=&quot;dataSource&quot;&gt;&amp;lt;ref bean=&quot;dataSource&quot;/&gt;&amp;lt;/property&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;lt;property name=&quot;usersByUsernameQuery&quot;&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;lt;value&gt;&lt;b&gt;select username,password,fullname,last_logged_in,enabled from person where username=?&lt;/b&gt;&amp;lt;/value&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;lt;/property&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;lt;property name=&quot;authoritiesByUsernameQuery&quot;&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;lt;value&gt;&lt;b&gt;select p.username,r.name as rolename from person p, role r, authority a where a.person_id = p.id AND a.role_id = r.id AND p.username=?&lt;/b&gt;&amp;lt;/value&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;lt;/property&gt;&lt;br /&gt;
&amp;lt;/bean&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Now we implement the CustomJdbcDaoImpl class. This class is a subclass of the JdbcDaoImpl class. We override the loadByUsername method. An innerclass is created as a mapper between the sql statement and the PersonDetails object.&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
public class CustomJdbcDaoImpl extends JdbcDaoImpl {&lt;br /&gt;
&amp;#160;&amp;#160;public UserDetails loadUserByUsername(String username)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;throws UsernameNotFoundException, DataAccessException {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;List users = (new PersonsByUsernameMapping(getDataSource())).execute(username);&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;if (users.size() == 0) {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;throw new UsernameNotFoundException(&quot;User not found&quot;);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;PersonDetails person = (PersonDetails) users.get(0);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;List dbAuths = getAuthoritiesByUsernameMapping().execute(person.getUsername());&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;if (dbAuths.size() == 0) {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;throw new UsernameNotFoundException(&quot;User has no GrantedAuthority&quot;);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;GrantedAuthority[] arrayAuths = {};&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;addCustomAuthorities(person.getUsername(), dbAuths);&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;arrayAuths = (GrantedAuthority[]) dbAuths.toArray(arrayAuths);&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;return new PersonDetails(person.getUsername(), person.getFullname(),&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;person.getPassword(),person.getLastLoggedIn(),person.isEnabled(),&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;true, true, true,arrayAuths);&lt;br /&gt;
&amp;#160;&amp;#160;}&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;protected class PersonsByUsernameMapping extends MappingSqlQuery {&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;protected PersonsByUsernameMapping(DataSource ds) {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;super(ds, getUsersByUsernameQuery());&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;declareParameter(new SqlParameter(Types.VARCHAR));&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;compile();&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;protected Object mapRow(ResultSet rs, int rowNum) throws SQLException {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;String username = rs.getString(1);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;String password = rs.getString(2);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;String fullname = rs.getString(3);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;Date lastLoggedIn = rs.getDate(4);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;boolean enabled = rs.getBoolean(5);&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;PersonDetails person = new PersonDetails(&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;username, fullname, password, lastLoggedIn, enabled, true, true, true,&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;new GrantedAuthority[] { new GrantedAuthorityImpl(&quot;HOLDER&quot;) });&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;return person;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br /&gt;
&amp;#160;&amp;#160;}&lt;br /&gt;
}&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Actually this is all there is to it. But why all this trouble? We added two properties, the fullname and LastLoggedIn. Fullname is a value the user enters when he registers for the website. We want to show this property on the page to see who is logged on. What about the second property? We want to show what the last time was that a used logged in to the application. Showing the data is not that hard, but how can we plugin to the acegi framework to get information about who logged in when. The answer is [b]events[/b].&lt;br /&gt;
&lt;br /&gt;
Spring uses a very simple event mechanism that is used by acegi to provide you with information. You need to create a bean that implements the ApplicationListener interface, then simply configure the bean in the spring config file.&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;lt;bean id=&quot;wrongPasswordListener&quot; class=&quot;org.appfuse.security.AuthenticationFailurePasswordEventListener&quot;&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;lt;property name=&quot;personManager&quot; ref=&quot;personManager&quot;/&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;lt;/bean&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
The code for the bean looks like this:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&amp;#160;&amp;#160;public void onApplicationEvent(ApplicationEvent event) {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;if (event instanceof AuthenticationFailurePasswordEvent) {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;AuthenticationFailurePasswordEvent authEvent = (AuthenticationFailurePasswordEvent) event;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;personManager.disablePerson(authEvent.getUser().getUsername());&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;if (event instanceof AuthenticationSuccessEvent) {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;AuthenticationSuccessEvent authEvent = (AuthenticationSuccessEvent) event;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;personManager.saveLoggedOnPerson(authEvent.getUser().getUsername());&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br /&gt;
&amp;#160;&amp;#160;}&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
So we respond to two types of events, one that is raised in case of entering a wrong password, the other if a user successfully logged on. With these events we can lock an account if a user enters a wrong password more then three times and we can store the lastLoggedIn time if a user successfully logges in.&lt;br /&gt;
&lt;br /&gt;
The last part is showing the fullname and the lastloggedin property in the jsp page.&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&amp;lt;fmt:message key=&quot;general.welcome&quot;&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;lt;fmt:param&gt;&amp;lt;%=((PersonDetails) ((SecureContext)ContextHolder.getContext()).getAuthentication().getPrincipal()).getFullname()%&gt;&amp;lt;/fmt:param&gt;&lt;br /&gt;
&amp;lt;/fmt:message&gt;&lt;br /&gt;
&amp;lt;fmt:message key=&quot;general.lastlogin&quot;&gt;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;lt;fmt:param&gt;&amp;lt;fmt:formatDate pattern=&quot;dd/MM/yyyy&quot; value=&quot;&amp;lt;%=((PersonDetails) ((SecureContext)ContextHolder.getContext()).getAuthentication().getPrincipal()).getLastLoggedIn()%&gt;&quot;/&gt;&amp;lt;/fmt:param&gt;&lt;br /&gt;
&amp;lt;/fmt:message--%&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
Hope this can help you if you want to create your own custom authentication principal. If you want to have a look at the complete code, have a look at the javaforge project I created.&lt;br /&gt;
&lt;a href=&quot;http://javaforge.com/proj/forum.do?proj_id=71&quot;&gt;http://javaforge.com/proj/forum.do?proj_id=71&lt;/a&gt;&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Fri, 07 Oct 2005 20:41:00 +0200</pubDate>
    <guid isPermaLink="false">http://www.gridshore.nl/blog/index.php?/archives/3-guid.html</guid>
    
</item>

</channel>
</rss>