directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r908158 - in /websites/staging/directory/trunk/content: ./ apacheds/advanced-ug/6-implementing-interceptor.html
Date Tue, 06 May 2014 07:00:41 GMT
Author: buildbot
Date: Tue May  6 07:00:41 2014
New Revision: 908158

Log:
Staging update by buildbot for directory

Added:
    websites/staging/directory/trunk/content/apacheds/advanced-ug/6-implementing-interceptor.html
Modified:
    websites/staging/directory/trunk/content/   (props changed)

Propchange: websites/staging/directory/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Tue May  6 07:00:41 2014
@@ -1 +1 @@
-1592442
+1592668

Added: websites/staging/directory/trunk/content/apacheds/advanced-ug/6-implementing-interceptor.html
==============================================================================
--- websites/staging/directory/trunk/content/apacheds/advanced-ug/6-implementing-interceptor.html (added)
+++ websites/staging/directory/trunk/content/apacheds/advanced-ug/6-implementing-interceptor.html Tue May  6 07:00:41 2014
@@ -0,0 +1,438 @@
+<!DOCTYPE html>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<html>
+	<head>
+		<title>6 - Implementing a simple custom Interceptor for ApacheDS &mdash; Apache Directory</title>
+		
+        <link href="./../../css/common.css" rel="stylesheet" type="text/css">
+    	<link href="./../../css/green.css" rel="stylesheet" type="text/css">
+    
+        
+        <link rel="shortcut icon" href="./../../images/server-icon_16x16.png">
+    
+        <!-- Google Analytics -->
+        <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
+        <script type="text/javascript">
+            _uacct = "UA-1358462-1";
+            urchinTracker();
+        </script>
+	</head>
+	<body>
+	    <div id="container">
+            <div id="header">
+                <div id="subProjectsNavBar">
+                    <a href="./../../">
+                        
+                        Apache Directory Project
+                        
+                    </a>
+                    &nbsp;|&nbsp;
+                    <a href="./../../apacheds">
+                        
+                        <STRONG>ApacheDS</STRONG>
+                        
+                    </a>
+                    &nbsp;|&nbsp;
+                    <a href="./../../studio">
+                        
+                        Apache Directory Studio
+                        
+                    </a>
+                    &nbsp;|&nbsp;
+                    <a href="./../../api">
+                        
+                        Apache LDAP API
+                        
+                    </a>
+                    &nbsp;|&nbsp;
+                    <a href="./../../mavibot">
+                        
+                        Mavibot
+                        
+                    </a>
+                    &nbsp;|&nbsp;
+                    <a href="./../../escimo">
+                        
+                        eSCIMo
+                        
+                    </a>
+                </div><!-- subProjectsNavBar -->
+            </div><!-- header -->
+            <div id="content">
+                <div id="leftColumn">
+                    
+<div id="navigation">
+    
+    <h5>ApacheDS 2.0</h5>
+    <ul>
+        <li><a href="./../../apacheds/">Home</a></li>
+        <li><a href="./../../apacheds/news.html">News</a></li>
+        <li><a href="./../../apacheds/features.html">Features</a></li>
+    </ul>
+    <h5>Downloads</h5>
+    <ul>
+        <li><a href="./../../apacheds/downloads.html">ApacheDS 2.0.0-M16</a>&nbsp;&nbsp;<img src="./../../images/new_badge.gif" alt="" style="margin-bottom:-3px;" border="0"></li>
+        <li><a href="./../../apacheds/download-old-versions.html">Older versions</a></li>
+    </ul>
+    <h5>Documentation</h5>
+    <ul>
+        <li><a href="./../../apacheds/basic-user-guide.html">Basic User Guide </a></li>
+        <li><a href="./../../apacheds/advanced-user-guide.html">Advanced User Guide</a></li>
+        <li><a href="./../../apacheds/developer-guide.html">Developer Guide</a></li>
+        <li><a href="./../../apacheds/kerberos-user-guide.html">Kerberos User Guide</a></li>
+        <li><a href="./../../apacheds/configuration/ads-2.0-configuration.html">Configuration</a></li>
+        <li><a href="./../../apacheds/gen-docs/latest/apidocs">JavaDocs</a></li>
+    </ul>
+    
+    
+    <h5>Support</h5>
+    <ul>
+        <li><a href="./../../mailing-lists-and-irc.html">Mailing Lists &amp; IRC</a></li>
+        <li><a href="./../../sources.html">Sources</a></li>
+        <li><a href="./../../issue-tracking.html">Issue Tracking</a></li>
+        <li><a href="./../../commercial-support.html">Commercial Support</a></li>
+    </ul>
+    <h5>Community</h5>
+    <ul>
+        <li><a href="./../../contribute.html">How to Contribute</a></li>
+        <li><a href="./../../team.html">Team</a></li>
+        <li><a href="./../../original-project-proposal.html">Original Project Proposal</a></li>
+        <li><a href="./../../special-thanks.html" class="external-link" rel="nofollow">Special Thanks</a></li>
+    </ul>
+    <h5>About Apache</h5>
+    <ul>
+        <li><a href="http://www.apache.org/">Apache</a></li>
+        <li><a href="http://www.apache.org/licenses/">License</a></li>
+        <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
+        <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
+        <li><a href="http://www.apache.org/security/">Security</a></li>
+    </ul>
+    
+</div><!-- navigation -->
+
+                </div><!-- leftColumn -->
+                <div id="rightColumn">
+
+
+    <div class="nav">
+        <div class="nav_prev">
+        
+            <a href="5.4-replication.html">5.4 - Replication</a>
+		
+        </div>
+        <div class="nav_up">
+        
+            <a href="../advanced-user-guide.html">Advanced User Guide</a>
+		
+        </div>
+        <div class="nav_next">
+        
+			&nbsp;
+        
+        </div>
+        <div class="clearfix"></div>
+    </div>
+
+
+<h1 id="6-implementing-a-simple-custom-interceptor-for-apacheds">6 - Implementing a simple custom Interceptor for ApacheDS</h1>
+<p>This site was updated for ApacheDS 2.0.</p>
+<p>The following is for developers who plan to implement their own interceptors in order to extend or modify the functionality of Apache Directory Server. It contains a simple example as a starting point.</p>
+<h2 id="what-exactly-is-an-interceptor">What exactly is an interceptor?</h2>
+<p>An interceptor filters method calls performed on on the DefaultPartitionNexus just like Servlet filters do. The ApacheDS configuration contains a chain of filters performing several tasks. In order to illustrate this, here is the list of interceptors from the default server configuration of ApacheDS 2.0</p>
+<div class="codehilite"><pre><span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">normalization</span><span class="p">.</span><span class="n">NormalizationInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">authn</span><span class="p">.</span><span class="n">AuthenticationInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">referral</span><span class="p">.</span><span class="n">ReferralInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">authz</span><span class="p">.</span><span class="n">AciAuthorizationInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">authz</span><span class="p">.</span><span class="n">DefaultAuthorizationInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">exception</span><span class="p">.</span><span class="n">ExceptionInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">changelog</span><span class="p">.</span><span class="n">ChangeLogInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">operational</span><span class="p">.</span><span class="n">OperationalAttributeInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">schema</span><span class="p">.</span><span class="n">SchemaInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">subtree</span><span class="p">.</span><span class="n">SubentryInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">collective</span><span class="p">.</span><span class="n">CollectiveAttributeInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">event</span><span class="p">.</span><span class="n">EventInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">trigger</span><span class="p">.</span><span class="n">TriggerInterceptor</span>
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">journal</span><span class="p">.</span><span class="n">JournalInterceptor</span>
+</pre></div>
+
+
+<p>Interceptors should usually pass the control of current invocation to the next interceptor by calling an appropriate method on NextInterceptor. The flow control is returned when the next interceptor's filter method returns. You can therefore implement pre-, post-, around- invocation handler by how you place the statement.</p>
+<p>Interceptors are a powerful way to extend and modify the server behavior. But be warned. A mistakenly written interceptor may lead to a dis-functional or corrupt server.
+Password hash. A simple interceptor</p>
+<p>In order to demonstrate how to write an interceptor, here is a simple but realistic example. The following requirement should be fulfilled by an interceptor.</p>
+<div class="codehilite"><pre><span class="n">No</span> <span class="n">user</span> <span class="n">password</span> <span class="n">should</span> <span class="n">be</span> <span class="n">stored</span> <span class="n">in</span> <span class="n">the</span> <span class="n">directory</span> <span class="n">in</span> <span class="n">clear</span> <span class="n">text</span><span class="p">.</span>
+</pre></div>
+
+
+<p>To be more concrete:</p>
+<div class="codehilite"><pre><span class="n">If</span> <span class="n">a</span> <span class="n">userpassword</span> <span class="n">is</span> <span class="n">set</span> <span class="n">by</span> <span class="n">an</span> <span class="n">LDAP</span> <span class="n">client</span> <span class="n">in</span> <span class="n">plain</span> <span class="n">text</span><span class="p">,</span> <span class="n">a</span> <span class="n">message</span> <span class="n">digest</span> <span class="n">algorithm</span> <span class="n">should</span> <span class="n">be</span> <span class="n">applied</span> <span class="n">to</span> <span class="n">the</span> <span class="n">value</span><span class="p">,</span> <span class="n">and</span> <span class="n">the</span> <span class="n">one</span><span class="o">-</span><span class="n">way</span> <span class="n">encrypted</span> <span class="n">value</span> <span class="n">should</span> <span class="n">be</span> <span class="n">stored</span>
+<span class="n">the</span> <span class="n">algorithm</span> <span class="n">should</span> <span class="n">be</span> <span class="n">applied</span> <span class="k">if</span> <span class="n">new</span> <span class="n">entries</span> <span class="n">are</span> <span class="n">created</span> <span class="n">or</span> <span class="n">existing</span> <span class="n">entries</span> <span class="n">are</span> <span class="n">modified</span> <span class="p">(</span><span class="n">hence</span> <span class="n">modify</span> <span class="n">and</span> <span class="n">add</span> <span class="n">operations</span> <span class="n">will</span> <span class="n">be</span> <span class="n">intercepted</span><span class="p">)</span>
+<span class="n">If</span> <span class="n">the</span> <span class="n">value</span> <span class="n">given</span> <span class="n">by</span> <span class="n">the</span> <span class="n">client</span> <span class="n">is</span> <span class="n">already</span> <span class="n">provided</span> <span class="n">in</span> <span class="n">hashed</span> <span class="n">form</span><span class="p">,</span> <span class="n">nothing</span> <span class="n">happens</span><span class="p">,</span> <span class="n">and</span> <span class="n">the</span> <span class="n">given</span> <span class="n">value</span> <span class="n">is</span> <span class="n">stored</span> <span class="n">in</span> <span class="n">the</span> <span class="n">directory</span> <span class="n">without</span> <span class="n">modification</span>
+</pre></div>
+
+
+<h2 id="the-sources">The sources</h2>
+<p>Currently, the sources are checked in here</p>
+<div class="codehilite"><pre><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">svn</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">org</span><span class="o">/</span><span class="n">repos</span><span class="o">/</span><span class="n">asf</span><span class="o">/</span><span class="n">directory</span><span class="o">/</span><span class="n">sandbox</span><span class="o">/</span><span class="n">szoerner</span><span class="o">/</span><span class="n">passwordHashInterceptor</span>
+</pre></div>
+
+
+<p>In order to build it, simply check it out and type "mvn install".
+Implementing the class PasswordHashInterceptor</p>
+<p>The following UML class diagram depicts the structure of the little example. Classes in white are given by Apache Directory Server as extension points. The two gray classes comprise the example interceptor.</p>
+<p><a href="passwordHashInterceptor_UML.png"></a></p>
+<p>The class HashTools contains two simple methods w.r.t. hashing. isAlreadyHashed detects whether a value has already been hashed with a known message digest algorithm. applyHashAlgorithm applies a hash algorithm to a sequence of bytes. See the source code and the unit tests of this class for details, it has not that much to do with the interceptor stuff.</p>
+<p>The central class is PasswordHashInterceptor. Every interceptor has to implement the Interceptor interface from package org.apache.directory.server.core.interceptor. PasswordHashInterceptor does so by extended the convenience class BaseInterceptor from the same package.</p>
+<p>The property hashAlgorithm allows to configure the alhorithm used for hashing the passwords. It defaults to MD5 (Message-Digest algorithm 5). The property passwordAttributeName allows configuration of the attribute type which stores the user password. Its value will be hashed if needed. The property defaults to "userPassword", which is quite common and used for instance in the inetOrgPerson object class.</p>
+<p>The most interesting methods of the class are add and modify. They intercept the requests ans modify the attribute values, if needed. See below the complete source code of the class.</p>
+<div class="codehilite"><pre><span class="n">package</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">samples</span><span class="p">.</span><span class="n">interceptor</span><span class="p">.</span><span class="n">pwdhash</span><span class="p">;</span>
+
+<span class="n">import</span> <span class="n">static</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">samples</span><span class="p">.</span><span class="n">interceptor</span><span class="p">.</span><span class="n">pwdhash</span><span class="p">.</span><span class="n">HashTools</span><span class="p">.</span><span class="n">applyHashAlgorithm</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">static</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">samples</span><span class="p">.</span><span class="n">interceptor</span><span class="p">.</span><span class="n">pwdhash</span><span class="p">.</span><span class="n">HashTools</span><span class="p">.</span><span class="n">isAlreadyHashed</span><span class="p">;</span>
+
+<span class="n">import</span> <span class="n">java</span><span class="p">.</span><span class="n">util</span><span class="p">.</span><span class="n">List</span><span class="p">;</span>
+
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">entry</span><span class="p">.</span><span class="n">ClonedServerEntry</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">interceptor</span><span class="p">.</span><span class="n">BaseInterceptor</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">interceptor</span><span class="p">.</span><span class="n">NextInterceptor</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">interceptor</span><span class="p">.</span><span class="n">context</span><span class="p">.</span><span class="n">AddOperationContext</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">interceptor</span><span class="p">.</span><span class="n">context</span><span class="p">.</span><span class="n">ModifyOperationContext</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">shared</span><span class="p">.</span><span class="n">ldap</span><span class="p">.</span><span class="n">entry</span><span class="p">.</span><span class="n">EntryAttribute</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">shared</span><span class="p">.</span><span class="n">ldap</span><span class="p">.</span><span class="n">entry</span><span class="p">.</span><span class="n">Modification</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">shared</span><span class="p">.</span><span class="n">ldap</span><span class="p">.</span><span class="n">entry</span><span class="p">.</span><span class="n">ModificationOperation</span><span class="p">;</span>
+
+<span class="n">public</span> <span class="n">class</span> <span class="n">PasswordHashInterceptor</span> <span class="n">extends</span> <span class="n">BaseInterceptor</span> <span class="p">{</span>
+
+    <span class="n">private</span> <span class="n">String</span> <span class="n">hashAlgorithm</span> <span class="p">=</span> &quot;<span class="n">MD5</span>&quot;<span class="p">;</span>
+
+    <span class="n">private</span> <span class="n">String</span> <span class="n">passwordAttributeName</span> <span class="p">=</span> &quot;<span class="n">userPassword</span>&quot;<span class="p">;</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">setHashAlgorithm</span><span class="p">(</span><span class="n">String</span> <span class="n">hashAlgorithm</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="p">.</span><span class="n">hashAlgorithm</span> <span class="p">=</span> <span class="n">hashAlgorithm</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">setPasswordAttributeName</span><span class="p">(</span><span class="n">String</span> <span class="n">passwordAttributeName</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="p">.</span><span class="n">passwordAttributeName</span> <span class="p">=</span> <span class="n">passwordAttributeName</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="o">/**</span>
+     <span class="o">*</span> <span class="n">Intercepts</span> <span class="n">the</span> <span class="n">add</span> <span class="n">operation</span> <span class="n">in</span> <span class="n">order</span> <span class="n">to</span> <span class="n">replace</span> <span class="n">plain</span> <span class="n">password</span> <span class="n">values</span>
+     <span class="o">*</span> <span class="n">with</span> <span class="n">hashed</span> <span class="nb">ones</span><span class="p">.</span>
+     <span class="o">*/</span>
+    <span class="p">@</span><span class="n">Override</span>
+    <span class="n">public</span> <span class="n">void</span> <span class="n">add</span><span class="p">(</span><span class="n">NextInterceptor</span> <span class="n">next</span><span class="p">,</span> <span class="n">AddOperationContext</span> <span class="n">opContext</span><span class="p">)</span>
+            <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+
+        <span class="n">ClonedServerEntry</span> <span class="n">entry</span> <span class="p">=</span> <span class="n">opContext</span><span class="p">.</span><span class="n">getEntry</span><span class="p">();</span>
+        <span class="n">EntryAttribute</span> <span class="n">attribute</span> <span class="p">=</span> <span class="n">entry</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">passwordAttributeName</span><span class="p">);</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">attribute</span> !<span class="p">=</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
+            <span class="n">hashPasswordIfNeccessary</span><span class="p">(</span><span class="n">attribute</span><span class="p">);</span>
+        <span class="p">}</span>
+
+        <span class="n">super</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">next</span><span class="p">,</span> <span class="n">opContext</span><span class="p">);</span>
+    <span class="p">}</span>
+
+    <span class="o">/**</span>
+     <span class="o">*</span> <span class="n">Intercepts</span> <span class="n">the</span> <span class="n">modify</span> <span class="n">operation</span> <span class="n">in</span> <span class="n">order</span> <span class="n">to</span> <span class="n">replace</span> <span class="n">plain</span> <span class="n">password</span> <span class="n">values</span>
+     <span class="o">*</span> <span class="n">with</span> <span class="n">hashed</span> <span class="nb">ones</span><span class="p">.</span>
+     <span class="o">*/</span>
+    <span class="p">@</span><span class="n">Override</span>
+    <span class="n">public</span> <span class="n">void</span> <span class="n">modify</span><span class="p">(</span><span class="n">NextInterceptor</span> <span class="n">next</span><span class="p">,</span> <span class="n">ModifyOperationContext</span> <span class="n">opContext</span><span class="p">)</span>
+            <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+
+        <span class="n">List</span><span class="o">&lt;</span><span class="n">Modification</span><span class="o">&gt;</span> <span class="n">items</span> <span class="p">=</span> <span class="n">opContext</span><span class="p">.</span><span class="n">getModItems</span><span class="p">();</span>
+        <span class="k">for</span> <span class="p">(</span><span class="n">Modification</span> <span class="n">modification</span> <span class="p">:</span> <span class="n">items</span><span class="p">)</span> <span class="p">{</span>
+            <span class="n">ModificationOperation</span> <span class="n">operation</span> <span class="p">=</span> <span class="n">modification</span><span class="p">.</span><span class="n">getOperation</span><span class="p">();</span>
+            <span class="k">if</span> <span class="p">(</span><span class="n">operation</span> <span class="o">==</span> <span class="n">ModificationOperation</span><span class="p">.</span><span class="n">ADD_ATTRIBUTE</span>
+                    <span class="o">||</span> <span class="n">operation</span> <span class="o">==</span> <span class="n">ModificationOperation</span><span class="p">.</span><span class="n">REPLACE_ATTRIBUTE</span><span class="p">)</span> <span class="p">{</span>
+                <span class="n">EntryAttribute</span> <span class="n">attribute</span> <span class="p">=</span> <span class="n">modification</span><span class="p">.</span><span class="n">getAttribute</span><span class="p">();</span>
+                <span class="k">if</span> <span class="p">(</span><span class="n">attribute</span><span class="p">.</span><span class="n">getId</span><span class="p">().</span><span class="n">equalsIgnoreCase</span><span class="p">(</span><span class="n">passwordAttributeName</span><span class="p">))</span> <span class="p">{</span>
+                    <span class="n">hashPasswordIfNeccessary</span><span class="p">(</span><span class="n">attribute</span><span class="p">);</span>
+                <span class="p">}</span>
+            <span class="p">}</span>
+        <span class="p">}</span>
+        <span class="n">super</span><span class="p">.</span><span class="n">modify</span><span class="p">(</span><span class="n">next</span><span class="p">,</span> <span class="n">opContext</span><span class="p">);</span>
+    <span class="p">}</span>
+
+    <span class="n">protected</span> <span class="n">void</span> <span class="n">hashPasswordIfNeccessary</span><span class="p">(</span><span class="n">EntryAttribute</span> <span class="n">attribute</span><span class="p">)</span> <span class="p">{</span>
+        <span class="k">try</span> <span class="p">{</span>
+            <span class="n">byte</span><span class="p">[]</span> <span class="n">password</span> <span class="p">=</span> <span class="n">attribute</span><span class="p">.</span><span class="n">getBytes</span><span class="p">();</span>
+            <span class="k">if</span> <span class="p">(</span>!<span class="n">isAlreadyHashed</span><span class="p">(</span><span class="n">password</span><span class="p">))</span> <span class="p">{</span>
+                <span class="n">byte</span><span class="p">[]</span> <span class="n">hashed</span> <span class="p">=</span> <span class="n">applyHashAlgorithm</span><span class="p">(</span><span class="n">hashAlgorithm</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
+                <span class="n">attribute</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
+                <span class="n">attribute</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">hashed</span><span class="p">);</span>
+            <span class="p">}</span>
+        <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
+            <span class="n">throw</span> <span class="n">new</span> <span class="n">RuntimeException</span><span class="p">(</span>&quot;<span class="n">Password</span> <span class="n">hash</span> <span class="n">failed</span>&quot;<span class="p">,</span> <span class="n">e</span><span class="p">);</span>
+        <span class="p">}</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<h2 id="using-the-interceptor">Using the interceptor</h2>
+<p>You may use a custom interceptor both in a standard ApacheDS installation and in a server started embedded.
+Adding it to a standard server installation (server.xml)</p>
+<p>In order to get the interceptor installed in a default installation of ApacheDS 1.5.5., just copy the jar-File resulting from the Maven build, which contains the custom classes, to APACHEDS_INSTALLDIR/lib/ext.</p>
+<p>After that, add the interceptor to the server.xml file in APACHEDS_INSTALLDIR/conf/. Make sure to backup the file before your modifications. Within server.xml find the XML elements which list the interceptors. The easiest way to add a custom interceptor is to add a spring bean (namespace "s"). You mya set configuration properties to the interceptor as well, if it supports some.</p>
+<p>The following fragment shows the interceptor list with the example interceptor added just behind normalization. For demonstration purposes, the hash algorithm is set to "MD5" (which is the default of our interceptor anyway).</p>
+<div class="codehilite"><pre>...
+<span class="nt">&lt;interceptors&gt;</span>
+  <span class="nt">&lt;normalizationInterceptor/&gt;</span>
+  <span class="nt">&lt;s:bean</span> <span class="na">class=</span><span class="s">&quot;org.apache.directory.samples.interceptor.pwdhash.PasswordHashInterceptor&quot;</span><span class="nt">&gt;</span> 
+     <span class="nt">&lt;s:property</span> <span class="na">name=</span><span class="s">&quot;hashAlgorithm&quot;</span> <span class="na">value=</span><span class="s">&quot;MD5&quot;</span> <span class="nt">/&gt;</span> 
+  <span class="nt">&lt;/s:bean&gt;</span>
+  <span class="nt">&lt;authenticationInterceptor/&gt;</span>
+  <span class="nt">&lt;referralInterceptor/&gt;</span>
+  <span class="nt">&lt;aciAuthorizationInterceptor/&gt;</span>
+  <span class="nt">&lt;defaultAuthorizationInterceptor/&gt;</span>
+  <span class="nt">&lt;exceptionInterceptor/&gt;</span>
+  <span class="nt">&lt;operationalAttributeInterceptor/&gt;</span>
+  ...
+<span class="nt">&lt;/interceptors&gt;</span>
+...
+</pre></div>
+
+
+<h2 id="embedded-mode">Embedded mode</h2>
+<p>As an alternative, the following Java code starts an ApacheDS embedded in a main method. The list of interceptors is complemented with the example interceptor. We insert it exactly behind the NormalizingInterceptor (the position is a little bit tricky to determine).</p>
+<div class="codehilite"><pre><span class="n">package</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">samples</span><span class="p">.</span><span class="n">interceptor</span><span class="p">.</span><span class="n">pwdhash</span><span class="p">;</span>
+
+<span class="n">import</span> <span class="n">java</span><span class="p">.</span><span class="n">util</span><span class="p">.</span><span class="n">List</span><span class="p">;</span>
+
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">DefaultDirectoryService</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">DirectoryService</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">interceptor</span><span class="p">.</span><span class="n">Interceptor</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">core</span><span class="p">.</span><span class="n">normalization</span><span class="p">.</span><span class="n">NormalizationInterceptor</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">ldap</span><span class="p">.</span><span class="n">LdapServer</span><span class="p">;</span>
+<span class="n">import</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">directory</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">protocol</span><span class="p">.</span><span class="n">shared</span><span class="p">.</span><span class="n">transport</span><span class="p">.</span><span class="n">TcpTransport</span><span class="p">;</span>
+
+<span class="o">/**</span>
+ <span class="o">*</span> <span class="n">Main</span> <span class="n">class</span> <span class="n">which</span> <span class="n">starts</span> <span class="n">an</span> <span class="n">embedded</span> <span class="n">server</span> <span class="n">with</span> <span class="n">the</span> <span class="n">interceptor</span> <span class="n">inserted</span> <span class="n">into</span>
+ <span class="o">*</span> <span class="n">the</span> <span class="n">chain</span><span class="p">.</span>
+ <span class="o">*/</span>
+<span class="n">public</span> <span class="n">class</span> <span class="n">Main</span> <span class="p">{</span>
+
+    <span class="n">public</span> <span class="n">static</span> <span class="n">void</span> <span class="n">main</span><span class="p">(</span><span class="n">String</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
+
+        <span class="n">DirectoryService</span> <span class="n">directoryService</span> <span class="p">=</span> <span class="n">new</span> <span class="n">DefaultDirectoryService</span><span class="p">();</span>
+        <span class="n">directoryService</span><span class="p">.</span><span class="n">setShutdownHookEnabled</span><span class="p">(</span><span class="n">true</span><span class="p">);</span>
+
+        <span class="n">List</span><span class="o">&lt;</span><span class="n">Interceptor</span><span class="o">&gt;</span> <span class="n">interceptors</span> <span class="p">=</span> <span class="n">directoryService</span><span class="p">.</span><span class="n">getInterceptors</span><span class="p">();</span>
+
+        <span class="o">//</span> <span class="n">Find</span> <span class="n">Normalization</span> <span class="n">interceptor</span> <span class="n">in</span> <span class="n">chain</span>
+        <span class="n">int</span> <span class="n">insertionPosition</span> <span class="p">=</span> <span class="o">-</span>1<span class="p">;</span>
+        <span class="k">for</span> <span class="p">(</span><span class="n">int</span> <span class="n">pos</span> <span class="p">=</span> 0<span class="p">;</span> <span class="n">pos</span> <span class="o">&lt;</span> <span class="n">interceptors</span><span class="p">.</span><span class="nb">size</span><span class="p">();</span> <span class="o">++</span><span class="n">pos</span><span class="p">)</span> <span class="p">{</span>
+            <span class="n">Interceptor</span> <span class="n">interceptor</span> <span class="p">=</span> <span class="n">interceptors</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">pos</span><span class="p">);</span>
+            <span class="k">if</span> <span class="p">(</span><span class="n">interceptor</span> <span class="n">instanceof</span> <span class="n">NormalizationInterceptor</span><span class="p">)</span> <span class="p">{</span>
+                <span class="n">insertionPosition</span> <span class="p">=</span> <span class="n">pos</span><span class="p">;</span>
+            <span class="p">}</span>
+        <span class="p">}</span>
+
+        <span class="o">//</span> <span class="n">insert</span> <span class="n">our</span> <span class="n">new</span> <span class="n">interceptor</span> <span class="n">just</span> <span class="n">behind</span>
+        <span class="n">interceptors</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">insertionPosition</span> <span class="o">+</span> 1<span class="p">,</span> <span class="n">new</span> <span class="n">PasswordHashInterceptor</span><span class="p">());</span>
+        <span class="n">directoryService</span><span class="p">.</span><span class="n">setInterceptors</span><span class="p">(</span><span class="n">interceptors</span><span class="p">);</span>
+
+        <span class="n">LdapServer</span> <span class="n">ldapServer</span> <span class="p">=</span> <span class="n">new</span> <span class="n">LdapServer</span><span class="p">();</span>
+        <span class="n">ldapServer</span><span class="p">.</span><span class="n">setDirectoryService</span><span class="p">(</span><span class="n">directoryService</span><span class="p">);</span>
+        <span class="n">ldapServer</span><span class="p">.</span><span class="n">setAllowAnonymousAccess</span><span class="p">(</span><span class="n">true</span><span class="p">);</span>
+
+        <span class="n">TcpTransport</span> <span class="n">ldapTransport</span> <span class="p">=</span> <span class="n">new</span> <span class="n">TcpTransport</span><span class="p">(</span>10389<span class="p">);</span>
+        <span class="n">ldapServer</span><span class="p">.</span><span class="n">setTransports</span><span class="p">(</span><span class="n">ldapTransport</span><span class="p">);</span>
+
+        <span class="n">directoryService</span><span class="p">.</span><span class="n">startup</span><span class="p">();</span>
+        <span class="n">ldapServer</span><span class="p">.</span><span class="n">start</span><span class="p">();</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<h2 id="verification">Verification</h2>
+<p>Let's check whether our new interceptor does its job! In order to do so, we use Apache Directory Studio and connect to the server with the interceptor enabled (see above).</p>
+<p>First we create a new entry with the following data, using "New Entry ..." within Studio.</p>
+<div class="codehilite"><pre><span class="n">dn</span><span class="o">:</span> <span class="n">cn</span><span class="o">=</span><span class="n">Kate</span> <span class="n">Bush</span><span class="o">,</span><span class="n">ou</span><span class="o">=</span><span class="n">users</span><span class="o">,</span><span class="n">ou</span><span class="o">=</span><span class="n">system</span>
+<span class="n">objectClass</span><span class="o">:</span> <span class="n">person</span>
+<span class="n">objectClass</span><span class="o">:</span> <span class="n">top</span>
+<span class="n">cn</span><span class="o">:</span> <span class="n">Kate</span> <span class="n">Bush</span>
+<span class="n">sn</span><span class="o">:</span> <span class="n">Bush</span>
+</pre></div>
+
+
+<p>Then we add a new attribute userPassword in the entry editor. For the value, a special editor appears:</p>
+<p><a href="passwordHashInterceptor_passwordEditor.png"></a></p>
+<p>Select "Plaintext" as the hash method and enter a new password. We selected "secret" (see screen shot above). After pressing OK, a modify operation is sent to the server, which will be intercepted by our example class.</p>
+<p><a href="passwordHashInterceptor_modificationLog.png"></a></p>
+<p>After that, the value for userPassword is not "secret", but the MD5 digested value of it.</p>
+<p><a href="passwordHashInterceptor_entryEditor.png"></a></p>
+<p>The user Kate Bush is still capable of authenticating with the password "secret", because Apache Directory Server supports authentication with passwords hashed with this algorithm. You can verify this by connecting with Studio and the using "cn=Kate Bush,ou=users,ou=system" as bind DN.</p>
+<p>Here it is demonstrated with the help of the ldapsearch command line tool. The result also shows that the userPassword value is hashed with MD5.</p>
+<div class="codehilite"><pre>$ <span class="n">ldapsearch</span> <span class="o">-</span><span class="n">h</span> <span class="n">localhost</span> <span class="o">-</span><span class="n">p</span> 10389 <span class="o">-</span><span class="n">D</span> &quot;<span class="n">cn</span><span class="p">=</span><span class="n">Kate</span> <span class="n">Bush</span><span class="p">,</span><span class="n">ou</span><span class="p">=</span><span class="n">users</span><span class="p">,</span><span class="n">ou</span><span class="p">=</span><span class="n">system</span>&quot; <span class="o">\\</span>
+    <span class="o">-</span><span class="n">w</span> <span class="n">secret</span>  <span class="o">-</span><span class="n">b</span> &quot;<span class="n">ou</span><span class="p">=</span><span class="n">users</span><span class="p">,</span><span class="n">ou</span><span class="p">=</span><span class="n">system</span>&quot; <span class="o">-</span><span class="n">s</span> <span class="n">one</span> &quot;<span class="p">(</span><span class="n">objectClass</span><span class="p">=</span><span class="o">*</span><span class="p">)</span>&quot;
+<span class="n">version</span><span class="p">:</span> 1
+<span class="n">dn</span><span class="p">:</span> <span class="n">cn</span><span class="p">=</span><span class="n">Kate</span> <span class="n">Bush</span><span class="p">,</span><span class="n">ou</span><span class="p">=</span><span class="n">users</span><span class="p">,</span><span class="n">ou</span><span class="p">=</span><span class="n">system</span>
+<span class="n">objectClass</span><span class="p">:</span> <span class="n">person</span>
+<span class="n">objectClass</span><span class="p">:</span> <span class="n">top</span>
+<span class="n">cn</span><span class="p">:</span> <span class="n">Kate</span> <span class="n">Bush</span>
+<span class="n">sn</span><span class="p">:</span> <span class="n">Bush</span>
+<span class="n">userPassword</span><span class="p">:</span> <span class="p">{</span><span class="n">MD5</span><span class="p">}</span><span class="n">Xr4ilOzQ4PCOq3aQ0qbuaQ</span><span class="o">==</span>
+$
+</pre></div>
+
+
+<h2 id="limitations-of-the-example">Limitations of the example</h2>
+<p>This example is intended as a demonstration, on how to write your custom interceptor. Don't consider it bullet proof. It has not been tested under production conditions, etc.</p>
+<p>At least the following limitation should be mentioned</p>
+<div class="codehilite"><pre><span class="n">The</span> <span class="n">default</span> <span class="n">hash</span> <span class="n">algorithm</span> <span class="n">MD5</span> <span class="n">is</span> <span class="n">considered</span> <span class="n">weak</span><span class="p">.</span>
+<span class="n">Exception</span> <span class="n">handling</span> <span class="n">is</span> <span class="n">poor</span><span class="p">.</span> <span class="n">E</span><span class="p">.</span><span class="n">g</span><span class="p">.</span> <span class="k">if</span> <span class="n">someone</span> <span class="n">configures</span> <span class="n">an</span> <span class="n">unsupported</span> <span class="n">hash</span> <span class="n">algorithm</span><span class="p">,</span> <span class="n">the</span> <span class="n">interceptor</span> <span class="n">fails</span> <span class="n">to</span> <span class="n">create</span> <span class="n">an</span> <span class="n">appropriate</span> <span class="n">LDAP</span> <span class="n">error</span><span class="p">.</span>
+<span class="n">If</span> <span class="n">a</span> <span class="n">multivalued</span> <span class="n">password</span> <span class="n">attribute</span> <span class="n">is</span> <span class="n">used</span><span class="p">,</span> <span class="n">the</span> <span class="n">interceptor</span> <span class="n">will</span> <span class="n">simply</span> <span class="n">ignore</span> <span class="n">that</span> <span class="n">fact</span> <span class="p">(</span><span class="n">does</span> <span class="n">not</span> <span class="n">apply</span> <span class="n">to</span> <span class="n">userPassword</span> <span class="n">as</span> <span class="n">of</span> <span class="n">RFC</span> 2256<span class="p">).</span>
+</pre></div>
+
+
+<h2 id="further-reading">Further reading</h2>
+<p>Learn more about interceptors in ApacheDS Architecture Documentation, check out the source code of some implementations of the Interceptor interface, and/or read the javadoc comments.</p>
+
+
+    <div class="nav">
+        <div class="nav_prev">
+        
+            <a href="5.4-replication.html">5.4 - Replication</a>
+		
+        </div>
+        <div class="nav_up">
+        
+            <a href="../advanced-user-guide.html">Advanced User Guide</a>
+		
+        </div>
+        <div class="nav_next">
+        
+			&nbsp;
+        
+        </div>
+        <div class="clearfix"></div>
+    </div>
+
+
+                </div><!-- rightColumn -->
+                <div id="endContent"></div>
+            </div><!-- content -->
+            <div id="footer">&copy; 2003-2014, <a href="http://www.apache.org">The Apache Software Foundation</a> - <a href="./../../privacy-policy.html">Privacy Policy</a><br />
+                Apache Directory, ApacheDS, Apache Directory Server, Apache Directory Studio, Apache LDAP API, Apache Triplesec, Triplesec, Apache Mavibot, Mavibot, Apache eSCIMo, eSCIMo, Apache, the Apache feather logo, and the Apache Directory project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </div><!-- container -->
+    </body>
+</html>
\ No newline at end of file



Mime
View raw message