You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2017/09/01 13:17:04 UTC

[06/64] [partial] knox git commit: KNOX-998 - Refactoring save 1

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/filter/ShiroSubjectIdentityAdapter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/filter/ShiroSubjectIdentityAdapter.java b/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/filter/ShiroSubjectIdentityAdapter.java
deleted file mode 100644
index b625f34..0000000
--- a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/filter/ShiroSubjectIdentityAdapter.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * 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.hadoop.gateway.filter;
-
-import java.io.IOException;
-import java.security.Principal;
-import java.security.PrivilegedExceptionAction;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.Callable;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-import org.apache.hadoop.gateway.audit.api.Action;
-import org.apache.hadoop.gateway.audit.api.ActionOutcome;
-import org.apache.hadoop.gateway.audit.api.AuditService;
-import org.apache.hadoop.gateway.audit.api.AuditServiceFactory;
-import org.apache.hadoop.gateway.audit.api.Auditor;
-import org.apache.hadoop.gateway.audit.api.ResourceType;
-import org.apache.hadoop.gateway.audit.log4j.audit.AuditConstants;
-import org.apache.hadoop.gateway.security.GroupPrincipal;
-import org.apache.hadoop.gateway.security.PrimaryPrincipal;
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.subject.Subject;
-
-public class ShiroSubjectIdentityAdapter implements Filter {
-  
-  private static final String SUBJECT_USER_GROUPS = "subject.userGroups";
-  private static AuditService auditService = AuditServiceFactory.getAuditService();
-  private static Auditor auditor = auditService.getAuditor(
-      AuditConstants.DEFAULT_AUDITOR_NAME, AuditConstants.KNOX_SERVICE_NAME,
-      AuditConstants.KNOX_COMPONENT_NAME );
-  
-
-  @Override
-  public void init( FilterConfig filterConfig ) throws ServletException {
-  }
-
-  public void destroy() {
-  }
-
-  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
-      throws IOException, ServletException {
-    
-    Subject subject = SecurityUtils.getSubject();
-    
-    // trigger call to shiro authorization realm
-    // we use shiro authorization realm to look up groups
-    subject.hasRole("authenticatedUser");
-
-    CallableChain callableChain = new CallableChain(request, response, chain);
-    SecurityUtils.getSubject().execute(callableChain);
-  }
-  
-  private static class CallableChain implements Callable<Void> {
-    private FilterChain chain = null;
-    ServletRequest request = null;
-    ServletResponse response = null;
-    
-    CallableChain(ServletRequest request, ServletResponse response, FilterChain chain) {
-      this.request = request;
-      this.response = response;
-      this.chain = chain;
-    }
-
-    @Override
-    public Void call() throws Exception {
-      PrivilegedExceptionAction<Void> action = new PrivilegedExceptionAction<Void>() {
-        @Override
-        public Void run() throws Exception {
-          chain.doFilter( request, response );
-          return null;
-        }
-      };
-      Subject shiroSubject = SecurityUtils.getSubject();
-
-      if (shiroSubject == null || shiroSubject.getPrincipal() == null) {
-        throw new IllegalStateException("Unable to determine authenticated user from Shiro, please check that your Knox Shiro configuration is correct");
-      }
-
-      final String principal = (String) shiroSubject.getPrincipal().toString();
-      HashSet emptySet = new HashSet();
-      Set<Principal> principals = new HashSet<>();
-      Principal p = new PrimaryPrincipal(principal);
-      principals.add(p);
-      auditService.getContext().setUsername( principal ); //KM: Audit Fix
-      String sourceUri = (String)request.getAttribute( AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME );
-      auditor.audit( Action.AUTHENTICATION , sourceUri, ResourceType.URI, ActionOutcome.SUCCESS );
-
-      Set<String> userGroups = null;
-      // map ldap groups saved in session to Java Subject GroupPrincipal(s)
-      if (SecurityUtils.getSubject().getSession().getAttribute(SUBJECT_USER_GROUPS) != null) {
-        userGroups = (Set<String>)SecurityUtils.getSubject().getSession().getAttribute(SUBJECT_USER_GROUPS);
-      } else { // KnoxLdapRealm case
-        if(  shiroSubject.getPrincipal() instanceof String ) { 
-           userGroups = new HashSet<>(shiroSubject.getPrincipals().asSet());
-           userGroups.remove(principal);
-        } else { // KnoxPamRealm case
-           Set<Principal> shiroPrincipals = new HashSet<>(shiroSubject.getPrincipals().asSet());
-           userGroups = new HashSet<>(); // Here we are creating a new UserGroup
-                                               // so we don't need to remove a Principal
-                                               // In the case of LDAP the userGroup may have already Principal
-                                               // added to the list of groups, so it is not needed.
-           for( Principal shiroPrincipal: shiroPrincipals ) {
-                userGroups.add(shiroPrincipal.toString() );
-           }
-        }
-      }
-      for (String userGroup : userGroups) {
-        Principal gp = new GroupPrincipal(userGroup);
-        principals.add(gp);
-      }
-      auditor.audit( Action.AUTHENTICATION , sourceUri, ResourceType.URI, ActionOutcome.SUCCESS, "Groups: " + userGroups );
-      
-//      The newly constructed Sets check whether this Subject has been set read-only 
-//      before permitting subsequent modifications. The newly created Sets also prevent 
-//      illegal modifications by ensuring that callers have sufficient permissions.
-//
-//      To modify the Principals Set, the caller must have AuthPermission("modifyPrincipals"). 
-//      To modify the public credential Set, the caller must have AuthPermission("modifyPublicCredentials"). 
-//      To modify the private credential Set, the caller must have AuthPermission("modifyPrivateCredentials").
-      javax.security.auth.Subject subject = new javax.security.auth.Subject(true, principals, emptySet, emptySet);
-      javax.security.auth.Subject.doAs( subject, action );
-      
-      return null;
-    }
-    
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxCacheManager.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxCacheManager.java b/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxCacheManager.java
deleted file mode 100644
index cf2d529..0000000
--- a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxCacheManager.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.hadoop.gateway.shirorealm;
-
-import org.apache.shiro.cache.ehcache.EhCacheManager;
-
-public class KnoxCacheManager extends EhCacheManager {
-
-  public KnoxCacheManager() {
-    setCacheManager(net.sf.ehcache.CacheManager.create());
-  }
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapContextFactory.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapContextFactory.java b/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapContextFactory.java
deleted file mode 100644
index b4d0c5c..0000000
--- a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapContextFactory.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- *  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.hadoop.gateway.shirorealm;
-
-import java.util.Hashtable;
-
-import javax.naming.Context;
-import javax.naming.NamingException;
-import javax.naming.ldap.LdapContext;
-
-import org.apache.hadoop.gateway.GatewayMessages;
-import org.apache.hadoop.gateway.GatewayServer;
-import org.apache.hadoop.gateway.config.GatewayConfig;
-import org.apache.hadoop.gateway.config.impl.GatewayConfigImpl;
-import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
-import org.apache.hadoop.gateway.services.GatewayServices;
-import org.apache.hadoop.gateway.services.security.AliasService;
-import org.apache.hadoop.gateway.services.security.AliasServiceException;
-import org.apache.hadoop.gateway.util.KnoxCLI;
-import org.apache.shiro.realm.ldap.JndiLdapContextFactory;
-
-/**
- * An extension of {@link JndiLdapContextFactory} that allows a different authentication mechanism
- * for system-level authentications (as used by authorization lookups, for example)
- * compared to regular authentication.
- * 
- * <p>
- * See {@link IsisLdapRealm} for typical configuration within <tt>shiro.ini</tt>.
- */
-public class KnoxLdapContextFactory extends JndiLdapContextFactory {
-
-    private static GatewayMessages LOG = MessagesFactory.get( GatewayMessages.class );
-  
-    private String systemAuthenticationMechanism = "simple";
-    private String clusterName = "";
-
-    public KnoxLdapContextFactory() {
-      setAuthenticationMechanism("simple");
-    }
-    
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    @Override
-    protected LdapContext createLdapContext(Hashtable env) throws NamingException {
-        if(getSystemUsername() != null && getSystemUsername().equals(env.get(Context.SECURITY_PRINCIPAL))) {
-            env.put(Context.SECURITY_AUTHENTICATION, getSystemAuthenticationMechanism());
-        }
-        return super.createLdapContext(env);
-    }
-
-    public String getSystemAuthenticationMechanism() {
-        return systemAuthenticationMechanism != null? systemAuthenticationMechanism: getAuthenticationMechanism();
-    }
-    
-    public void setSystemAuthenticationMechanism(String systemAuthenticationMechanism) {
-        this.systemAuthenticationMechanism = systemAuthenticationMechanism;
-    }
-    
-    @Override
-    public void setSystemPassword(String systemPass) {
-     
-      if ( systemPass == null ) {
-        return;
-      }
-      
-      systemPass = systemPass.trim();
-      if (systemPass.length() == 0) {
-        return;
-      }
-      
-      if (!systemPass.startsWith("S{ALIAS=")) {
-        super.setSystemPassword( systemPass );
-        return;
-      }
-      
-      systemPass= systemPass.substring( "S{ALIAS=".length(), systemPass.length() - 1 );
-      String aliasName = systemPass;
-      
-      GatewayServices services = GatewayServer.getGatewayServices();
-      AliasService aliasService = (AliasService)services.getService(GatewayServices.ALIAS_SERVICE);
-      
-      String clusterName = getClusterName();
-      //System.err.println("FACTORY systempass 30: " + systemPass);
-      //System.err.println("FACTORY clustername 40: " + clusterName);
-      //System.err.println("FACTORY SystemProperty GatewayHome 50: " + System.getProperty(GatewayConfig.GATEWAY_HOME_VAR));
-      char[] password = null;
-      try {
-        password = aliasService.getPasswordFromAliasForCluster(clusterName, systemPass);
-      } catch (AliasServiceException e) {
-        LOG.unableToGetPassword(e);
-      }
-      //System.err.println("FACTORY password: " + ((password == null) ? "NULL" : new String(password)));
-      if ( password != null ) {
-        //System.err.println("FACTORY SUCCESS 20 system password :" + new String(password));
-        super.setSystemPassword( new String(password) );
-      } else {
-        //System.err.println("FACTORY FORCING system password to blank");
-        super.setSystemPassword("" );
-        LOG.aliasValueNotFound(clusterName, aliasName);
-      }
-    }
-    
-    public String getClusterName() {
-      return clusterName;
-    }
-
-    public void setClusterName(String clusterName) {
-      if (clusterName != null) {
-        this.clusterName = clusterName.trim();
-      }
-    }
-    
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java b/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
deleted file mode 100644
index c81125a..0000000
--- a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
+++ /dev/null
@@ -1,768 +0,0 @@
-/*
- *  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.hadoop.gateway.shirorealm;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.naming.AuthenticationException;
-import javax.naming.Context;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.PartialResultException;
-import javax.naming.SizeLimitExceededException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.SearchControls;
-import javax.naming.directory.SearchResult;
-import javax.naming.ldap.Control;
-import javax.naming.ldap.LdapContext;
-import javax.naming.ldap.LdapName;
-import javax.naming.ldap.PagedResultsControl;
-import javax.naming.ldap.PagedResultsResponseControl;
-
-import org.apache.hadoop.gateway.GatewayMessages;
-import org.apache.hadoop.gateway.audit.api.Action;
-import org.apache.hadoop.gateway.audit.api.ActionOutcome;
-import org.apache.hadoop.gateway.audit.api.AuditService;
-import org.apache.hadoop.gateway.audit.api.AuditServiceFactory;
-import org.apache.hadoop.gateway.audit.api.Auditor;
-import org.apache.hadoop.gateway.audit.api.ResourceType;
-import org.apache.hadoop.gateway.audit.log4j.audit.AuditConstants;
-import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
-import org.apache.hadoop.gateway.shirorealm.impl.i18n.KnoxShiroMessages;
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.authc.AuthenticationInfo;
-import org.apache.shiro.authc.AuthenticationToken;
-import org.apache.shiro.authc.SimpleAuthenticationInfo;
-import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
-import org.apache.shiro.authz.AuthorizationInfo;
-import org.apache.shiro.authz.SimpleAuthorizationInfo;
-import org.apache.shiro.crypto.hash.DefaultHashService;
-import org.apache.shiro.crypto.hash.Hash;
-import org.apache.shiro.crypto.hash.HashRequest;
-import org.apache.shiro.crypto.hash.HashService;
-import org.apache.shiro.realm.ldap.JndiLdapRealm;
-import org.apache.shiro.realm.ldap.LdapContextFactory;
-import org.apache.shiro.realm.ldap.LdapUtils;
-import org.apache.shiro.subject.MutablePrincipalCollection;
-import org.apache.shiro.subject.PrincipalCollection;
-import org.apache.shiro.util.StringUtils;
-
-/**
- * Implementation of {@link org.apache.shiro.realm.ldap.JndiLdapRealm} that also
- * returns each user's groups.
- * This implementation is heavily based on org.apache.isis.security.shiro.IsisLdapRealm.
- * 
- * This implementation saves looked up ldap groups in Shiro Session to make them
- * easy to be looked up outside of this object
- * 
- * <p>
- * Sample config for <tt>shiro.ini</tt>:
- * 
- * [main]
- * ldapRealm=org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm
- * ldapGroupContextFactory=org.apache.hadoop.gateway.shirorealm.KnoxLdapContextFactory
- * ldapRealm.contextFactory=$ldapGroupContextFactory
- * ldapRealm.contextFactory.authenticationMechanism=simple
- * ldapRealm.contextFactory.url=ldap://localhost:33389
- * ldapRealm.userDnTemplate=uid={0},ou=people,dc=hadoop,dc=apache,dc=org
- * ldapRealm.authorizationEnabled=true
- * ldapRealm.contextFactory.systemAuthenticationMechanism=simple
- * ldapRealm.searchBase=ou=groups,dc=hadoop,dc=apache,dc=org
- * ldapRealm.groupObjectClass=groupofnames
- * ldapRealm.memberAttribute=member
- * ldapRealm.memberAttributeValueTemplate=cn={0},ou=people,dc=hadoop,dc=apache,dc=org
- * ldapRealm.contextFactory.systemUsername=uid=guest,ou=people,dc=hadoop,dc=apache,dc=org
- * ldapRealm.contextFactory.clusterName=sandbox
- * ldapRealm.contextFactory.systemPassword=S{ALIAS=ldcSystemPassword}
- * [urls]
- * **=authcBasic
- *
- * # optional mapping from physical groups to logical application roles
- * ldapRealm.rolesByGroup = \
- *    LDN_USERS: user_role,\
- *    NYK_USERS: user_role,\
- *    HKG_USERS: user_role,\
- *    GLOBAL_ADMIN: admin_role,\
- *    DEMOS: self-install_role
- * 
- * ldapRealm.permissionsByRole=\
- *    user_role = *:ToDoItemsJdo:*:*,\
- *                *:ToDoItem:*:*; \
- *    self-install_role = *:ToDoItemsFixturesService:install:* ; \
- *    admin_role = *
- * 
- * securityManager.realms = $ldapRealm
- * 
- * </pre>
- */
-public class KnoxLdapRealm extends JndiLdapRealm {
-
-    private static GatewayMessages LOG = MessagesFactory.get( GatewayMessages.class );
-    KnoxShiroMessages ShiroLog = MessagesFactory.get( KnoxShiroMessages.class );
-    private static AuditService auditService = AuditServiceFactory.getAuditService();
-    private static Auditor auditor = auditService.getAuditor(
-        AuditConstants.DEFAULT_AUDITOR_NAME, AuditConstants.KNOX_SERVICE_NAME,
-        AuditConstants.KNOX_COMPONENT_NAME );
-
-    private static Pattern TEMPLATE_PATTERN = Pattern.compile( "\\{(\\d+?)\\}" );
-    private static String DEFAULT_PRINCIPAL_REGEX = "(.*)";
-    private static final String MEMBER_SUBSTITUTION_TOKEN = "{0}";
-
-    private static final SearchControls SUBTREE_SCOPE = new SearchControls();
-    private static final SearchControls ONELEVEL_SCOPE = new SearchControls();
-    private static final SearchControls OBJECT_SCOPE = new SearchControls();
-
-    private static final String  SUBJECT_USER_ROLES = "subject.userRoles";
-    private static final String  SUBJECT_USER_GROUPS = "subject.userGroups";
-
-    private static final String  MEMBER_URL = "memberUrl";
-
-    private static final String POSIX_GROUP = "posixGroup";
-
-    private static final String HASHING_ALGORITHM = "SHA-256";
-
-    static {
-          SUBTREE_SCOPE.setSearchScope(SearchControls.SUBTREE_SCOPE);
-          ONELEVEL_SCOPE.setSearchScope(SearchControls.ONELEVEL_SCOPE);
-          OBJECT_SCOPE.setSearchScope( SearchControls.OBJECT_SCOPE );
-      }
-
- 
-    private String searchBase;
-    private String userSearchBase;
-    private String principalRegex = DEFAULT_PRINCIPAL_REGEX;
-    private Pattern principalPattern = Pattern.compile( DEFAULT_PRINCIPAL_REGEX );
-    private String userDnTemplate = "{0}";
-    private String userSearchFilter = null;
-    private String userSearchAttributeTemplate = "{0}";
-    private String userSearchScope = "subtree";
-
-    private String groupSearchBase;
-
-    private String groupObjectClass = "groupOfNames";
-    
-    //  typical value: member, uniqueMember, meberUrl
-    private String memberAttribute = "member";
-
-    private String groupIdAttribute = "cn";
-    
-    private String memberAttributeValuePrefix = "uid={0}";
-    private String memberAttributeValueSuffix = "";
-    
-    private final Map<String,String> rolesByGroup = new LinkedHashMap<String, String>();
-    private final Map<String,List<String>> permissionsByRole = new LinkedHashMap<String, List<String>>();
-    
-    private boolean authorizationEnabled;
-
-    private String userSearchAttributeName;
-    private String userObjectClass = "person";
-
-    private HashService hashService = new DefaultHashService();
-
-    public KnoxLdapRealm() {
-      HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(HASHING_ALGORITHM);
-      setCredentialsMatcher(credentialsMatcher);
-    }
-
-  @Override
-  //KNOX-534 overriding this method to be able to audit authentication exceptions
-  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws org.apache.shiro.authc.AuthenticationException {
-    try {
-      return super.doGetAuthenticationInfo(token);
-    } catch ( org.apache.shiro.authc.AuthenticationException e ) {
-      auditor.audit( Action.AUTHENTICATION , token.getPrincipal().toString(), ResourceType.PRINCIPAL, ActionOutcome.FAILURE, e.getMessage() );
-      ShiroLog.failedLoginInfo(token);
-      ShiroLog.failedLoginStackTrace(e);
-      ShiroLog.failedLoginAttempt(e.getCause());
-
-      throw e;
-    }
-  }
-
-  /**
-     * Get groups from LDAP.
-     * 
-     * @param principals
-     *            the principals of the Subject whose AuthenticationInfo should
-     *            be queried from the LDAP server.
-     * @param ldapContextFactory
-     *            factory used to retrieve LDAP connections.
-     * @return an {@link AuthorizationInfo} instance containing information
-     *         retrieved from the LDAP server.
-     * @throws NamingException
-     *             if any LDAP errors occur during the search.
-     */
-    @Override
-    protected AuthorizationInfo queryForAuthorizationInfo(final PrincipalCollection principals, 
-        final LdapContextFactory ldapContextFactory) throws NamingException {
-      if (!isAuthorizationEnabled()) {
-        return null;
-      }
-      final Set<String> roleNames = getRoles(principals, ldapContextFactory);
-        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(roleNames);
-        Set<String> stringPermissions = permsFor(roleNames);
-        simpleAuthorizationInfo.setStringPermissions(stringPermissions);
-        return simpleAuthorizationInfo;
-    }
-
-    private Set<String> getRoles(PrincipalCollection principals,
-        final LdapContextFactory ldapContextFactory) throws NamingException {
-        final String username = (String) getAvailablePrincipal(principals);
-
-        LdapContext systemLdapCtx = null;
-        try {
-            systemLdapCtx = ldapContextFactory.getSystemLdapContext();
-            return rolesFor(principals, username, systemLdapCtx, ldapContextFactory);
-        } catch (AuthenticationException e) {
-          LOG.failedToGetSystemLdapConnection(e);
-          return Collections.emptySet();
-        } finally {
-            LdapUtils.closeContext(systemLdapCtx);
-        }
-    }
-
-    private Set<String> rolesFor(PrincipalCollection principals, final String userName, final LdapContext ldapCtx,
-        final LdapContextFactory ldapContextFactory) throws NamingException {
-      final Set<String> roleNames = new HashSet<>();
-      final Set<String> groupNames = new HashSet<>();
-
-      String userDn;
-      if (userSearchAttributeName == null || userSearchAttributeName.isEmpty()) {
-        // memberAttributeValuePrefix and memberAttributeValueSuffix were computed from memberAttributeValueTemplate
-        userDn = memberAttributeValuePrefix + userName + memberAttributeValueSuffix;
-      } else {
-        userDn = getUserDn(userName);
-      }
-
-      // Activate paged results
-      int pageSize = 100;
-      int numResults = 0;
-      byte[] cookie = null;
-      try {
-        ldapCtx.addToEnvironment(Context.REFERRAL, "ignore");
-
-        ldapCtx.setRequestControls(new Control[]{new PagedResultsControl(pageSize, Control.NONCRITICAL)});
-
-        do {
-          // ldapsearch -h localhost -p 33389 -D uid=guest,ou=people,dc=hadoop,dc=apache,dc=org -w  guest-password
-          //       -b dc=hadoop,dc=apache,dc=org -s sub '(objectclass=*)'
-
-          NamingEnumeration<SearchResult> searchResultEnum = null;
-          try {
-            searchResultEnum = ldapCtx.search(
-                getGroupSearchBase(),
-                "objectClass=" + groupObjectClass,
-                SUBTREE_SCOPE);
-
-            while (searchResultEnum != null && searchResultEnum.hasMore()) { // searchResults contains all the groups in search scope
-              numResults++;
-              final SearchResult group = searchResultEnum.next();
-              addRoleIfMember(userDn, group, roleNames, groupNames, ldapContextFactory);
-            }
-          } catch (PartialResultException e) {
-            LOG.ignoringPartialResultException();
-          } finally {
-            if (searchResultEnum != null) {
-              searchResultEnum.close();
-            }
-          }
-
-          // Examine the paged results control response
-          Control[] controls = ldapCtx.getResponseControls();
-          if (controls != null) {
-            for (Control control : controls) {
-              if (control instanceof PagedResultsResponseControl) {
-                PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
-                cookie = prrc.getCookie();
-              }
-            }
-          }
-
-          // Re-activate paged results
-          ldapCtx.setRequestControls(new Control[]{new PagedResultsControl(pageSize, cookie, Control.CRITICAL)});
-        } while (cookie != null);
-      } catch (SizeLimitExceededException e) {
-        LOG.sizeLimitExceededOnlyRetrieved(numResults);
-//        System.out.println("Only retrieved first " + numResults + " groups due to SizeLimitExceededException.");
-      } catch(IOException e) {
-        LOG.unableToSetupPagedResults();
-//        System.out.println("Unabled to setup paged results");
-      }
-
-      // save role names and group names in session so that they can be easily looked up outside of this object
-      SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_ROLES, roleNames);
-      SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_GROUPS, groupNames);
-      if (!groupNames.isEmpty() && (principals instanceof MutablePrincipalCollection)) {
-        ((MutablePrincipalCollection)principals).addAll(groupNames, getName());
-      }
-      LOG.lookedUpUserRoles(roleNames, userName);
-
-      return roleNames;
-    }
-
-  private void addRoleIfMember(final String userDn, final SearchResult group,
-      final Set<String> roleNames, final Set<String> groupNames,
-      final LdapContextFactory ldapContextFactory) throws NamingException {
-
-    NamingEnumeration<? extends Attribute> attributeEnum = null;
-    NamingEnumeration<?> e = null;
-    try {
-      LdapName userLdapDn = new LdapName(userDn);
-      Attribute attribute = group.getAttributes().get(getGroupIdAttribute());
-      String groupName = attribute.get().toString();
-      
-      attributeEnum = group
-          .getAttributes().getAll();
-      while (attributeEnum.hasMore()) {
-        final Attribute attr = attributeEnum.next();
-        if (!memberAttribute.equalsIgnoreCase(attr.getID())) {
-          continue;
-        }
-        e = attr.getAll();
-        while (e.hasMore()) {
-          String attrValue = e.next().toString();
-          if (memberAttribute.equalsIgnoreCase(MEMBER_URL)) {
-            boolean dynamicGroupMember = isUserMemberOfDynamicGroup(userLdapDn,
-                attrValue, // memberUrl value
-                ldapContextFactory);
-            if (dynamicGroupMember) {
-              groupNames.add(groupName);
-              String roleName = roleNameFor(groupName);
-              if (roleName != null) {
-                roleNames.add(roleName);
-              } else {
-                roleNames.add(groupName);
-              }
-            }
-          } else {
-            if (groupObjectClass.equalsIgnoreCase(POSIX_GROUP)){
-              attrValue = memberAttributeValuePrefix + attrValue + memberAttributeValueSuffix;
-            }
-            if (userLdapDn.equals(new LdapName(attrValue))) {
-              groupNames.add(groupName);
-              String roleName = roleNameFor(groupName);
-              if (roleName != null) {
-                roleNames.add(roleName);
-              } else {
-                roleNames.add(groupName);
-              }
-              break;
-            }
-          }
-        }
-      }
-    }
-    finally {
-      try {
-        if (attributeEnum != null) {
-          attributeEnum.close();
-        }
-      }
-      finally {
-        if (e != null) {
-          e.close();
-        }
-      }
-    }
-  }
-
-    private String roleNameFor(String groupName) {
-        return !rolesByGroup.isEmpty() ? rolesByGroup.get(groupName) : groupName;
-    }
-
-
-    private Set<String> permsFor(Set<String> roleNames) {
-        Set<String> perms = new LinkedHashSet<String>(); // preserve order
-        for(String role: roleNames) {
-            List<String> permsForRole = permissionsByRole.get(role);
-            if(permsForRole != null) {
-                perms.addAll(permsForRole);
-            }
-        }
-        return perms;
-    }
-
-    public String getSearchBase() {
-        return searchBase;
-    }
-
-    public void setSearchBase(String searchBase) {
-      this.searchBase = searchBase;
-    }
-
-    public String getUserSearchBase() {
-      return  (userSearchBase != null && !userSearchBase.isEmpty()) ? 
-          userSearchBase : searchBase;
-    }
-
-    public void setUserSearchBase(String userSearchBase) {
-      this.userSearchBase = userSearchBase;
-    }
-
-    public String getGroupSearchBase() {
-      return (groupSearchBase != null && !groupSearchBase.isEmpty()) ? 
-          groupSearchBase : searchBase;
-    }
-
-    public void setGroupSearchBase(String groupSearchBase) {
-      this.groupSearchBase = groupSearchBase;
-    }
-
-    public String getGroupObjectClass() {
-      return groupObjectClass;
-    }
-    
-    public void setGroupObjectClass(String groupObjectClassAttribute) {
-        this.groupObjectClass = groupObjectClassAttribute;
-    }
-
-    public String getMemberAttribute() {
-      return memberAttribute;
-    }
-    
-    public void setMemberAttribute(String memberAttribute) {
-        this.memberAttribute = memberAttribute;
-    }
-    
-    public String getGroupIdAttribute() {
-      return groupIdAttribute;
-    }
-    
-    public void setGroupIdAttribute(String groupIdAttribute) {
-        this.groupIdAttribute = groupIdAttribute;
-    }
-    
-    public void setMemberAttributeValueTemplate(String template) {
-        if (!StringUtils.hasText(template)) {
-            String msg = "User DN template cannot be null or empty.";
-            throw new IllegalArgumentException(msg);
-        }
-        int index = template.indexOf(MEMBER_SUBSTITUTION_TOKEN);
-        if (index < 0) {
-            String msg = "Member attribute value template must contain the '" +
-                    MEMBER_SUBSTITUTION_TOKEN + "' replacement token to understand how to " +
-                    "parse the group members.";
-            throw new IllegalArgumentException(msg);
-        }
-        String prefix = template.substring(0, index);
-        String suffix = template.substring(prefix.length() + MEMBER_SUBSTITUTION_TOKEN.length());
-        this.memberAttributeValuePrefix = prefix;
-        this.memberAttributeValueSuffix = suffix;
-    }
-
-    public void setRolesByGroup(Map<String, String> rolesByGroup) {
-        this.rolesByGroup.putAll(rolesByGroup);
-    }
-
-    public void setPermissionsByRole(String permissionsByRoleStr) {
-        permissionsByRole.putAll(parsePermissionByRoleString(permissionsByRoleStr));
-    }
-    
-    public boolean isAuthorizationEnabled() {
-      return authorizationEnabled;
-    }
-
-    public void setAuthorizationEnabled(boolean authorizationEnabled) {
-      this.authorizationEnabled = authorizationEnabled;
-    }
-
-    public String getUserSearchAttributeName() {
-        return userSearchAttributeName;
-    }
-
-    public void setUserSearchAttributeName(String userSearchAttributeName) {
-      if (userSearchAttributeName != null) {
-        userSearchAttributeName = userSearchAttributeName.trim();
-      }
-      this.userSearchAttributeName = userSearchAttributeName;
-    }
-
-    public String getUserObjectClass() {
-      return userObjectClass;
-    }
-    
-    public void setUserObjectClass(String userObjectClass) {
-        this.userObjectClass = userObjectClass;
-    }
-
-    private Map<String, List<String>> parsePermissionByRoleString(String permissionsByRoleStr) {
-      Map<String,List<String>> perms = new HashMap<>();
-   
-      // split by semicolon ; then by eq = then by  comma ,
-      StringTokenizer stSem = new StringTokenizer(permissionsByRoleStr, ";");
-      while (stSem.hasMoreTokens()) {
-        String roleAndPerm = stSem.nextToken();
-        StringTokenizer stEq = new StringTokenizer(roleAndPerm, "=");
-        if (stEq.countTokens() != 2) {
-          continue;
-        }
-        String role = stEq.nextToken().trim();
-        String perm = stEq.nextToken().trim();
-        StringTokenizer stCom = new StringTokenizer(perm, ",");
-        List<String> permList = new ArrayList<String>();
-        while (stCom.hasMoreTokens()) {
-          permList.add(stCom.nextToken().trim());
-        }
-        perms.put(role,  permList);
-      }
-      return perms;
-  }
-
-  boolean isUserMemberOfDynamicGroup(LdapName userLdapDn, String memberUrl,
-      final LdapContextFactory ldapContextFactory) throws NamingException {
-
-    // ldap://host:port/dn?attributes?scope?filter?extensions
-
-    boolean member = false;
-
-    if (memberUrl == null) {
-      return false;
-    }
-    String[] tokens = memberUrl.split("\\?");
-    if (tokens.length < 4) {
-      return false;
-    }
-
-    String searchBaseString = tokens[0]
-        .substring(tokens[0].lastIndexOf("/") + 1);
-    String searchScope = tokens[2];
-    String searchFilter = tokens[3];
-
-    LdapName searchBaseDn = new LdapName(searchBaseString);
-
-    // do scope test
-    if (searchScope.equalsIgnoreCase("base")) {
-      return false;
-    }
-    if (!userLdapDn.toString().endsWith(searchBaseDn.toString())) {
-      return false;
-    }
-    if (searchScope.equalsIgnoreCase("one")
-        && (userLdapDn.size() != searchBaseDn.size() - 1)) {
-      return false;
-    }
-    // search for the filter, substituting base with userDn
-    // search for base_dn=userDn, scope=base, filter=filter
-    LdapContext systemLdapCtx = null;
-    systemLdapCtx = ldapContextFactory.getSystemLdapContext();
-    NamingEnumeration<SearchResult> searchResultEnum = null;
-    try {
-      searchResultEnum = systemLdapCtx
-        .search(userLdapDn, searchFilter,
-            searchScope.equalsIgnoreCase("sub") ? SUBTREE_SCOPE
-                : ONELEVEL_SCOPE);
-      if (searchResultEnum.hasMore()) {
-        return true;
-      }
-    }
-    finally {
-        try {
-          if (searchResultEnum != null) {
-            searchResultEnum.close();
-          }
-        }
-        finally {
-          LdapUtils.closeContext(systemLdapCtx);
-        }
-    }
-    return member;
-  }
-
-  public String getPrincipalRegex() {
-    return principalRegex;
-  }
-
-  public void setPrincipalRegex( String regex ) {
-    if( regex == null || regex.trim().isEmpty() ) {
-      principalPattern = Pattern.compile( DEFAULT_PRINCIPAL_REGEX );
-      principalRegex = DEFAULT_PRINCIPAL_REGEX;
-    } else {
-      regex = regex.trim();
-      Pattern pattern = Pattern.compile( regex );
-      principalPattern = pattern;
-      principalRegex = regex;
-    }
-  }
-
-  public String getUserSearchAttributeTemplate() {
-    return userSearchAttributeTemplate;
-  }
-
-  public void setUserSearchAttributeTemplate( final String template ) {
-    this.userSearchAttributeTemplate = ( template == null ? null : template.trim() );
-  }
-
-  public String getUserSearchFilter() {
-    return userSearchFilter;
-  }
-
-  public void setUserSearchFilter( final String filter ) {
-    this.userSearchFilter = ( filter == null ? null : filter.trim() );
-  }
-
-  public String getUserSearchScope() {
-    return userSearchScope;
-  }
-
-  public void setUserSearchScope( final String scope ) {
-    this.userSearchScope = ( scope == null ? null : scope.trim().toLowerCase() );
-  }
-
-  private SearchControls getUserSearchControls() {
-    SearchControls searchControls = SUBTREE_SCOPE;
-    if ( "onelevel".equalsIgnoreCase( userSearchScope ) ) {
-      searchControls = ONELEVEL_SCOPE;
-    } else if ( "object".equalsIgnoreCase( userSearchScope ) ) {
-      searchControls = OBJECT_SCOPE;
-    }
-    return searchControls;
-  }
-
-  @Override
-  public void setUserDnTemplate( final String template ) throws IllegalArgumentException {
-    userDnTemplate = template;
-  }
-
-  private Matcher matchPrincipal( final String principal ) {
-    Matcher matchedPrincipal = principalPattern.matcher( principal );
-    if( !matchedPrincipal.matches() ) {
-      throw new IllegalArgumentException( "Principal " + principal + " does not match " + principalRegex );
-    }
-    return matchedPrincipal;
-  }
-
-  /**
-     * Returns the LDAP User Distinguished Name (DN) to use when acquiring an
-     * {@link javax.naming.ldap.LdapContext LdapContext} from the {@link LdapContextFactory}.
-     * <p/>
-     * If the the {@link #getUserDnTemplate() userDnTemplate} property has been set, this implementation will construct
-     * the User DN by substituting the specified {@code principal} into the configured template.  If the
-     * {@link #getUserDnTemplate() userDnTemplate} has not been set, the method argument will be returned directly
-     * (indicating that the submitted authentication token principal <em>is</em> the User DN).
-     *
-     * @param principal the principal to substitute into the configured {@link #getUserDnTemplate() userDnTemplate}.
-     * @return the constructed User DN to use at runtime when acquiring an {@link javax.naming.ldap.LdapContext}.
-     * @throws IllegalArgumentException if the method argument is null or empty
-     * @throws IllegalStateException    if the {@link #getUserDnTemplate userDnTemplate} has not been set.
-     * @see LdapContextFactory#getLdapContext(Object, Object)
-     */
-    @Override
-    protected String getUserDn( final String principal ) throws IllegalArgumentException, IllegalStateException {
-      String userDn;
-      Matcher matchedPrincipal = matchPrincipal( principal );
-      String userSearchBase = getUserSearchBase();
-      String userSearchAttributeName = getUserSearchAttributeName();
-
-      // If not searching use the userDnTemplate and return.
-      if ( ( userSearchBase == null || userSearchBase.isEmpty() ) ||
-          ( userSearchAttributeName == null &&
-              userSearchFilter == null &&
-              !"object".equalsIgnoreCase( userSearchScope ) ) ) {
-        userDn = expandTemplate( userDnTemplate, matchedPrincipal );
-        LOG.computedUserDn( userDn, principal );
-        return userDn;
-      }
-
-      // Create the searchBase and searchFilter from config.
-      String searchBase = expandTemplate( getUserSearchBase(), matchedPrincipal );
-      String searchFilter = null;
-      if ( userSearchFilter == null ) {
-        if ( userSearchAttributeName == null ) {
-          searchFilter = String.format( "(objectclass=%1$s)", getUserObjectClass() );
-        } else {
-          searchFilter = String.format(
-              "(&(objectclass=%1$s)(%2$s=%3$s))",
-              getUserObjectClass(),
-              userSearchAttributeName,
-              expandTemplate( getUserSearchAttributeTemplate(), matchedPrincipal ) );
-        }
-      } else {
-        searchFilter = expandTemplate( userSearchFilter, matchedPrincipal );
-      }
-      SearchControls searchControls = getUserSearchControls();
-
-      // Search for userDn and return.
-      LdapContext systemLdapCtx = null;
-      NamingEnumeration<SearchResult> searchResultEnum = null;
-      try {
-        systemLdapCtx = getContextFactory().getSystemLdapContext();
-        LOG.searchBaseFilterScope(searchBase, searchFilter, userSearchScope);
-        searchResultEnum = systemLdapCtx.search( searchBase, searchFilter, searchControls );
-        // SearchResults contains all the entries in search scope
-        if (searchResultEnum.hasMore()) {
-          SearchResult searchResult = searchResultEnum.next();
-          userDn = searchResult.getNameInNamespace();
-          LOG.searchedAndFoundUserDn(userDn, principal);
-          return userDn;
-        } else {
-          throw new IllegalArgumentException("Illegal principal name: " + principal);
-        }
-      } catch (AuthenticationException e) {
-        LOG.failedToGetSystemLdapConnection(e);
-        throw new IllegalArgumentException("Illegal principal name: " + principal);
-      } catch (NamingException e) {
-        throw new IllegalArgumentException("Hit NamingException: " + e.getMessage());
-      } finally {
-        try {
-          if (searchResultEnum != null) {
-            searchResultEnum.close();
-          }
-        } catch (NamingException e) {
-          // Ignore exception on close.
-        }
-        finally {
-          LdapUtils.closeContext(systemLdapCtx);
-        }
-      }
-    }
-
-    @Override
-    protected AuthenticationInfo createAuthenticationInfo(AuthenticationToken token, Object ldapPrincipal, Object ldapCredentials, LdapContext ldapContext) throws NamingException {
-      HashRequest.Builder builder = new HashRequest.Builder();
-      Hash credentialsHash = hashService.computeHash(builder.setSource(token.getCredentials()).setAlgorithmName(HASHING_ALGORITHM).build());
-      return new SimpleAuthenticationInfo(token.getPrincipal(), credentialsHash.toHex(), credentialsHash.getSalt(), getName());
-    }
-
-  private static final String expandTemplate( final String template, final Matcher input ) {
-    String output = template;
-    Matcher matcher = TEMPLATE_PATTERN.matcher( output );
-    while( matcher.find() ) {
-      String lookupStr = matcher.group( 1 );
-      int lookupIndex = Integer.parseInt( lookupStr );
-      String lookupValue = input.group( lookupIndex );
-      output = matcher.replaceFirst( lookupValue == null ? "" : lookupValue );
-      matcher = TEMPLATE_PATTERN.matcher( output );
-    }
-    return output;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxPamRealm.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxPamRealm.java b/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxPamRealm.java
deleted file mode 100644
index 45cdd45..0000000
--- a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxPamRealm.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- *  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.hadoop.gateway.shirorealm;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-import org.apache.hadoop.gateway.GatewayMessages;
-import org.apache.hadoop.gateway.audit.api.Action;
-import org.apache.hadoop.gateway.audit.api.ActionOutcome;
-import org.apache.hadoop.gateway.audit.api.ResourceType;
-import org.apache.hadoop.gateway.audit.api.AuditService;
-import org.apache.hadoop.gateway.audit.api.AuditServiceFactory;
-import org.apache.hadoop.gateway.audit.api.Auditor;
-import org.apache.hadoop.gateway.audit.log4j.audit.AuditConstants;
-import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
-import org.apache.hadoop.gateway.shirorealm.impl.i18n.KnoxShiroMessages;
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.authc.AuthenticationException;
-
-import org.apache.shiro.authc.AuthenticationInfo;
-import org.apache.shiro.authc.AuthenticationToken;
-import org.apache.shiro.authc.SimpleAuthenticationInfo;
-import org.apache.shiro.authc.UsernamePasswordToken;
-import org.apache.shiro.authz.AuthorizationInfo;
-import org.apache.shiro.authz.SimpleAuthorizationInfo;
-import org.apache.shiro.realm.AuthorizingRealm;
-import org.apache.shiro.subject.PrincipalCollection;
-import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
-import org.apache.shiro.crypto.hash.*;
-import org.jvnet.libpam.PAM;
-import org.jvnet.libpam.PAMException;
-import org.jvnet.libpam.UnixUser;
-
-/**
- * A Unix-style
- * <a href="http://www.kernel.org/pub/linux/libs/pam/index.html">PAM</a>
- * {@link org.apache.shiro.realm.Realm Realm} that uses
- * <a href="https://github.com/kohsuke/libpam4j">libpam4j</a> to interface with
- * the PAM system libraries.
- * <p>
- * This is a single Shiro {@code Realm} that interfaces with the OS's
- * {@code PAM} subsystem which itself can be connected to several authentication
- * methods (unix-crypt,Samba, LDAP, etc.)
- * <p>
- * This {@code Realm} can also take part in Shiro's Pluggable Realms concept.
- * <p>
- * Using a {@code KnoxPamRealm} requires a PAM {@code service} name. This is the
- * name of the file under {@code /etc/pam.d} that is used to initialise and
- * configure the PAM subsytem. Normally, this file reflects the application
- * using it. For example {@code gdm}, {@code su}, etc. There is no default value
- * for this propery.
- * <p>
- * For example, defining this realm in Shiro .ini:
- *
- * <pre>
- * [main]
- * pamRealm = org.apache.shiro.realm.libpam4j.KnoxPamRealm
- * pamRealm.service = [ knox-pam-ldap-service | knox-pam-os-service | knox-pam-winbind-service ]
- * [urls]
- * **=authcBasic
- * </pre>
- *
- */
-
-public class KnoxPamRealm extends AuthorizingRealm {
-  private static final String HASHING_ALGORITHM = "SHA-256";
-  private static final String SUBJECT_USER_ROLES = "subject.userRoles";
-  private static final String SUBJECT_USER_GROUPS = "subject.userGroups";
-  private HashService hashService = new DefaultHashService();
-  KnoxShiroMessages ShiroLog = MessagesFactory.get(KnoxShiroMessages.class);
-  GatewayMessages GatewayLog = MessagesFactory.get(GatewayMessages.class);
-  private static AuditService auditService = AuditServiceFactory.getAuditService();
-  private static Auditor auditor = auditService.getAuditor(AuditConstants.DEFAULT_AUDITOR_NAME,
-      AuditConstants.KNOX_SERVICE_NAME, AuditConstants.KNOX_COMPONENT_NAME);
-
-  private String service;
-
-  public KnoxPamRealm() {
-    HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(HASHING_ALGORITHM);
-    setCredentialsMatcher(credentialsMatcher);
-  }
-
-  public void setService(String service) {
-    this.service = service;
-  }
-
-  public String getService() {
-    return this.service;
-  }
-
-  @Override
-  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
-    Set<String> roles = new LinkedHashSet<String>();
-
-    UnixUserPrincipal user = principals.oneByType(UnixUserPrincipal.class);
-    if (user != null) {
-      roles.addAll(user.getUnixUser().getGroups());
-    }
-    SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_ROLES, roles);
-    SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_GROUPS, roles);
-
-    /* Coverity Scan CID 1361682 */
-    String userName = null;
-
-    if (user != null) {
-      userName = user.getName();
-    }
-
-    GatewayLog.lookedUpUserRoles(roles, userName);
-    return new SimpleAuthorizationInfo(roles);
-  }
-
-  @Override
-  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
-    UsernamePasswordToken upToken = (UsernamePasswordToken) token;
-    UnixUser user = null;
-    try {
-      user = (new PAM(this.getService())).authenticate(upToken.getUsername(), new String(upToken.getPassword()));
-    } catch (PAMException e) {
-      handleAuthFailure(token, e.getMessage(), e);
-    }
-    HashRequest.Builder builder = new HashRequest.Builder();
-    Hash credentialsHash = hashService
-        .computeHash(builder.setSource(token.getCredentials()).setAlgorithmName(HASHING_ALGORITHM).build());
-    /* Coverity Scan CID 1361684 */
-    if (credentialsHash == null) {
-      handleAuthFailure(token, "Failed to compute hash", null);
-    }
-    return new SimpleAuthenticationInfo(new UnixUserPrincipal(user), credentialsHash.toHex(), credentialsHash.getSalt(),
-        getName());
-  }
-
-  private void handleAuthFailure(AuthenticationToken token, String errorMessage, Exception e) {
-    auditor.audit(Action.AUTHENTICATION, token.getPrincipal().toString(), ResourceType.PRINCIPAL, ActionOutcome.FAILURE,
-        errorMessage);
-    ShiroLog.failedLoginInfo(token);
-
-    if (e != null) {
-      ShiroLog.failedLoginAttempt(e.getCause());
-      throw new AuthenticationException(e);
-    }
-
-    throw new AuthenticationException(errorMessage);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/UnixUserPrincipal.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/UnixUserPrincipal.java b/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/UnixUserPrincipal.java
deleted file mode 100644
index a659888..0000000
--- a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/UnixUserPrincipal.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  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.hadoop.gateway.shirorealm;
-
-import java.security.Principal;
-import org.jvnet.libpam.UnixUser;
-
-public class UnixUserPrincipal implements Principal {
-	private final UnixUser userName;
-
-	public UnixUserPrincipal(UnixUser userName) {
-		this.userName = userName;
-	}
-
-	@Override
-	public String getName() {
-		return userName.getUserName();
-	}
-
-	public UnixUser getUnixUser() {
-		return userName;
-	}
-
-	@Override
-	public String toString() {
-		return String.valueOf(userName.getUserName());
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/impl/i18n/KnoxShiroMessages.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/impl/i18n/KnoxShiroMessages.java b/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/impl/i18n/KnoxShiroMessages.java
deleted file mode 100644
index c9de024..0000000
--- a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/impl/i18n/KnoxShiroMessages.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * 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.hadoop.gateway.shirorealm.impl.i18n;
-
-import org.apache.hadoop.gateway.i18n.messages.Message;
-import org.apache.hadoop.gateway.i18n.messages.MessageLevel;
-import org.apache.hadoop.gateway.i18n.messages.Messages;
-
-import org.apache.hadoop.gateway.i18n.messages.StackTrace;
-import org.apache.shiro.authc.AuthenticationToken;
-import org.apache.shiro.subject.Subject;
-
-@Messages(logger = "org.apache.hadoop.gateway")
-public interface KnoxShiroMessages {
-
-  @Message(level = MessageLevel.ERROR, text = "Shiro unable to login: {0}")
-  void failedLoginAttempt(Throwable e);
-
-  @Message(level = MessageLevel.INFO, text = "Could not login: {0}")
-  void failedLoginInfo(AuthenticationToken token);
-
-  @Message( level = MessageLevel.DEBUG, text = "Failed to Authenticate with LDAP server: {1}" )
-  void failedLoginStackTrace( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
-
-  @Message(level = MessageLevel.INFO, text = "Successfully logged in: {0}, {1}")
-  void successfulLoginAttempt(Subject subject, AuthenticationToken authToken);
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/deploy/impl/ShiroConfig.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/deploy/impl/ShiroConfig.java b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/deploy/impl/ShiroConfig.java
new file mode 100644
index 0000000..4049a93
--- /dev/null
+++ b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/deploy/impl/ShiroConfig.java
@@ -0,0 +1,71 @@
+/**
+ * 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.knox.gateway.deploy.impl;
+
+import org.apache.knox.gateway.topology.Provider;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class ShiroConfig {
+  
+  private Map<String, Map<String, String>> sections = new LinkedHashMap<String, Map<String, String>>();
+ 
+  public ShiroConfig(Provider provider, String clusterName) {
+    Map<String, String> params = provider.getParams();
+    String name = null;
+    String sectionName = null;
+    String value = null;
+    for(Entry<String, String> entry : params.entrySet()) {
+      int sectionDot = entry.getKey().indexOf('.');
+      if (sectionDot > 0) {
+        sectionName = entry.getKey().substring(0, sectionDot);
+        name = entry.getKey().substring(sectionDot + 1);
+        value = entry.getValue().trim();
+        if (value.startsWith("${ALIAS=") && value.endsWith("}")) {
+          String baseName = name.substring(0, name.lastIndexOf("."));
+          addNameValueToSection(baseName + ".clusterName", clusterName, sectionName);
+          addNameValueToSection(name, "S" + value.substring(1), sectionName);
+        } else {
+          addNameValueToSection(name, value, sectionName);
+        }
+      }
+    }
+  }
+
+  private void addNameValueToSection(String name, String value, String sectionName) {
+    Map<String, String> section = sections.get(sectionName);
+    if (section == null) {
+      section = new LinkedHashMap<String, String>();
+      sections.put(sectionName, section);
+    }
+    section.put(name, value);
+  }
+  
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    for(Entry<String, Map<String, String>> section : sections.entrySet()) {
+      sb.append("[").append(section.getKey()).append("]\n");
+      for(Entry<String, String> entry : section.getValue().entrySet()) {
+        sb.append(entry.getKey()).append("=").append(entry.getValue()).append("\n");
+      }
+    }
+    return sb.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/deploy/impl/ShiroDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/deploy/impl/ShiroDeploymentContributor.java b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/deploy/impl/ShiroDeploymentContributor.java
new file mode 100644
index 0000000..111b13b
--- /dev/null
+++ b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/deploy/impl/ShiroDeploymentContributor.java
@@ -0,0 +1,140 @@
+/**
+ * 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.knox.gateway.deploy.impl;
+
+import org.apache.knox.gateway.deploy.DeploymentContext;
+import org.apache.knox.gateway.deploy.ProviderDeploymentContributorBase;
+import org.apache.knox.gateway.descriptor.FilterParamDescriptor;
+import org.apache.knox.gateway.descriptor.ResourceDescriptor;
+import org.apache.knox.gateway.filter.RedirectToUrlFilter;
+import org.apache.knox.gateway.filter.ResponseCookieFilter;
+import org.apache.knox.gateway.topology.Provider;
+import org.apache.knox.gateway.topology.Service;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.descriptor.api.webapp30.WebAppDescriptor;
+import org.jboss.shrinkwrap.descriptor.api.webcommon30.SessionConfigType;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class ShiroDeploymentContributor extends ProviderDeploymentContributorBase {
+
+  private static final String LISTENER_CLASSNAME = "org.apache.shiro.web.env.EnvironmentLoaderListener";
+  private static final String SHIRO_FILTER_CLASSNAME = "org.apache.shiro.web.servlet.ShiroFilter";
+  private static final String POST_FILTER_CLASSNAME = "ShiroSubjectIdentityAdapter";
+  private static final String COOKIE_FILTER_CLASSNAME = "ResponseCookieFilter";
+  private static final String REDIRECT_FILTER_CLASSNAME = "RedirectToUrlFilter";
+  private static final String SESSION_TIMEOUT = "sessionTimeout";
+  private static final String REMEMBER_ME = "rememberme";
+  private static final String SHRIO_CONFIG_FILE_NAME = "shiro.ini";
+  private static final int DEFAULT_SESSION_TIMEOUT = 30; // 30min
+
+  @Override
+  public String getRole() {
+    return "authentication";
+  }
+
+  @Override
+  public String getName() {
+    return "ShiroProvider";
+  }
+
+  @Override
+  public void contributeProvider( DeploymentContext context, Provider provider ) {
+    // Many filter based authentication mechanisms require a ServletContextListener
+    // to be added and the Knox deployment machinery provides the ability to add this
+    // through the DeploymentContext.
+
+    // Writing provider specific config out to the war for cluster specific config can be
+    // accomplished through the DeploymentContext as well. The JBoss shrinkwrap API can be
+    // used to write the asset to the war.
+
+    // add servletContextListener
+    context.getWebAppDescriptor().createListener().listenerClass( LISTENER_CLASSNAME );
+
+    // add session timeout
+    int st = DEFAULT_SESSION_TIMEOUT;
+    SessionConfigType<WebAppDescriptor> sessionConfig = context.getWebAppDescriptor().createSessionConfig();
+    Map<String, String> params = provider.getParams();
+    String sts = params.get( SESSION_TIMEOUT );
+    if( sts != null && sts.trim().length() != 0 ) {
+      st = Integer.parseInt( sts.trim() );
+    }
+    if( st <= 0 ) {
+      // user default session timeout
+      st = DEFAULT_SESSION_TIMEOUT;
+    }
+    sessionConfig.sessionTimeout( st );
+    sessionConfig.getOrCreateCookieConfig().httpOnly( true );
+    sessionConfig.getOrCreateCookieConfig().secure( true );
+
+    String clusterName = context.getTopology().getName();
+    ShiroConfig config = new ShiroConfig( provider, clusterName );
+    String configStr = config.toString();
+    if( config != null ) {
+      context.getWebArchive().addAsWebInfResource( new StringAsset( configStr ), SHRIO_CONFIG_FILE_NAME );
+    }
+  }
+
+  @Override
+  public void contributeFilter( DeploymentContext context, Provider provider,
+      Service service, ResourceDescriptor resource, List<FilterParamDescriptor> params ) {
+    // Leveraging a third party filter is a primary usecase for Knox
+    // in order to do so, we need to make sure that the end result of the third party integration
+    // puts a standard javax.security.auth.Subject on the current thread through a doAs.
+    // As many filters do not use the standard java Subject, often times a post processing filter will
+    // need to be added in order to canonicalize the result into an expected security context.
+
+    // You may also need to do some additional processing of the response in order to not return cookies or other
+    // filter specifics that are not needed for integration with Knox. Below we do that in the pre-processing filter.
+    if (params == null) {
+      params = new ArrayList<FilterParamDescriptor>();
+    }
+    Map<String, String> providerParams = provider.getParams();
+    String redirectToUrl = providerParams.get(RedirectToUrlFilter.REDIRECT_TO_URL);
+    if (redirectToUrl != null) {
+      params.add( resource.createFilterParam()
+          .name(RedirectToUrlFilter.REDIRECT_TO_URL)
+          .value(redirectToUrl));
+      resource.addFilter().name( "Redirect" + getName() ).role(
+          getRole() ).impl( REDIRECT_FILTER_CLASSNAME ).params( params );
+      params.clear();
+    }
+
+    String cookies = providerParams.get( ResponseCookieFilter.RESTRICTED_COOKIES );
+    if (cookies == null) {
+      params.add( resource.createFilterParam()
+          .name( ResponseCookieFilter.RESTRICTED_COOKIES )
+          .value( REMEMBER_ME ) );
+    }
+    else {
+      params.add( resource.createFilterParam()
+          .name(ResponseCookieFilter.RESTRICTED_COOKIES ).value( cookies ) );
+    }
+
+    resource.addFilter().name( "Pre" + getName() ).role(
+        getRole() ).impl( COOKIE_FILTER_CLASSNAME ).params( params );
+    params.clear();
+
+    resource.addFilter().name( getName() ).role(
+        getRole() ).impl( SHIRO_FILTER_CLASSNAME ).params( params );
+    resource.addFilter().name( "Post" + getName() ).role(
+        getRole() ).impl( POST_FILTER_CLASSNAME ).params( params );
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/RedirectToUrlFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/RedirectToUrlFilter.java b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/RedirectToUrlFilter.java
new file mode 100644
index 0000000..2ecdd85
--- /dev/null
+++ b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/RedirectToUrlFilter.java
@@ -0,0 +1,52 @@
+/**
+ * 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.knox.gateway.filter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class RedirectToUrlFilter extends AbstractGatewayFilter {
+  public static final String REDIRECT_TO_URL = "redirectToUrl";
+
+  protected String redirectUrl = null;
+
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {
+    super.init(filterConfig);
+    redirectUrl = filterConfig.getInitParameter(REDIRECT_TO_URL);
+  }
+
+  @Override
+  protected void doFilter( HttpServletRequest request,
+      HttpServletResponse response, FilterChain chain ) throws IOException, ServletException {
+    if (redirectUrl != null && request.getHeader("Authorization") == null) {
+      response.sendRedirect(redirectUrl + getOriginalQueryString(request));
+    }
+    chain.doFilter( request, response );
+  }
+
+  private String getOriginalQueryString(HttpServletRequest request) {
+    String originalQueryString = request.getQueryString();
+    return (originalQueryString == null) ? "" : "?" + originalQueryString;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/ResponseCookieFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/ResponseCookieFilter.java b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/ResponseCookieFilter.java
new file mode 100644
index 0000000..9ea9302
--- /dev/null
+++ b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/ResponseCookieFilter.java
@@ -0,0 +1,88 @@
+/**
+ * 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.knox.gateway.filter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ResponseCookieFilter extends AbstractGatewayFilter {
+  public static final String RESTRICTED_COOKIES = "restrictedCookies";
+
+  protected static List<String> restrictedCookies = new ArrayList<String>();
+
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {
+    super.init(filterConfig);
+    String cookies = filterConfig.getInitParameter(RESTRICTED_COOKIES);
+    if (cookies != null) {
+      restrictedCookies = Arrays.asList(cookies.split(","));
+    }
+  }
+
+  @Override
+  protected void doFilter( HttpServletRequest request, HttpServletResponse response, FilterChain chain ) throws IOException, ServletException {
+    ResponseWrapper responseWrapper = new ResponseWrapper( response );
+    chain.doFilter( request, responseWrapper );
+  }
+
+  // inner class wraps response to prevent adding of not allowed headers
+  private static class ResponseWrapper extends HttpServletResponseWrapper {
+    public ResponseWrapper( HttpServletResponse response ) {
+      super( response );
+    }
+
+    public void addCookie( Cookie cookie ) {
+      if( cookie != null && isAllowedHeader( cookie.getName() ) ) {
+        super.addCookie( cookie );
+      }
+    }
+
+    public void setHeader( String name, String value ) {
+      if( isAllowedHeader( name ) ) {
+        super.setHeader( name, value );
+      }
+    }
+
+    public void addHeader( String name, String value ) {
+      if( isAllowedHeader( name ) ) {
+        super.addHeader( name, value );
+      }
+    }
+
+    private boolean isAllowedHeader( String value ) {
+      if( value != null ) {
+        for( String v : restrictedCookies ) {
+          if( value.contains( v ) ) {
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/ShiroSubjectIdentityAdapter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/ShiroSubjectIdentityAdapter.java b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/ShiroSubjectIdentityAdapter.java
new file mode 100644
index 0000000..6fb1340
--- /dev/null
+++ b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/ShiroSubjectIdentityAdapter.java
@@ -0,0 +1,150 @@
+/**
+ * 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.knox.gateway.filter;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.apache.knox.gateway.audit.api.Action;
+import org.apache.knox.gateway.audit.api.ActionOutcome;
+import org.apache.knox.gateway.audit.api.AuditService;
+import org.apache.knox.gateway.audit.api.AuditServiceFactory;
+import org.apache.knox.gateway.audit.api.Auditor;
+import org.apache.knox.gateway.audit.api.ResourceType;
+import org.apache.knox.gateway.audit.log4j.audit.AuditConstants;
+import org.apache.knox.gateway.security.GroupPrincipal;
+import org.apache.knox.gateway.security.PrimaryPrincipal;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+
+public class ShiroSubjectIdentityAdapter implements Filter {
+  
+  private static final String SUBJECT_USER_GROUPS = "subject.userGroups";
+  private static AuditService auditService = AuditServiceFactory.getAuditService();
+  private static Auditor auditor = auditService.getAuditor(
+      AuditConstants.DEFAULT_AUDITOR_NAME, AuditConstants.KNOX_SERVICE_NAME,
+      AuditConstants.KNOX_COMPONENT_NAME );
+  
+
+  @Override
+  public void init( FilterConfig filterConfig ) throws ServletException {
+  }
+
+  public void destroy() {
+  }
+
+  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
+      throws IOException, ServletException {
+    
+    Subject subject = SecurityUtils.getSubject();
+    
+    // trigger call to shiro authorization realm
+    // we use shiro authorization realm to look up groups
+    subject.hasRole("authenticatedUser");
+
+    CallableChain callableChain = new CallableChain(request, response, chain);
+    SecurityUtils.getSubject().execute(callableChain);
+  }
+  
+  private static class CallableChain implements Callable<Void> {
+    private FilterChain chain = null;
+    ServletRequest request = null;
+    ServletResponse response = null;
+    
+    CallableChain(ServletRequest request, ServletResponse response, FilterChain chain) {
+      this.request = request;
+      this.response = response;
+      this.chain = chain;
+    }
+
+    @Override
+    public Void call() throws Exception {
+      PrivilegedExceptionAction<Void> action = new PrivilegedExceptionAction<Void>() {
+        @Override
+        public Void run() throws Exception {
+          chain.doFilter( request, response );
+          return null;
+        }
+      };
+      Subject shiroSubject = SecurityUtils.getSubject();
+
+      if (shiroSubject == null || shiroSubject.getPrincipal() == null) {
+        throw new IllegalStateException("Unable to determine authenticated user from Shiro, please check that your Knox Shiro configuration is correct");
+      }
+
+      final String principal = (String) shiroSubject.getPrincipal().toString();
+      HashSet emptySet = new HashSet();
+      Set<Principal> principals = new HashSet<>();
+      Principal p = new PrimaryPrincipal(principal);
+      principals.add(p);
+      auditService.getContext().setUsername( principal ); //KM: Audit Fix
+      String sourceUri = (String)request.getAttribute( AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME );
+      auditor.audit( Action.AUTHENTICATION , sourceUri, ResourceType.URI, ActionOutcome.SUCCESS );
+
+      Set<String> userGroups = null;
+      // map ldap groups saved in session to Java Subject GroupPrincipal(s)
+      if (SecurityUtils.getSubject().getSession().getAttribute(SUBJECT_USER_GROUPS) != null) {
+        userGroups = (Set<String>)SecurityUtils.getSubject().getSession().getAttribute(SUBJECT_USER_GROUPS);
+      } else { // KnoxLdapRealm case
+        if(  shiroSubject.getPrincipal() instanceof String ) { 
+           userGroups = new HashSet<>(shiroSubject.getPrincipals().asSet());
+           userGroups.remove(principal);
+        } else { // KnoxPamRealm case
+           Set<Principal> shiroPrincipals = new HashSet<>(shiroSubject.getPrincipals().asSet());
+           userGroups = new HashSet<>(); // Here we are creating a new UserGroup
+                                               // so we don't need to remove a Principal
+                                               // In the case of LDAP the userGroup may have already Principal
+                                               // added to the list of groups, so it is not needed.
+           for( Principal shiroPrincipal: shiroPrincipals ) {
+                userGroups.add(shiroPrincipal.toString() );
+           }
+        }
+      }
+      for (String userGroup : userGroups) {
+        Principal gp = new GroupPrincipal(userGroup);
+        principals.add(gp);
+      }
+      auditor.audit( Action.AUTHENTICATION , sourceUri, ResourceType.URI, ActionOutcome.SUCCESS, "Groups: " + userGroups );
+      
+//      The newly constructed Sets check whether this Subject has been set read-only 
+//      before permitting subsequent modifications. The newly created Sets also prevent 
+//      illegal modifications by ensuring that callers have sufficient permissions.
+//
+//      To modify the Principals Set, the caller must have AuthPermission("modifyPrincipals"). 
+//      To modify the public credential Set, the caller must have AuthPermission("modifyPublicCredentials"). 
+//      To modify the private credential Set, the caller must have AuthPermission("modifyPrivateCredentials").
+      javax.security.auth.Subject subject = new javax.security.auth.Subject(true, principals, emptySet, emptySet);
+      javax.security.auth.Subject.doAs( subject, action );
+      
+      return null;
+    }
+    
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/shirorealm/KnoxCacheManager.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/shirorealm/KnoxCacheManager.java b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/shirorealm/KnoxCacheManager.java
new file mode 100644
index 0000000..123d16e
--- /dev/null
+++ b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/shirorealm/KnoxCacheManager.java
@@ -0,0 +1,27 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.knox.gateway.shirorealm;
+
+import org.apache.shiro.cache.ehcache.EhCacheManager;
+
+public class KnoxCacheManager extends EhCacheManager {
+
+  public KnoxCacheManager() {
+    setCacheManager(net.sf.ehcache.CacheManager.create());
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/shirorealm/KnoxLdapContextFactory.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/shirorealm/KnoxLdapContextFactory.java b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/shirorealm/KnoxLdapContextFactory.java
new file mode 100644
index 0000000..aa28594
--- /dev/null
+++ b/gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/shirorealm/KnoxLdapContextFactory.java
@@ -0,0 +1,125 @@
+/*
+ *  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.knox.gateway.shirorealm;
+
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.knox.gateway.GatewayMessages;
+import org.apache.knox.gateway.GatewayServer;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.AliasServiceException;
+import org.apache.shiro.realm.ldap.JndiLdapContextFactory;
+
+/**
+ * An extension of {@link JndiLdapContextFactory} that allows a different authentication mechanism
+ * for system-level authentications (as used by authorization lookups, for example)
+ * compared to regular authentication.
+ * 
+ * <p>
+ * See {@link IsisLdapRealm} for typical configuration within <tt>shiro.ini</tt>.
+ */
+public class KnoxLdapContextFactory extends JndiLdapContextFactory {
+
+    private static GatewayMessages LOG = MessagesFactory.get( GatewayMessages.class );
+  
+    private String systemAuthenticationMechanism = "simple";
+    private String clusterName = "";
+
+    public KnoxLdapContextFactory() {
+      setAuthenticationMechanism("simple");
+    }
+    
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Override
+    protected LdapContext createLdapContext(Hashtable env) throws NamingException {
+        if(getSystemUsername() != null && getSystemUsername().equals(env.get(Context.SECURITY_PRINCIPAL))) {
+            env.put(Context.SECURITY_AUTHENTICATION, getSystemAuthenticationMechanism());
+        }
+        return super.createLdapContext(env);
+    }
+
+    public String getSystemAuthenticationMechanism() {
+        return systemAuthenticationMechanism != null? systemAuthenticationMechanism: getAuthenticationMechanism();
+    }
+    
+    public void setSystemAuthenticationMechanism(String systemAuthenticationMechanism) {
+        this.systemAuthenticationMechanism = systemAuthenticationMechanism;
+    }
+    
+    @Override
+    public void setSystemPassword(String systemPass) {
+     
+      if ( systemPass == null ) {
+        return;
+      }
+      
+      systemPass = systemPass.trim();
+      if (systemPass.length() == 0) {
+        return;
+      }
+      
+      if (!systemPass.startsWith("S{ALIAS=")) {
+        super.setSystemPassword( systemPass );
+        return;
+      }
+      
+      systemPass= systemPass.substring( "S{ALIAS=".length(), systemPass.length() - 1 );
+      String aliasName = systemPass;
+      
+      GatewayServices services = GatewayServer.getGatewayServices();
+      AliasService aliasService = (AliasService)services.getService(GatewayServices.ALIAS_SERVICE);
+      
+      String clusterName = getClusterName();
+      //System.err.println("FACTORY systempass 30: " + systemPass);
+      //System.err.println("FACTORY clustername 40: " + clusterName);
+      //System.err.println("FACTORY SystemProperty GatewayHome 50: " + System.getProperty(GatewayConfig.GATEWAY_HOME_VAR));
+      char[] password = null;
+      try {
+        password = aliasService.getPasswordFromAliasForCluster(clusterName, systemPass);
+      } catch (AliasServiceException e) {
+        LOG.unableToGetPassword(e);
+      }
+      //System.err.println("FACTORY password: " + ((password == null) ? "NULL" : new String(password)));
+      if ( password != null ) {
+        //System.err.println("FACTORY SUCCESS 20 system password :" + new String(password));
+        super.setSystemPassword( new String(password) );
+      } else {
+        //System.err.println("FACTORY FORCING system password to blank");
+        super.setSystemPassword("" );
+        LOG.aliasValueNotFound(clusterName, aliasName);
+      }
+    }
+    
+    public String getClusterName() {
+      return clusterName;
+    }
+
+    public void setClusterName(String clusterName) {
+      if (clusterName != null) {
+        this.clusterName = clusterName.trim();
+      }
+    }
+    
+}
\ No newline at end of file