Hello Jerome,
what about put the javax.security.Principal in the request attributes after successfull authentication?
This is a possibility, maybe a good compromise that would also you to get
rid of your subclass?
Yes. I've created a patch and attach it to this email.
Your implementation of "findSecret(id)" can perfectly retrieve an encrypted
password in a database, decode it and return the password in clear, just for
the time of the verification.
But than you have to save the password decryptable. If you put the password hashed with a Crypto hash (MD5 or SHA) into the database, than it could be undecryptable by anyone. It has the advantage, that no one with access to the database (allowed or criminal attack) could get the password.
But that's not the point for my thesis :-)

best regards
 Stephan
Index: modules/org.restlet/src/org/restlet/Guard.java
===================================================================
--- modules/org.restlet/src/org/restlet/Guard.java      (revision 2623)
+++ modules/org.restlet/src/org/restlet/Guard.java      (working copy)
@@ -18,11 +18,14 @@
 
 package org.restlet;
 
+import java.io.Serializable;
+import java.security.Principal;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import org.restlet.data.ChallengeResponse;
 import org.restlet.data.ChallengeScheme;
 import org.restlet.data.Request;
 import org.restlet.data.Response;
@@ -37,6 +40,62 @@
  * @author Jerome Louvel ([EMAIL PROTECTED])
  */
 public class Guard extends Filter {
+    /**
+     * @author Stephan Koops
+     */
+    private class PrincipalImpl implements Principal, Serializable {
+
+        private static final long serialVersionUID = -1842197948591956691L;
+
+        private String name;
+
+        @SuppressWarnings("unused")
+        private PrincipalImpl() {
+            // constructor for deserialization
+        }
+
+        /**
+         * Creates a new Principal with the given name
+         * 
+         * @param name
+         *                The name of the Principal; must not be null
+         */
+        public PrincipalImpl(String name) {
+            if (name == null)
+                throw new IllegalArgumentException("The name must not be 
null");
+            this.name = name;
+        }
+
+        @Override
+        public boolean equals(Object another) {
+            if (another == this)
+                return true;
+            if (!(another instanceof Principal))
+                return false;
+            Principal otherPrinc = (Principal) another;
+            return getName().equals(otherPrinc.getName());
+        }
+
+        /**
+         * Returns the name of this principal.
+         * 
+         * @return the name of this principal.
+         */
+        public String getName() {
+            return this.name;
+        }
+
+        @Override
+        public int hashCode() {
+            return this.name.hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return getName();
+        }
+    }
+
     /** Indicates that an authentication response is considered invalid. */
     public static final int AUTHENTICATION_INVALID = -1;
 
@@ -52,6 +111,25 @@
     /** Default lifespan for generated nonces (5 minutes). */
     public static final long DEFAULT_NONCE_LIFESPAN_MILLIS = 5 * 60 * 1000L;
 
+    /**
+     * Name of the Header Principal in the request attributes.
+     * 
+     * @see Principal
+     */
+    private static final String JAVA_SECURITY_HEADER = 
"java.security.Principal";
+
+    /**
+     * Gets the logged in user.
+     * 
+     * @param request
+     *                The Restlet [EMAIL PROTECTED] Request}
+     * @return The [EMAIL PROTECTED] Principal} of the logged in user.
+     * @see #setPrincipal(Principal, Request)
+     */
+    public static Principal getPrincipal(Request request) {
+        return (Principal) request.getAttributes().get(JAVA_SECURITY_HEADER);
+    }
+
     /** The URIs that define the HTTP DIGEST authentication protection 
domains. */
     private Collection<String> domainUris = Collections.singleton("/");
 
@@ -120,9 +198,17 @@
     }
 
     /**
+     * <p>
      * Accepts the call. By default, it is invoked it the request is
      * authenticated and authorized, and asks the attached Restlet to handle 
the
      * call.
+     * </p>
+     * <p>
+     * If this method will be overridden without call this method by
+     * super.accept(..), you should also call
+     * [EMAIL PROTECTED] #createAndSetPrincipal(Request)} before call
+     * [EMAIL PROTECTED] #doHandle(Request, Response)}.
+     * </p>
      * 
      * @param request
      *                The request to accept.
@@ -130,6 +216,7 @@
      *                The response to accept.
      */
     public void accept(Request request, Response response) {
+        this.createAndSetPrincipal(request);
         // Invoke the attached Restlet
         super.doHandle(request, response);
     }
@@ -159,6 +246,7 @@
      *                The request to authorize.
      * @return True if the request is authorized.
      */
+    @SuppressWarnings("unused")
     public boolean authorize(Request request) {
         // Authorize everything by default
         return true;
@@ -196,12 +284,15 @@
      * this returns true given the correct login/password couple as verified 
via
      * the findSecret() method.
      * 
+     * @param request
+     *                The Request
      * @param identifier
      *                the identifier
      * @param secret
      *                the identifier's secret
      * @return true if the secret is valid for the given identifier
      */
+    @SuppressWarnings("unused")
     public boolean checkSecret(Request request, String identifier, char[] 
secret) {
         return checkSecret(identifier, secret);
     }
@@ -240,6 +331,27 @@
     }
 
     /**
+     * Creates a [EMAIL PROTECTED] Principal} and put in in the attributes Map 
of the given
+     * request. You can read this Principal with method
+     * [EMAIL PROTECTED] Guard#getPrincipal(Request)}.
+     * 
+     * @param request
+     */
+    protected void createAndSetPrincipal(Request request) {
+        Principal principal = null;
+        ChallengeResponse challengeResponse = request.getChallengeResponse();
+        if (challengeResponse != null) {
+            String credentials = challengeResponse.getIdentifier();
+            if (credentials != null)
+                principal = new PrincipalImpl(credentials);
+        }
+        if (principal != null)
+            request.getAttributes().put(JAVA_SECURITY_HEADER, principal);
+        else
+            request.getAttributes().remove(JAVA_SECURITY_HEADER);
+    }
+
+    /**
      * Handles the call by distributing it to the next Restlet.
      * 
      * @param request
@@ -436,4 +548,4 @@
     public void setServerKey(String serverKey) {
         this.serverKey = serverKey;
     }
-}
+}
\ No newline at end of file

Reply via email to