You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by sb...@apache.org on 2012/03/01 02:02:49 UTC

git commit: DELTASPIKE-78 partial implementation of Authentication API

Updated Branches:
  refs/heads/master b259252f9 -> a179c42c9


DELTASPIKE-78 partial implementation of Authentication API

Submitted on behalf of a third party: Red Hat, Inc. under the terms of the ALv2


Project: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/commit/a179c42c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/tree/a179c42c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/diff/a179c42c

Branch: refs/heads/master
Commit: a179c42c94b7fc87ed9b7c2910b796e34bf36d3f
Parents: b259252
Author: Shane Bryzak <sb...@gmail.com>
Authored: Thu Mar 1 11:01:18 2012 +1000
Committer: Shane Bryzak <sb...@gmail.com>
Committed: Thu Mar 1 11:01:18 2012 +1000

----------------------------------------------------------------------
 .../security/api/AuthenticatorSelector.java        |   37 ++++
 .../deltaspike/security/api/BaseAuthenticator.java |   57 +++++
 .../apache/deltaspike/security/api/Identity.java   |   10 -
 .../deltaspike/security/spi/Authenticator.java     |   29 +++
 .../security/impl/AuthenticatorSelectorImpl.java   |  149 ++++++++++++++
 .../deltaspike/security/impl/IdentityImpl.java     |  158 ++++++++++++---
 .../security/impl/jaas/JaasAuthenticator.java      |  160 +++++++++++++++
 .../security/impl/management/IdmAuthenticator.java |   79 +++++++
 .../deltaspike/security/impl/util/Strings.java     |  101 +++++++++
 .../impl/secured/SecuredAnnotationTest.java        |    4 +-
 .../impl/secured/SecuredBeanWithStereotype.java    |    2 +-
 11 files changed, 748 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/a179c42c/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/AuthenticatorSelector.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/AuthenticatorSelector.java b/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/AuthenticatorSelector.java
new file mode 100644
index 0000000..5931a99
--- /dev/null
+++ b/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/AuthenticatorSelector.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+package org.apache.deltaspike.security.api;
+
+import org.apache.deltaspike.security.spi.Authenticator;
+
+/**
+ * Selects which Authenticator implementation is used to manage the authentication process 
+ */
+public interface AuthenticatorSelector
+{
+    Class<? extends Authenticator> getAuthenticatorClass();
+
+    void setAuthenticatorClass(Class<? extends Authenticator> authenticatorClass);
+
+    String getAuthenticatorName();
+
+    void setAuthenticatorName(String authenticatorName);
+    
+    Authenticator getSelectedAuthenticator();
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/a179c42c/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/BaseAuthenticator.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/BaseAuthenticator.java b/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/BaseAuthenticator.java
new file mode 100644
index 0000000..fbbe5de
--- /dev/null
+++ b/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/BaseAuthenticator.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+package org.apache.deltaspike.security.api;
+
+import org.apache.deltaspike.security.spi.Authenticator;
+
+/**
+ * Abstract base class that Authenticator implementations can extend for convenience. 
+ *
+ */
+public abstract class BaseAuthenticator implements Authenticator
+{
+    private AuthenticationStatus status;
+    
+    private User user;
+
+    public AuthenticationStatus getStatus() 
+    {
+        return status;
+    }
+
+    public void setStatus(AuthenticationStatus status) 
+    {
+        this.status = status;
+    }
+
+    public User getUser() 
+    {
+        return user;
+    }
+
+    public void setUser(User user) 
+    {
+        this.user = user;
+    }
+
+    public void postAuthenticate() 
+    {
+        // No-op, override if any post-authentication processing is required.
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/a179c42c/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/Identity.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/Identity.java b/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/Identity.java
index b8ec720..95b22c2 100644
--- a/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/Identity.java
+++ b/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/Identity.java
@@ -23,7 +23,6 @@ import java.util.Set;
 import org.apache.deltaspike.security.Group;
 import org.apache.deltaspike.security.api.annotation.LoggedIn;
 import org.apache.deltaspike.security.api.annotation.Secures;
-import org.apache.deltaspike.security.spi.Authenticator;
 
 /**
  * Represents the identity of the current user, and provides an API for authentication and authorization. 
@@ -134,13 +133,4 @@ public interface Identity
      * @return
      */
     Set<Group> getGroups();
-
-    Class<? extends Authenticator> getAuthenticatorClass();
-
-    void setAuthenticatorClass(Class<? extends Authenticator> authenticatorClass);
-
-    String getAuthenticatorName();
-
-    void setAuthenticatorName(String authenticatorName);
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/a179c42c/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/spi/Authenticator.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/spi/Authenticator.java b/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/spi/Authenticator.java
index f117b97..f682f6f 100644
--- a/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/spi/Authenticator.java
+++ b/deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/spi/Authenticator.java
@@ -19,7 +19,36 @@
 
 package org.apache.deltaspike.security.spi;
 
+import java.util.Set;
+
+import javax.management.relation.Role;
+
+import org.apache.deltaspike.security.Group;
+import org.apache.deltaspike.security.api.User;
+
+/**
+ * An Authenticator implementation is responsible for managing the user authentication process. 
+ */
 public interface Authenticator
 {
+    public enum AuthenticationStatus 
+    {
+        SUCCESS, 
+        FAILURE, 
+        DEFERRED
+    }
+
+    void authenticate();
+
+    void postAuthenticate();
+
+    AuthenticationStatus getStatus();
+
+    User getUser();
+
+    // TODO we'll likely remove the following two methods - still under discussion
+    
+    Set<Role>  getRoleMemberships();
 
+    Set<Group>  getGroupMemberships(); 
 }

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/a179c42c/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/AuthenticatorSelectorImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/AuthenticatorSelectorImpl.java b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/AuthenticatorSelectorImpl.java
new file mode 100644
index 0000000..23a730c
--- /dev/null
+++ b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/AuthenticatorSelectorImpl.java
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+package org.apache.deltaspike.security.impl;
+
+import java.util.List;
+
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+
+import org.apache.deltaspike.core.api.literal.NamedLiteral;
+import org.apache.deltaspike.core.api.provider.BeanProvider;
+import org.apache.deltaspike.security.api.AuthenticatorSelector;
+import org.apache.deltaspike.security.impl.jaas.JaasAuthenticator;
+import org.apache.deltaspike.security.impl.management.IdmAuthenticator;
+import org.apache.deltaspike.security.impl.util.Strings;
+import org.apache.deltaspike.security.spi.Authenticator;
+
+/**
+ * Default implementation of AuthenticatorSelector
+ */
+public class AuthenticatorSelectorImpl implements AuthenticatorSelector
+{
+    private String authenticatorName;
+    
+    private Class<? extends Authenticator> authenticatorClass;
+    
+    @Inject @Any 
+    private Instance<Authenticator> authenticators;
+    
+    /**
+     * Returns an Authenticator instance to be used for authentication. The default
+     * implementation obeys the following business logic:
+     * <p/>
+     * 1. If the user has specified an authenticatorClass property, use it to
+     * locate the Authenticator with that exact type
+     * 2. If the user has specified an authenticatorName property, use it to
+     * locate and return the Authenticator with that name
+     * 3. If the authenticatorClass and authenticatorName haven't been specified,
+     * and the user has provided their own custom Authenticator, return that one
+     * 4. If the user hasn't provided a custom Authenticator, return IdmAuthenticator
+     * and attempt to use the Identity Management API to authenticate
+     *
+     * @return
+     */
+    public Authenticator getSelectedAuthenticator() 
+    {
+        if (authenticatorClass != null) 
+        {
+            return authenticators.select(authenticatorClass).get();
+        }
+
+        if (!Strings.isEmpty(authenticatorName)) 
+        {
+            Instance<Authenticator> selected = authenticators.select(new NamedLiteral(authenticatorName));
+            if (selected.isAmbiguous()) 
+            {
+                //log.error("Multiple Authenticators found with configured name [" + authenticatorName + "]");
+                return null;
+            }
+
+            if (selected.isUnsatisfied()) 
+            {
+                //log.error("No authenticator with name [" + authenticatorName + "] was found");
+                return null;
+            }
+
+            return selected.get();
+        }
+
+        Authenticator selectedAuth = null;
+        
+        List<Authenticator> references = BeanProvider.getContextualReferences(Authenticator.class, true);
+
+        for (Authenticator auth : references) 
+        {
+            // If the user has provided their own custom authenticator then use it -
+            // a custom authenticator is one that isn't one of the known authenticators;
+            // JaasAuthenticator, IdmAuthenticator, or any external authenticator, etc
+            if (!JaasAuthenticator.class.isAssignableFrom(auth.getClass()) &&
+                    !IdmAuthenticator.class.isAssignableFrom(auth.getClass()) &&
+                    !isExternalAuthenticator(auth.getClass())) 
+            {
+                selectedAuth = auth;
+                break;
+            }
+
+            if (IdmAuthenticator.class.isAssignableFrom(auth.getClass())) 
+            {
+                selectedAuth = auth;
+            }
+        }
+
+        return selectedAuth;
+    }
+
+
+    private boolean isExternalAuthenticator(Class<? extends Authenticator> authClass) 
+    {
+        Class<?> cls = authClass;
+
+        while (cls != Object.class) 
+        {
+            if (cls.getName().startsWith("org.jboss.seam.security.external.")) 
+            {
+                return true;
+            }
+            cls = cls.getSuperclass();
+        }
+
+        return false;
+    }
+
+    public Class<? extends Authenticator> getAuthenticatorClass()
+    {
+        return authenticatorClass;
+    }
+
+    public void setAuthenticatorClass(Class<? extends Authenticator> authenticatorClass)
+    {
+        this.authenticatorClass = authenticatorClass;
+    }
+
+    public String getAuthenticatorName()
+    {
+        return authenticatorName;
+    }
+
+    public void setAuthenticatorName(String authenticatorName)
+    {
+        this.authenticatorName = authenticatorName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/a179c42c/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/IdentityImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/IdentityImpl.java b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/IdentityImpl.java
index d098710..7fcddbf 100644
--- a/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/IdentityImpl.java
+++ b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/IdentityImpl.java
@@ -28,6 +28,7 @@ import javax.inject.Inject;
 
 import org.apache.deltaspike.security.Group;
 import org.apache.deltaspike.security.api.AuthenticationException;
+import org.apache.deltaspike.security.api.AuthenticatorSelector;
 import org.apache.deltaspike.security.api.Credentials;
 import org.apache.deltaspike.security.api.Identity;
 import org.apache.deltaspike.security.api.Role;
@@ -35,10 +36,13 @@ import org.apache.deltaspike.security.api.User;
 import org.apache.deltaspike.security.api.events.AlreadyLoggedInEvent;
 import org.apache.deltaspike.security.api.events.LoggedInEvent;
 import org.apache.deltaspike.security.api.events.LoginFailedEvent;
+import org.apache.deltaspike.security.api.events.PostAuthenticateEvent;
 import org.apache.deltaspike.security.api.events.PostLoggedOutEvent;
+import org.apache.deltaspike.security.api.events.PreAuthenticateEvent;
 import org.apache.deltaspike.security.api.events.PreLoggedOutEvent;
 import org.apache.deltaspike.security.api.events.QuietLoginEvent;
 import org.apache.deltaspike.security.spi.Authenticator;
+import org.apache.deltaspike.security.spi.Authenticator.AuthenticationStatus;
 
 /**
  * Default Identity implementation
@@ -54,15 +58,21 @@ public class IdentityImpl implements Identity
     @Inject 
     private Instance<RequestSecurityState> requestSecurityState;
     
-    private User user;
+    @Inject
+    private Instance<AuthenticatorSelector> authenticatorSelector;
     
-    private Class<? extends Authenticator> authenticatorClass;
+    private Authenticator activeAuthenticator;
     
-    private String authenticatorName;    
+    private User user;
     
     private Set<Role> userRoles = new HashSet<Role>();
 
     private Set<Group> userGroups = new HashSet<Group>();    
+    
+    /**
+     * Flag indicating whether we are currently authenticating
+     */
+    private boolean authenticating;
 
     public boolean isLoggedIn() 
     {
@@ -155,8 +165,126 @@ public class IdentityImpl implements Identity
     
     protected boolean authenticate() throws AuthenticationException 
     {
-        // TODO discuss authentication API
-        return false;
+        if (authenticating) 
+        {
+            authenticating = false;
+            throw new IllegalStateException("Authentication already in progress.");
+        }
+
+        try 
+        {
+            authenticating = true;
+
+            user = null;
+
+            beanManager.fireEvent(new PreAuthenticateEvent());
+
+            activeAuthenticator = authenticatorSelector.get().getSelectedAuthenticator();
+
+            if (activeAuthenticator == null) 
+            {
+                authenticating = false;
+                throw new AuthenticationException("An Authenticator could not be located");
+            }
+
+            activeAuthenticator.authenticate();
+
+            if (activeAuthenticator.getStatus() == null) 
+            {
+                throw new AuthenticationException("Authenticator must return a valid authentication status");
+            }
+
+            switch (activeAuthenticator.getStatus()) 
+            {
+                case SUCCESS:
+                    postAuthenticate();
+                    return true;
+                case FAILURE:
+                default:
+                    authenticating = false;
+                    return false;
+            }
+        } 
+        catch (Exception ex) 
+        {
+            authenticating = false;
+            if (ex instanceof AuthenticationException) 
+            {
+                throw (AuthenticationException) ex;
+            } 
+            else 
+            {
+                throw new AuthenticationException("Authentication failed.", ex);
+            }
+        }
+    }    
+    
+    protected void postAuthenticate() 
+    {
+        if (activeAuthenticator == null) 
+        {
+            throw new IllegalStateException("activeAuthenticator is null");
+        }
+
+        try 
+        {
+            activeAuthenticator.postAuthenticate();
+
+            if (!activeAuthenticator.getStatus().equals(AuthenticationStatus.SUCCESS))
+            {
+                return;
+            }
+
+            user = activeAuthenticator.getUser();
+
+            if (user == null) 
+            {
+                throw new AuthenticationException(
+                        "Authenticator must provide a non-null User after successful authentication");
+            }
+
+            if (isLoggedIn()) 
+            {
+                // TODO rewrite this once we decide how user privilege state is managed
+                
+                /**if (!preAuthenticationRoles.isEmpty()) 
+                {
+                    for (String group : preAuthenticationRoles.keySet()) 
+                    {
+                        Map<String, List<String>> groupTypeRoles = preAuthenticationRoles.get(group);
+                        for (String groupType : groupTypeRoles.keySet()) 
+                        {
+                            for (String roleType : groupTypeRoles.get(groupType)) 
+                            {
+                                addRole(roleType, group, groupType);
+                            }
+                        }
+                    }
+                    preAuthenticationRoles.clear();
+                }
+
+                if (!preAuthenticationGroups.isEmpty()) 
+                {
+                    for (String group : preAuthenticationGroups.keySet()) 
+                    {
+                        for (String groupType : preAuthenticationGroups.get(group)) 
+                        {
+                            activeGroups.add(new SimpleGroup(group, groupType));
+                        }
+                    }
+                    preAuthenticationGroups.clear();
+                }*/
+            }
+
+            beanManager.fireEvent(new PostAuthenticateEvent());
+        } 
+        finally 
+        {
+            // Set credential to null whether authentication is successful or not
+            activeAuthenticator = null;
+            credentials.setCredential(null);
+            authenticating = false;
+        }
     }    
 
     @Override
@@ -214,24 +342,4 @@ public class IdentityImpl implements Identity
     {
         return Collections.unmodifiableSet(userGroups);
     }
-
-    public Class<? extends Authenticator> getAuthenticatorClass() 
-    {
-        return authenticatorClass;
-    }
-
-    public void setAuthenticatorClass(Class<? extends Authenticator> authenticatorClass) 
-    {
-        this.authenticatorClass = authenticatorClass;
-    }
-
-    public String getAuthenticatorName() 
-    {
-        return authenticatorName;
-    }
-
-    public void setAuthenticatorName(String authenticatorName) 
-    {
-        this.authenticatorName = authenticatorName;
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/a179c42c/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/jaas/JaasAuthenticator.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/jaas/JaasAuthenticator.java b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/jaas/JaasAuthenticator.java
new file mode 100644
index 0000000..98d9f4b
--- /dev/null
+++ b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/jaas/JaasAuthenticator.java
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+package org.apache.deltaspike.security.impl.jaas;
+
+import java.io.IOException;
+import java.util.Set;
+
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.management.relation.Role;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.apache.deltaspike.security.Group;
+import org.apache.deltaspike.security.api.BaseAuthenticator;
+import org.apache.deltaspike.security.api.Credentials;
+import org.apache.deltaspike.security.api.Identity;
+import org.apache.deltaspike.security.impl.PasswordCredential;
+import org.apache.deltaspike.security.spi.Authenticator;
+
+/**
+ * An authenticator for authenticating with JAAS.  The jaasConfigName property
+ * _must_ be configured to point to a valid JAAS configuration name, typically
+ * defined in a file called login-config.xml in the application server.
+ */
+@Named
+@RequestScoped
+public class JaasAuthenticator extends BaseAuthenticator implements Authenticator 
+{
+    @Inject
+    private Identity identity;
+    
+    @Inject
+    private Credentials credentials;
+    
+    @Inject
+    private BeanManager manager;
+
+    private Subject subject;
+
+    private String jaasConfigName = null;
+
+    public JaasAuthenticator() 
+    {
+        subject = new Subject();
+    }
+
+    public void authenticate() 
+    {
+        if (getJaasConfigName() == null) 
+        {
+            throw new IllegalStateException(
+                    "jaasConfigName cannot be null.  Please set it to a valid JAAS configuration name.");
+        }
+
+        try 
+        {
+            getLoginContext().login();
+            setStatus(AuthenticationStatus.SUCCESS);
+        } 
+        catch (LoginException e) 
+        {
+            setStatus(AuthenticationStatus.FAILURE);
+            //log.error("JAAS authentication failed", e);
+        }
+    }
+
+    protected LoginContext getLoginContext() throws LoginException 
+    {
+        return new LoginContext(getJaasConfigName(), subject,
+                createCallbackHandler());
+    }
+
+    /**
+     * Creates a callback handler that can handle a standard username/password
+     * callback, using the credentials username and password properties
+     */
+    public CallbackHandler createCallbackHandler() 
+    {
+        return new CallbackHandler() 
+        {
+            public void handle(Callback[] callbacks)
+                throws IOException, UnsupportedCallbackException 
+            {
+                for (int i = 0; i < callbacks.length; i++) 
+                {
+                    if (callbacks[i] instanceof NameCallback) 
+                    {
+                        ((NameCallback) callbacks[i]).setName(credentials.getUsername());
+                    } 
+                    else if (callbacks[i] instanceof PasswordCallback) 
+                    {
+                        if (credentials.getCredential() instanceof PasswordCredential) 
+                        {
+                            PasswordCredential credential = (PasswordCredential) credentials.getCredential();
+                            ((PasswordCallback) callbacks[i]).setPassword(credential.getValue() != null ?
+                                    credential.getValue().toCharArray() : null);
+                        }
+                    } 
+                    else 
+                    {
+                        //log.warn("Unsupported callback " + callbacks[i]);
+                    }
+                }
+            }
+        };
+    }
+
+    public String getJaasConfigName() 
+    {
+        return jaasConfigName;
+    }
+
+    public void setJaasConfigName(String jaasConfigName) 
+    {
+        this.jaasConfigName = jaasConfigName;
+    }
+
+    public void postAuthenticate() 
+    {
+    }
+
+    @Override
+    public Set<Role> getRoleMemberships()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Set<Group> getGroupMemberships()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/a179c42c/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/management/IdmAuthenticator.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/management/IdmAuthenticator.java b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/management/IdmAuthenticator.java
new file mode 100644
index 0000000..667c7dc
--- /dev/null
+++ b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/management/IdmAuthenticator.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+package org.apache.deltaspike.security.impl.management;
+
+import java.util.Set;
+
+import javax.management.relation.Role;
+
+import org.apache.deltaspike.security.Group;
+import org.apache.deltaspike.security.api.User;
+import org.apache.deltaspike.security.spi.Authenticator;
+
+/**
+ * Authenticates using the Identity Management API
+ * 
+ *  TODO - discuss the Identity Management API before implementing this class
+ */
+public class IdmAuthenticator implements Authenticator
+{
+
+    @Override
+    public void authenticate()
+    {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void postAuthenticate()
+    {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public AuthenticationStatus getStatus()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User getUser()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Set<Role> getRoleMemberships()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Set<Group> getGroupMemberships()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/a179c42c/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/util/Strings.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/util/Strings.java b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/util/Strings.java
new file mode 100644
index 0000000..c242817
--- /dev/null
+++ b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/util/Strings.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+package org.apache.deltaspike.security.impl.util;
+
+/**
+ * String utility methods
+ */
+public class Strings 
+{
+    private Strings() 
+    {
+        
+    }
+    
+    public static String unqualify(String name) 
+    {
+        return unqualify(name, '.');
+    }
+
+    public static String unqualify(String name, char sep) 
+    {
+        return name.substring(name.lastIndexOf(sep) + 1, name.length());
+    }
+
+    public static boolean isEmpty(String string) 
+    {
+        int len = string.length();
+        if (string == null || len == 0) 
+        {
+            return true;
+        }
+
+        for (int i = 0; i < len; i++) 
+        {
+            if ((Character.isWhitespace(string.charAt(i)) == false)) 
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static String toClassNameString(String sep, Object... objects) 
+    {
+        if (objects.length == 0) 
+        {
+            return "";
+        }
+        
+        StringBuilder builder = new StringBuilder();
+        for (Object object : objects) 
+        {
+            builder.append(sep);
+            if (object == null) 
+            {
+                builder.append("null");
+            } 
+            else 
+            {
+                builder.append(object.getClass().getName());
+            }
+        }
+        return builder.substring(sep.length());
+    }
+
+    public static String toString(Object... objects) 
+    {
+        return toString(" ", objects);
+    }
+
+    public static String toString(String sep, Object... objects) 
+    {
+        if (objects.length == 0) 
+        {
+            return "";
+        }
+        
+        StringBuilder builder = new StringBuilder();
+        for (Object object : objects) 
+        {
+            builder.append(sep).append(object);
+        }
+        return builder.substring(sep.length());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/a179c42c/deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/secured/SecuredAnnotationTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/secured/SecuredAnnotationTest.java b/deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/secured/SecuredAnnotationTest.java
index 32d8195..d914ba1 100644
--- a/deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/secured/SecuredAnnotationTest.java
+++ b/deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/secured/SecuredAnnotationTest.java
@@ -69,8 +69,8 @@ public class SecuredAnnotationTest
                 .addAsLibraries(ShrinkWrapArchiveUtil.getArchives(null,
                         "META-INF/beans.xml",
                         new String[]{"org.apache.deltaspike.core",
-                                "org.apache.deltaspike.security",
-                                "org.apache.deltaspike.test.security.impl.secured"},
+                            "org.apache.deltaspike.security",
+                            "org.apache.deltaspike.test.security.impl.secured"},
                         excludedFiles))
                 .addAsServiceProvider(Extension.class, ExcludeExtension.class)
                 .addAsWebInfResource(beansXml, "beans.xml");

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/a179c42c/deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/secured/SecuredBeanWithStereotype.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/secured/SecuredBeanWithStereotype.java b/deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/secured/SecuredBeanWithStereotype.java
index 0e1a215..19873fd 100644
--- a/deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/secured/SecuredBeanWithStereotype.java
+++ b/deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/secured/SecuredBeanWithStereotype.java
@@ -31,7 +31,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
 @Stereotype
 
 @Retention(value = RUNTIME)
-@Target({TYPE, METHOD} )
+@Target({TYPE, METHOD } )
 
 @Secured(TestAccessDecisionVoter.class)
 public @interface SecuredBeanWithStereotype