Initial Contribution

Signed-off-by: Vinay Vishal <vinay.vishal@oracle.com>
diff --git a/nucleus/security/core/exclude.xml b/nucleus/security/core/exclude.xml
new file mode 100644
index 0000000..25744ca
--- /dev/null
+++ b/nucleus/security/core/exclude.xml
@@ -0,0 +1,46 @@
+<!--
+
+    Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<FindBugsFilter>
+    <!--
+        Need to keep both method getUsername in
+        com.sun.appserv.security.AppservPasswordLoginModule
+        and method getUserName in
+        com.sun.enterprise.security.GUILoginDialog
+        with names differing only in case, for compatibility.
+    -->
+    <Match>
+        <Class name="com.sun.appserv.security.AppservPasswordLoginModule"/>
+        <Method name="getUsername"/>
+        <Bug pattern="NM_CONFUSING"/>
+    </Match>
+
+    <!--
+        These public fields of SecurityContext are set and read by code in
+	other modules.
+    -->
+    <Match>
+        <Class name="com.sun.enterprise.common.iiop.security.SecurityContext"/>
+	<Or>
+	    <Field name="authcls"/>
+	    <Field name="identcls"/>
+	    <Field name="subject"/>
+	</Or>
+        <Bug pattern="UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD"/>
+    </Match>
+</FindBugsFilter>
diff --git a/nucleus/security/core/osgi.bundle b/nucleus/security/core/osgi.bundle
new file mode 100644
index 0000000..4624464
--- /dev/null
+++ b/nucleus/security/core/osgi.bundle
@@ -0,0 +1,48 @@
+#
+# Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+-exportcontents: \
+                        com.iplanet.ias.security.auth.login; \
+                        com.sun.enterprise.security; \
+                        com.sun.enterprise.security.auth; \
+                        com.sun.enterprise.security.audit; \
+                        com.sun.enterprise.security.auth.login; \
+                        com.sun.enterprise.security.factory; \
+                        com.iplanet.ias.security.auth.realm; \
+                        com.sun.enterprise.security.auth.realm; \
+                        com.sun.enterprise.security.auth.realm.certificate; \
+                        com.sun.enterprise.security.auth.realm.file; \
+                        com.sun.enterprise.security.auth.realm.ldap; \
+                        com.sun.enterprise.security.auth.realm.solaris; \
+                        com.sun.enterprise.security.util; \
+                        com.sun.enterprise.common.iiop.security; \
+                        com.sun.enterprise.security.auth.digest.api; \
+                        com.sun.enterprise.security.auth.login.common; \
+                        com.sun.enterprise.security.common; \
+                        com.sun.logging.enterprise.system.core.security; \
+                        com.sun.enterprise.security.ssl; version=${project.osgi.version}
+Bundle-NativeCode: \
+        libsolsparcauth.so ; \
+        osname=SunOS ; \
+        osname=Solaris ; \
+        processor=sparc , \
+        libsolx86auth.so ; \
+        osname=SunOS ; \
+        osname=Solaris ; \
+        processor=x86 , \
+        *
+# dependent flashlight package resolved at runtime
+DynamicImport-Package: org.glassfish.flashlight.provider
diff --git a/nucleus/security/core/pom.xml b/nucleus/security/core/pom.xml
new file mode 100644
index 0000000..c541dc5
--- /dev/null
+++ b/nucleus/security/core/pom.xml
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.glassfish.main.security</groupId>
+        <artifactId>nucleus-security</artifactId>
+        <version>5.0.1-SNAPSHOT</version>
+    </parent>
+    <artifactId>security</artifactId>
+    <packaging>glassfish-jar</packaging>
+
+    <name>Security Core Classes</name>
+
+    <developers>
+        <developer>
+            <id>kumarjayanti</id>
+            <name>V B Kumar Jayanti</name>
+            <organization>Oracle, Inc.</organization>
+            <roles>
+                <role>developer</role>
+            </roles>
+        </developer>
+        <developer>
+            <id>nitkal</id>
+            <name>Nithya Subramanian</name>
+            <organization>Oracle, Inc.</organization>
+            <roles>
+                <role>developer</role>
+            </roles>
+        </developer>
+    </developers>
+
+    <properties>
+        <findbugs.exclude>${project.basedir}/exclude.xml</findbugs.exclude>
+    </properties>
+
+    <build>
+        <sourceDirectory>src/main/java</sourceDirectory>
+        <resources>
+            <resource>
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                </includes>
+            </resource>
+             <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                </includes>
+            </resource>
+             <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/*.1</include>
+                </includes>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/admin-keyfile</include>
+                </includes>
+            </resource>
+             <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/keyfile</include>
+                </includes>
+            </resource>
+             <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/*.jks</include>
+                </includes>
+            </resource>
+             <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/secure.seed</include>
+                </includes>
+            </resource>
+             <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/server.policy</include>
+                </includes>
+            </resource>
+             <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/login.conf</include>
+                </includes>
+            </resource>
+        </resources>
+        <plugins>
+           <plugin>
+           <groupId>org.apache.maven.plugins</groupId>
+           <artifactId>maven-dependency-plugin</artifactId>
+           <executions>
+             <execution>
+               <id>copy-installed</id>
+               <phase>process-classes</phase>
+               <goals>
+                 <goal>copy</goal>
+               </goals>
+               <configuration>
+                 <artifactItems>
+                   <artifactItem>
+                     <groupId>solarisrealm</groupId>
+                     <artifactId>libsolsparcauth</artifactId>
+                     <version>1.0</version>
+                     <type>so</type>
+                   </artifactItem>
+                   <artifactItem>
+                     <groupId>solarisrealm</groupId>
+                     <artifactId>libsolx86auth</artifactId>
+                     <version>1.0</version>
+                     <type>so</type>
+                   </artifactItem>
+                 </artifactItems>
+                 <stripVersion>
+                    true
+                 </stripVersion>
+                 <!--<outputDirectory>${maven.project.build.outputDirectory}</outputDirectory>-->
+                 <outputDirectory>target/classes</outputDirectory>
+               </configuration>
+             </execution>
+           </executions>
+         </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.hk2</groupId>
+            <artifactId>hk2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.admin</groupId>
+            <artifactId>config-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>common-util</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.security</groupId>
+            <artifactId>ssl-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.deployment</groupId>
+            <artifactId>deployment-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>internal-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>glassfish-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency> <!-- for FindBugs -->
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>simple-glassfish-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.ldapbp</groupId>
+            <artifactId>ldapbp</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+	    <groupId>org.glassfish.external</groupId>
+	    <artifactId>management-api</artifactId>
+        </dependency>
+        <dependency>
+    	    <groupId>org.glassfish.gmbal</groupId>
+	    <artifactId>gmbal</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.annotations</groupId>
+            <artifactId>logging-annotation-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/nucleus/security/core/src/main/java/com/iplanet/ias/security/auth/login/PasswordLoginModule.java b/nucleus/security/core/src/main/java/com/iplanet/ias/security/auth/login/PasswordLoginModule.java
new file mode 100644
index 0000000..30d72e7
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/iplanet/ias/security/auth/login/PasswordLoginModule.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.iplanet.ias.security.auth.login;
+
+import com.sun.enterprise.security.BasePasswordLoginModule;
+import com.sun.enterprise.security.auth.AuthenticationStatus;
+import com.sun.enterprise.security.auth.AuthenticationStatusImpl;
+import com.sun.enterprise.security.auth.realm.Realm;
+
+import javax.security.auth.login.LoginException;
+
+/**
+ * Provided for backward compatibility with SunOne 7.0
+ * Newer implementations should extend
+ * com.sun.appserv.security.BasePasswordLoginModule 
+ */
+public abstract class PasswordLoginModule extends BasePasswordLoginModule
+{
+    /**
+     * authenticateUser calls authenticate which is implemented by the implementation
+     * of this subclass
+     * @throws LoginException
+     */
+    protected final void authenticateUser() throws LoginException{
+        AuthenticationStatus as = authenticate();
+        if(as.getStatus() == as.AUTH_SUCCESS)
+            return;
+        else{
+            throw new LoginException();
+        }
+    }
+
+    @Deprecated
+     public final AuthenticationStatus commitAuthentication(String username,
+                                        String password,
+                                        Realm theRealm,
+                                        String[] groups)
+    {
+        return commitAuthentication(username, password.toCharArray(), theRealm, groups);
+    }
+    /** Called at the end of the authenticate method by the user
+     * @return AuthenticationStatus indicating success/failure
+     */
+    public final AuthenticationStatus commitAuthentication(String username,
+                                        char[] password,
+                                        Realm theRealm,
+                                        String[] groups)
+    {
+        commitUserAuthentication(groups);
+        int status = AuthenticationStatus.AUTH_SUCCESS;
+        String realm = theRealm.getName();
+        String authMethod = theRealm.getAuthType();
+        AuthenticationStatus as =
+            new AuthenticationStatusImpl(username, authMethod, realm, status);
+        return as;
+    }
+    abstract protected AuthenticationStatus authenticate() throws LoginException;
+}
diff --git a/nucleus/security/core/src/main/java/com/iplanet/ias/security/auth/realm/IASRealm.java b/nucleus/security/core/src/main/java/com/iplanet/ias/security/auth/realm/IASRealm.java
new file mode 100644
index 0000000..1f89c9e
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/iplanet/ias/security/auth/realm/IASRealm.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.iplanet.ias.security.auth.realm;
+
+import com.sun.enterprise.security.BaseRealm;
+
+/**
+ * Parent class for iAS Realm classes.
+ *
+ *  This class no longer implements the methods of Realm, instead it extends
+ *  from BaseRealm and now is only a place holder for migration and is a
+ *  candidate for deprecation.
+ *  This class is provided for migration of realms written for 7.0 to 8.x
+ */
+
+public abstract class IASRealm extends BaseRealm{
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/appserv/.gitkeep_empty_dir b/nucleus/security/core/src/main/java/com/sun/appserv/.gitkeep_empty_dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/appserv/.gitkeep_empty_dir
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/AnonCredential.java b/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/AnonCredential.java
new file mode 100644
index 0000000..50d5057
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/AnonCredential.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * @(#)AnonCredential.java	1.1 00/10/20
+ *
+ */
+
+package com.sun.enterprise.common.iiop.security;
+
+/**
+ * This class is part of the interface between J2EE RI and security 
+ * interceptors. This class is used to assert anonymous identities.
+ *
+ * @author    Sekhar Vajjhala
+ */
+
+public class AnonCredential {
+
+}
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/GSSUPName.java b/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/GSSUPName.java
new file mode 100644
index 0000000..eea9862
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/GSSUPName.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.common.iiop.security;
+
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.security.common.Util;
+import java.util.*;
+import java.util.logging.*;
+import com.sun.logging.*;
+
+/**
+ * This class implements the GSSAPI exported name functionality 
+ * as required by CSIV2.
+ *
+ * @author    Sekhar Vajjhala
+ */
+
+public class GSSUPName {
+    private static java.util.logging.Logger _logger=null;
+    static{
+       _logger=SecurityLoggerInfo.getLogger();
+        }
+    public static final char   AT_CHAR       = '@';
+    public static final String AT_STRING     = "@";
+    public static final char   ESCAPE_CHAR   = '\\';
+    public static final String ESCAPE_STRING = "\\";
+
+
+    private String username;  // username
+    private String realm;     // realmname
+    private GSSUtilsContract gssUtils;
+
+    public GSSUPName(String username, String realm)
+    {
+
+	this.username = username;
+	this.realm    = realm;
+        gssUtils = Util.getDefaultHabitat().getService(GSSUtilsContract.class);
+    }
+
+    /* Construct a GSSUPName from an exported name. This constructor
+     * is for use on the server side.
+     */
+    public GSSUPName(byte[] GSSExportedName)
+    {
+        int             realm_index = 0 ; // start of realm 
+        int             user_index  = -1 ; // start of user
+        String expname = "";
+        String name_value = "" ;
+        String name_scope = "" ;
+        byte[] exportedname = null ;
+
+        gssUtils = Util.getDefaultHabitat().getService(GSSUtilsContract.class);
+        assert(gssUtils != null);
+        if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE,"Attempting to create a mechanism specific name from the exported name.");
+        }
+	
+        try {
+            exportedname = gssUtils.importName(gssUtils.GSSUP_MECH_OID(), GSSExportedName);
+            // extract from the "UTF8" encoding
+            expname = new String(exportedname, "UTF8");
+        } catch (Exception e) {
+             _logger.log(Level.SEVERE, SecurityLoggerInfo.iiopImportNameError , e.getLocalizedMessage());
+	}
+
+	if(_logger.isLoggable(Level.FINE)) {
+		_logger.log(Level.FINE,"Mechanism specific name: " + expname);
+	}
+        // Deterimine the starting indices of the username and realm name
+
+        int at_index  = expname.indexOf(AT_CHAR);
+        int esc_index = expname.indexOf(ESCAPE_CHAR);
+
+        if (at_index == -1) {
+            /* scoped-username is of the form:
+             *     scoped-username ::== name_value
+             */
+            name_value = expname;
+
+        }  else if (esc_index == -1 ) {
+            if (at_index != 0) {	
+	        /* name_value is not null i.e. scoped-username is of the form:
+                 *     scoped-username ::= name_value@name_scope
+		 */
+                name_value = expname.substring(0, at_index);
+	    }
+            name_scope = expname.substring(at_index+1);
+	}   else {
+	    // exported name contains both AT_CHAR and ESCAPE_CHAR. Separate
+            // the username and the realm name. The start of a realm name
+	    // is indicated by an AT_CHAR that is not preceded by an
+	    // ESCAPE_CHAR. 
+	    // The username always starts at 0.
+
+            user_index  = 0;
+            realm_index = 0;
+            int i = 0;
+	    while ( (i = expname.indexOf(AT_CHAR, i)) != -1) {
+	        if (expname.charAt(i-1) != ESCAPE_CHAR) {
+                    realm_index = i;
+                    break;
+		}
+                i += 1;
+	    }
+            name_value = expname.substring(user_index, realm_index);
+            name_scope = expname.substring(realm_index+1);
+	}
+
+	if(_logger.isLoggable(Level.FINE)) {
+		_logger.log(Level.FINE,"name_value: " + name_value + " ;  name_scope: " + name_scope);
+	}
+
+        if ((name_value.length() > 0) && (at_index != -1)) {
+	    // remove the ESCAPE_CHAR from the username
+            StringBuilder strbuf = new StringBuilder("");
+            int starti = 0  ; // start index
+            int endi   = 0  ; // end index
+
+            while ((endi = name_value.indexOf(ESCAPE_CHAR, starti)) != -1) {
+                strbuf.append(name_value.substring(starti, endi));
+                starti = endi + 1;
+	    }
+            strbuf.append(name_value.substring(starti));
+            name_value = strbuf.toString();
+	}
+
+        username = name_value;
+        realm    = name_scope;
+	if(_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE,"Constructed GSSUPName ( " + toString()+ " )");
+        }
+    }
+
+    /**
+     *  returns and exported name as an array of 1 or more UTF8 characters.
+     */
+    public byte[] getExportedName() {
+
+        byte[] expname = {} ;
+        byte[] expname_utf8 = null ;
+        StringTokenizer strtok ;
+
+	if(_logger.isLoggable(Level.FINE)) {
+		_logger.log(Level.FINE,"Going to create exported name for:" + toString());
+	}
+
+        StringBuffer strbuf = new StringBuffer("");
+       
+        /* Process the username for special characters AT_CHAR and ESCAPE_CHAR */
+
+        int at_index  = username.indexOf(AT_CHAR);
+        int esc_index = username.indexOf(ESCAPE_CHAR);
+        
+        if ( (at_index == -1) &&  (esc_index == -1))
+	    strbuf = new StringBuffer(username); // just copy - no processing required.
+	else {
+
+	    // N.B. Order of processing is important
+
+	    // Replace the ESCAPE_CHAR first
+	    if (esc_index != -1) {
+                strtok = new StringTokenizer(username, ESCAPE_STRING);
+                while (strtok.hasMoreTokens()) { 
+                    strbuf.append(strtok.nextToken());
+                    strbuf.append(ESCAPE_CHAR).append(ESCAPE_CHAR);
+		}
+	    }
+
+            // Replace the AT_CHAR next
+            if (at_index != -1) {
+                strtok = new StringTokenizer(username, AT_STRING);
+                while (strtok.hasMoreTokens()) { 
+                    strbuf.append(strtok.nextToken());
+                    strbuf.append(ESCAPE_CHAR).append(AT_CHAR);
+		}
+	    }
+	}
+
+	if(_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE,"username after processing for @ and \\: " + strbuf);
+	}
+
+        /** Do not append realm name: this ensures that we dont sent
+            "default" or "certificate" to another appserver.
+
+        // append an AT-CHAR only if realm is not null.
+        // NOTe: In the current implementation, realm will never
+        // be null. It is either "certificate" or "default".
+
+        if (realm.length() > 0) {
+            strbuf.append(AT_CHAR);
+            strbuf.append(realm);
+	}
+        **/
+
+	if(_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE,"username and realm name : " + strbuf);
+	}
+        try {
+            expname_utf8 = strbuf.toString().getBytes("UTF8");
+            assert(gssUtils != null);
+            expname = gssUtils.createExportedName(
+                       gssUtils.GSSUP_MECH_OID(), expname_utf8);
+        } catch (Exception e) {
+             _logger.log(Level.SEVERE, SecurityLoggerInfo.iiopCreateExportedNameError , e.getLocalizedMessage());
+	}
+
+	if(_logger.isLoggable(Level.FINE)) {
+                assert(gssUtils != null);
+		_logger.log(Level.FINE,"GSSUPName in exported format = " + gssUtils.dumpHex(expname));
+	}
+        return expname;
+    }
+
+    public String getRealm() {
+	return realm;
+    }
+
+    public String getUser() {
+        return username;
+    }
+
+    public boolean equals(Object o) {
+	if(o instanceof GSSUPName) {
+	    GSSUPName nm = (GSSUPName)o;
+	    if (nm.getUser().equals(username) && nm.getRealm().equals(realm))
+		return true;
+	}
+	return false;
+    }
+
+    /* Return the hashCode. */
+    public int hashCode() {
+	return username.hashCode() + realm.hashCode();
+    }
+
+    /* String representation of the GSSUPname */
+    public String toString() {
+	String s = "Username = " + username;
+	s = s + " Realm = " + realm;
+	return s;
+    }
+
+
+    // used locally by this file for test purposes
+    private static void testGSSUP(String user, String realm)
+    {
+        GSSUPName gssname;
+        GSSUPName gssname1;
+
+        _logger.log(Level.FINE,"Running unit test for TestGSSUPName.");
+        _logger.log(Level.FINE,"Creating a GSSUPName instance");
+        gssname = new GSSUPName(user, realm);
+        _logger.log(Level.FINE,"GSSUPName : " + gssname.toString());
+        _logger.log(Level.FINE,"Obtaining an exported name form");
+        byte[] expname = gssname.getExportedName();
+        _logger.log(Level.FINE,"Creating a GSSUPName instance from exported name");
+        gssname1 = new GSSUPName(expname);
+        _logger.log(Level.FINE,"GSSUPName created from exported name: " + gssname1.toString());
+    }
+
+    public static void main(String[] args) {
+        testGSSUP("sekhar@vajjha@la@", "sun.com");
+        testGSSUP("sekhar", "sun.com");
+        testGSSUP("sekhar", "");
+        testGSSUP("", "sun.com");
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/GSSUtilsContract.java b/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/GSSUtilsContract.java
new file mode 100644
index 0000000..e4d7af6
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/GSSUtilsContract.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.common.iiop.security;
+
+import java.io.IOException;
+import org.jvnet.hk2.annotations.Contract;
+import sun.security.util.ObjectIdentifier;
+
+/**
+ *
+ * @author Kumar
+ */
+@Contract
+public interface GSSUtilsContract {
+    
+    public String dumpHex(byte[] octets);
+
+    public byte[] importName(ObjectIdentifier oid, byte[] externalName)
+	throws IOException;
+    public byte[] createExportedName(ObjectIdentifier oid, byte[] extName)
+	throws IOException;
+    public ObjectIdentifier GSSUP_MECH_OID();
+    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/SecurityContext.java b/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/SecurityContext.java
new file mode 100644
index 0000000..e5452ae
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/common/iiop/security/SecurityContext.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * @(#)SecurityContext.java	1.5 00/10/24
+ */
+
+package com.sun.enterprise.common.iiop.security;
+
+
+import javax.security.auth.*;
+
+/*
+ * This interface is part of the contract between CSIV2 interceptors
+ * and the rest of J2EE RI.
+ *
+ * @author  Nithya Subramanian
+ */
+
+
+/**
+ *  A subject is used a container for passing the security context
+ *  information in the service context field. The security context
+ *  information in the subject must be stored either as a private or
+ *  a public credential according to the following convention:
+ *
+ *    PasswordCredential:
+ *      Client authentication will be performed using the username
+ *      and password in the PasswordCredential. PasswordCredential
+ *      must be passed as a PrivateCredential.
+ *
+ *    X500Name:
+ *      DN name specified in X500Name will be asserted. X500Name must 
+ *      be passed as a PublicCredential.
+ *
+ *    GSSUPName:
+ *      Identity specified in GSSUPName will be asserted. GSSUPName must
+ *      be passed as a PublicCredential.
+ *
+ *    X509CertificateCredential:
+ *      The certificate chain in the credential will be asserted. The 
+ *      credential must be passed as a PublicCredential.
+ *
+ *    AnonCredential:
+ *      Anonymous identity will be asserted. Credential must be passed
+ *      as a PublicCredential.
+ *
+ *    Class fields in the SecurityContext are used for credential selection.
+ *    There are two class fields: authcls and identcls.
+ *    
+ *    authcls is a Class object that identifies the credential for 
+ *    client authentication.
+ *          
+ *    identcls is a Class object that identifies the credential for
+ *    identity assertion.
+ *
+ *  The following semantics must be observed:
+ * 
+ *  1. A client authentication token is always passed as a private
+ *     credential. authcls set to the class of the authentication token
+ *     
+ *  2. An identity token is always passed as a public credential.
+ *     identcls is set to the class of the identity token.
+ *  
+ *  3. authcls is set to null if there is no client auth token
+ * 
+ *  4. identcls is set to null if there is no ident token
+ *
+ *  5. There must not be more than one instance of class identified
+ *     by authcls or identcls. However, there can be one instance of
+ *     identcls *and* authcls (this allows both a client auth token
+ *     and an identity token to be passed across the interface).
+ */
+
+public class SecurityContext {
+    public Subject subject;
+    public Class   authcls;
+    public Class   identcls;
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/AppCNonceCacheMap.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/AppCNonceCacheMap.java
new file mode 100644
index 0000000..bff3b3f
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/AppCNonceCacheMap.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import org.glassfish.security.common.CNonceCache;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jvnet.hk2.annotations.Service;
+import javax.inject.Singleton;
+
+
+
+/**
+ *
+ * @author vbkumarjayanti
+ */
+@Service
+@Singleton
+public class AppCNonceCacheMap extends HashMap<String,CNonceCache> {
+    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseAuditModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseAuditModule.java
new file mode 100644
index 0000000..dc42049
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseAuditModule.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * AuditModule.java
+ *
+ * Created on July 27, 2003, 11:32 PM
+ */
+
+package com.sun.enterprise.security;
+
+import java.util.Properties;
+/**
+ * Base class that should be extended by all classes that wish to provide their
+ * own Audit support.
+ * @author  Harpreet Singh
+ * @version
+ */
+public abstract class BaseAuditModule {
+    protected Properties props = null;
+    /** 
+     * Method is invoked at server startup, during AuditModule initialization.
+     * If method returns without any exception then S1AS assumes that the module
+     * is ready to serve any requests.
+     * @param props the properties for the AuditModule. These properties are
+     * defined in the domain.xml
+     */
+    public void init(Properties props) {
+        this.props = props;
+    }
+    
+    /**
+     * Invoked post authentication request for a user in a given realm
+     * @param user username for whom the authentication request was made
+     * @param realm the realm name under which the user is authenticated.
+     * @param success the status of the authentication
+     */
+    public void authentication(String user, String realm, boolean success) {
+    }
+    
+    /**
+     * Invoked upon completion of the server startup
+     */
+    public void serverStarted() {
+    }
+
+    /**
+     * Invoked upon completion of the server shutdown
+     */
+    public void serverShutdown() {
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseCertificateLoginModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseCertificateLoginModule.java
new file mode 100644
index 0000000..d7a29ca
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseCertificateLoginModule.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import com.sun.enterprise.security.auth.realm.certificate.CertificateRealm;
+import com.sun.enterprise.security.PrincipalGroupFactory;
+import com.sun.enterprise.security.PrincipalGroupFactory;
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import javax.security.auth.x500.X500Principal;
+
+import org.glassfish.internal.api.Globals;
+import org.glassfish.security.common.Group;
+
+/**
+ * Abstract base class for certificate-based login modules.
+ *
+ * <P>Subclasses need to implement the authenticateUser() method and later
+ * call commitUserAuthentication().
+ *
+ */
+public abstract class BaseCertificateLoginModule implements LoginModule {
+
+    private Subject subject;
+    /**
+     * State shared with other login modules.
+     */
+    protected Map<String, ?> _sharedState;
+    /**
+     * Options configured for this LoginModule.
+     */
+    protected Map<String, ?> _options;
+    /**
+     * System Logger.
+     */
+    protected static final Logger _logger =
+            SecurityLoggerInfo.getLogger();
+    private CallbackHandler callbackHandler;
+    private boolean success = false;
+    private String[] groups = null;
+    private boolean commitsuccess = false;
+    private X509Certificate[] certs = null;
+    private X500Principal x500Principal;
+    private String appName = null;
+
+    public final void initialize(Subject subject, CallbackHandler callbackHandler
+            , Map<String, ?> sharedState, Map<String, ?> options) {
+        this.subject = subject;
+        this._sharedState = sharedState;
+        this._options = options;
+        this.callbackHandler = callbackHandler;
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "Login module initialized: {0}"
+                    , this.getClass().toString());
+        }
+    }
+
+    public final boolean login() throws LoginException {
+        //Extract the certificates from the subject.
+        extractCredentials();
+
+        // Delegate the actual authentication to subclass.
+        authenticateUser();
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "JAAS login complete.");
+        }
+        return true;
+    }
+
+    public final boolean commit() throws LoginException {
+        if (!success) {
+            return false;
+        }
+        Set<Principal> principalSet = subject.getPrincipals();
+        for (int i = 0; i < groups.length; i++) {
+            if (groups[i] != null) {
+                Group g = Globals.getDefaultHabitat().<PrincipalGroupFactory>getService(PrincipalGroupFactory.class).
+                        getGroupInstance(groups[i], CertificateRealm.AUTH_TYPE);
+                principalSet.add(g);
+            }
+            groups[i] = null;
+        }
+        groups = null;
+        commitsuccess = true;
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "JAAS authentication committed.");
+        }
+        return true;
+    }
+
+    final public boolean abort() throws LoginException {
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "JAAS authentication aborted.");
+        }
+
+        if (!success) {
+            return false;
+        } else if (success && !commitsuccess) {
+            // login succeeded but overall authentication failed
+            success = false;
+            for (int i = 0; i < groups.length; i++) {
+                groups[i] = null;
+            }
+            groups = null;
+            if (certs != null) {
+                for (int i = 0; i < certs.length; i++) {
+                    certs[i] = null;
+                }
+                certs = null;
+            }
+            x500Principal = null;
+        } else {
+            // overall authentication succeeded and commit succeeded,
+            // but someone else's commit failed
+            logout();
+        }
+        return true;
+
+    }
+
+    final public boolean logout() throws LoginException {
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "JAAS logout for: {0}", subject.toString());
+        }
+
+        subject.getPrincipals().clear();
+        subject.getPublicCredentials().clear();
+        subject.getPrivateCredentials().clear();
+
+        success = false;
+        commitsuccess = false;
+        if (groups != null) {
+            for (int i = 0; i < groups.length; i++) {
+                groups[i] = null;
+            }
+            groups = null;
+        }
+        if (certs != null) {
+            for (int i = 0; i < certs.length; i++) {
+                certs[i] = null;
+            }
+            certs = null;
+        }
+        x500Principal = null;
+        return true;
+    }
+
+    private void extractCredentials() throws LoginException {
+        // Certificates are available as a List object in the Public Credentials.
+        Set<List> creds = subject.getPublicCredentials(List.class);
+        Iterator<List> itr = creds.iterator();
+        if (!itr.hasNext()) {
+            success = false;
+            throw new LoginException("No Certificate Credential found.");
+        }
+        List certCred = itr.next();
+        if (certCred == null || certCred.isEmpty()) {
+            success = false;
+            throw new LoginException("No Certificate(s) found.");
+        }
+        try {
+            certs = (X509Certificate[]) certCred.toArray(new X509Certificate[certCred.size()]);
+        } catch (Exception ex) {
+            throw (LoginException) new LoginException("No Certificate(s) found.").initCause(ex);
+        }
+        x500Principal = certs[0].getSubjectX500Principal();
+
+        // Callback to get the application name.
+        CertificateRealm.AppContextCallback appContext = new CertificateRealm.AppContextCallback();
+        try {
+            callbackHandler.handle(new Callback[]{appContext});
+            appName = appContext.getModuleID();
+        } catch (Exception ex) {
+        }
+    }
+
+    /**
+     *
+     * <P>This is a convenience method which can be used by subclasses
+     *
+     * <P>Note that this method is called after the authentication
+     * has succeeded. If authentication failed do not call this method.
+     *
+     * This method sets the authentication status to success if the
+     * groups parameter is non-null.
+     *
+     * @param groups String array of group memberships for user (could be
+     *     empty).
+     */
+    protected final void commitUserAuthentication(final String[] groups) {
+        this.groups = groups;
+        this.success = (groups != null);
+    }
+
+    /**
+     * Perform authentication decision.
+     *
+     * Method returns silently on success and returns a LoginException
+     * on failure.
+     *
+     * <p>Must be overridden to add custom functionality.
+     * @throws LoginException on authentication failure.
+     *
+     */
+    protected abstract void authenticateUser() throws LoginException;
+
+    /**
+     * Get the application name.
+     *
+     * <p> This may be useful when a single LoginModule has to handle
+     * multiple applications that use certificates.
+     *
+     * @return the application name. Non-null only for web container.
+     */
+    protected final String getAppName() {
+        return appName;
+    }
+
+    /**
+     * Get the certificate chain presented by the client.
+     *
+     * @return the certificate chain from the client.
+     */
+    protected X509Certificate[] getCerts() {
+        return certs;
+    }
+
+    /**
+     * Returns the subject (subject distinguished name) value from the
+     * first certificate, in the client certificate chain, as an
+     * <code>X500Principal</code>. If the subject value is empty, then
+     * the <code>getName()</code> method of the returned
+     * <code>X500Principal</code> object returns an empty string ("").
+     *
+     * @return an <code>X500Principal</code> representing the subject
+     *		distinguished name from thr first certificate, in the
+     *          client certificate chain;
+     */
+    protected X500Principal getX500Principal() {
+        return x500Principal;
+    }
+
+    /**
+     * Return the subject being authenticated.
+     *
+     * @return the subject being authenticated.
+     */
+    protected Subject getSubject() {
+        return subject;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/BasePasswordLoginModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BasePasswordLoginModule.java
new file mode 100644
index 0000000..0580d8c
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BasePasswordLoginModule.java
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import java.util.*;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+import com.sun.enterprise.security.PrincipalGroupFactory;
+import com.sun.enterprise.util.i18n.StringManager;
+import javax.security.auth.*;
+import javax.security.auth.callback.*;
+import javax.security.auth.login.*;
+import javax.security.auth.spi.*;
+
+import org.glassfish.internal.api.Globals;
+import org.glassfish.security.common.PrincipalImpl;
+import org.glassfish.security.common.Group;
+import com.sun.enterprise.security.auth.login.LoginCallbackHandler;
+import com.sun.enterprise.security.auth.realm.Realm;
+import com.sun.enterprise.security.auth.login.common.PasswordCredential;
+import java.security.Principal;
+
+/**
+ * Abstract base class for password-based login modules.
+ *
+ * <P>Most login modules receive a username and password from the client
+ * (possibly through HTTP BASIC auth, or FORM, or other mechanism) and
+ * then make (or delegate) an authentication decision based on this data.
+ * This class provides common methods for such password-based login modules.
+ *
+ * <P>Subclasses need to implement the authenticateUser() method and later
+ * call commitUserAuthentication().
+ *
+ */
+
+public abstract class BasePasswordLoginModule implements LoginModule
+{
+    // The _subject, _sharedState and _options satisfy LoginModule and are
+    // shared across sub-classes
+    protected Subject _subject;
+    protected Map _sharedState;
+    protected Map _options;
+    protected String _username;
+    @Deprecated
+    protected String _password;
+    protected char[] _passwd;
+    protected Realm _currentRealm;
+    
+    // the authentication status
+    protected boolean _succeeded = false;
+    protected boolean _commitSucceeded = false;
+    protected PrincipalImpl _userPrincipal;
+    protected String[] _groupsList = null;
+
+    protected static final Logger _logger =
+        SecurityLoggerInfo.getLogger();
+
+    protected final static StringManager sm =
+        StringManager.getManager(LoginCallbackHandler.class);
+    private LoginModule userDefinedLoginModule = null;
+    
+    /**
+     * Initialize this login module.
+     *
+     * @param subject - the Subject to be authenticated.
+     * @param callbackHandler - a CallbackHandler for obtaining the subject
+     *    username and password.
+     * @param sharedState - state shared with other configured LoginModules.
+     * @param options - options specified in the login Configuration for
+     *    this particular LoginModule.
+     *
+     */
+    final public void initialize(Subject subject, CallbackHandler callbackHandler,
+                           Map sharedState, Map options)
+    {
+        _subject = subject;
+        _sharedState = sharedState;
+        _options = options;
+        if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE, "Login module initialized: "+
+                           this.getClass().toString());
+        }
+    }
+
+
+    /**
+     * Perform login.
+     *
+     * <P>The callback handler is used to obtain authentication info
+     * for the subject and a login is attempted. This PasswordLoginModule
+     * expects to find a PasswordCredential in the private credentials
+     * of the Subject. If not present the login fails. The callback
+     * handler is ignored as it is not really relevant on the server side.
+     * Finally, the authenticateUser() method is invoked.
+     *
+     * @returns true if login succeeds, otherwise an exception is thrown.
+     * @throws LoginException Thrown if login failed, or on other problems.
+     *
+     */
+    final public boolean login() throws LoginException
+    {
+        //Extract the username and password
+        extractCredentials();
+        
+        // Delegate the actual authentication to subclass.
+        authenticateUser();
+        if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE, "JAAS login complete.");
+        }
+        return true;
+    }
+    
+
+    /**
+     * Commit the authentication.
+     *
+     * <P>Commit is called after all necessary login modules have succeeded.
+     * It adds (if not present) a PrincipalImpl principal and a
+     * LocalCredentials public credential to the Subject.
+     *
+     * @throws LoginException If commit fails.
+     *
+     */
+    public boolean commit() throws LoginException
+    {
+        if (_succeeded == false) {
+            return false;
+        }
+
+        // Add a Principal (authenticated identity) to the Subject
+        // Assume the user we authenticated is the PrincipalImpl [RI]
+        String realm_name = _currentRealm.getName();
+        PrincipalGroupFactory factory = Globals.getDefaultHabitat().getService(PrincipalGroupFactory.class);
+        if (factory != null)
+            _userPrincipal = 
+                factory.getPrincipalInstance(getUsername(),realm_name);
+        else
+            _userPrincipal = new PrincipalImpl(getUsername());
+
+        Set<Principal> principalSet = _subject.getPrincipals();
+        if (!principalSet.contains(_userPrincipal)){
+            principalSet.add(_userPrincipal);
+        }
+        /* populate the group in the subject and clean out the slate at the same
+         * time
+         */
+        for(int i = 0; i<_groupsList.length; i++){
+            if(_groupsList[i] != null){
+                Group g;
+                if (factory != null)
+                    g = factory.getGroupInstance(_groupsList[i], realm_name);
+                else
+                    g = new Group(_groupsList[i]);
+
+                if(!principalSet.contains(g)){
+                    principalSet.add(g);
+                }
+                
+                // cleaning the slate
+                _groupsList[i] = null;
+            }
+        }
+        
+        // In any case, clean out state.
+        _groupsList = null;
+        setUsername(null);
+        setPassword(null);
+        setPasswordChar(null);
+        _commitSucceeded = true;
+        if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE,"JAAS authentication committed.");
+        }
+        return true;
+    }
+
+
+    /**
+     * Abort the authentication process.
+     *
+     */
+    final public boolean abort() throws LoginException
+    {
+        if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE,"JAAS authentication aborted.");
+        }
+        
+        if (_succeeded == false) {
+            return false;
+        } else if (_succeeded == true && _commitSucceeded == false) {
+            // login succeeded but overall authentication failed
+            _succeeded = false;
+            setUsername(null);
+            setPassword(null);
+            setPasswordChar(null);
+            _userPrincipal = null;
+            for(int i = 0; i < _groupsList.length; i++){
+                _groupsList[i] = null;
+            }
+            _groupsList = null;
+        } else {
+            // overall authentication succeeded and commit succeeded,
+            // but someone else's commit failed
+            logout();
+        }
+        return true;
+    }
+
+
+    /**
+     * Log out the subject.
+     *
+     */
+    final public boolean logout() throws LoginException
+    {
+        if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE, "JAAS logout for: " + _subject.toString());
+        }
+
+        _subject.getPrincipals().clear();
+        _subject.getPublicCredentials().clear();
+        _subject.getPrivateCredentials().clear();
+        
+        _succeeded = false;
+        _commitSucceeded = false;
+        setUsername(null);
+        setPassword(null);
+        _userPrincipal = null;
+        if(_groupsList != null){
+            for (int i = 0; i < _groupsList.length; i++){
+                _groupsList[i] = null;
+            }
+            _groupsList = null;
+        }
+        return true;
+    }
+
+    
+    /**
+     *
+     * <P>This is a convenience method which can be used by subclasses
+     *
+     * <P>Note that this method is called after the authentication
+     * has succeeded. If authentication failed do not call this method.
+     * 
+     * Global instance field succeeded is set to true by this method.
+     *
+     * @param groups String array of group memberships for user (could be
+     *     empty). 
+     */
+    public final void commitUserAuthentication (final String[] groups)
+    {
+        //Copy the groups into a new array before storing it in the instance
+        String[] groupsListCopy =  (groups == null) ? null : Arrays.copyOf(groups, groups.length);
+
+        _groupsList = groupsListCopy;
+        _succeeded = true;
+    }
+
+    /**
+     * @return the subject being authenticated.
+     * use case:
+     * A custom login module could overwrite commit() method, and call getSubject()
+     * to get subject being authenticated inside its commit(). Custom principal
+     * then can be added to subject. By doing this,custom principal will be stored
+     * in calling thread's security context and participate in following Appserver's
+     * authorization.
+     *
+     */
+    public Subject getSubject()
+    {
+        return _subject;
+    }
+    
+    /**
+     * Method to extract container-provided username and password
+     * @throws javax.security.auth.login.LoginException
+     */
+    final public void extractCredentials() throws LoginException {
+
+        if (_subject == null) {
+            String msg = sm.getString("pwdlm.noinfo");
+            _logger.log(Level.SEVERE, msg);
+            throw new LoginException(msg);
+        }
+
+        PasswordCredential pwdCred = null;
+
+        try {
+            Iterator i = _subject.getPrivateCredentials().iterator();
+            while (i.hasNext() && pwdCred == null) {
+                Object privCred = i.next();
+                if (privCred instanceof PasswordCredential) {
+                    pwdCred = (PasswordCredential) privCred;
+                }
+            }
+        } catch (Exception e) {
+            _logger.log(Level.WARNING, SecurityLoggerInfo.privateSubjectCredentialsError, e.toString());
+        }
+
+        if (pwdCred == null) {
+            _logger.log(Level.SEVERE, SecurityLoggerInfo.noPwdCredentialProvidedError);
+            String msg = sm.getString("pwdlm.nocreds");
+            throw new LoginException(msg);
+        }
+
+        // Need to obtain the requested realm to get parameters.
+
+        String realm = null;
+        try {
+            realm = pwdCred.getRealm();
+            _currentRealm = Realm.getInstance(realm);
+
+        } catch (Exception e) {
+            String msg = sm.getString("pwdlm.norealm", realm);
+            _logger.log(Level.SEVERE, msg);
+            throw new LoginException(msg);
+        }
+
+         // Get username and password data from credential (ignore callback)
+
+        setUsername(pwdCred.getUser());
+        setPasswordChar(pwdCred.getPassword());
+        setPassword(new String(pwdCred.getPassword()));
+    }
+
+    
+    /**
+     * Perform authentication decision.
+     *
+     * Method returns silently on success and returns a LoginException
+     * on failure.
+     * @throws LoginException on authentication failure.
+     *
+     */
+    protected abstract void authenticateUser() throws LoginException;
+    
+    public void setLoginModuleForAuthentication(LoginModule userDefinedLoginModule) {
+        this.userDefinedLoginModule = userDefinedLoginModule;
+    }
+
+    /**
+     * @return the username sent by container - is made available to the custom 
+     * login module using the protected _username field.
+     * Use Case: A custom login module could use the username to validate against
+     * a realm of users
+     */
+    
+    public String getUsername() {
+        return _username;
+    }
+
+   /**
+    * Used for setting the username obtained from the container internally, to 
+    * be made available to the custom login module implementation
+    * @param username
+    */ 
+    private void setUsername(String username) {
+        this._username = username;
+    }
+
+    
+    /**
+     * Deprecated - password is preferred to be a char[]
+     */
+    @Deprecated
+    public String getPassword() {
+        return _password;
+    }
+
+    /**
+     * Deprecated - password is preferred to be a char[]
+     */
+    @Deprecated
+    private void setPassword(String password) {
+        this._password = password;
+    }
+
+
+
+    
+    /**
+     * @return the password sent by container - is made available to the custom
+     * login module using the protected _password field.
+     * Use Case: A custom login module could use the password to validate against
+     * a custom realm of usernames and passwords
+     * Password is preferred to be a char[] instead of a string
+     */
+
+
+    public char[] getPasswordChar() {
+        return Arrays.copyOf(_passwd, _passwd.length);
+    }
+    
+  /**
+    * Used for setting the password obtained from the container internally, to
+    * be made available to the custom login module implementation
+   *  Password is preferred to be a char[] instead of a string
+    * @param password
+    */
+    private void setPasswordChar(char[] password) {
+        this._passwd = password;
+    }
+    
+    /**
+     * @return the currentRealm - for backward compatability
+     */
+    public Realm getCurrentRealm() {
+        return _currentRealm;
+    }
+    
+    /**
+     * @return the succeeded state - for backward compatability
+     */
+    public boolean isSucceeded() {
+        return _succeeded;
+    }
+    
+    /**
+     * @return the commitsucceeded state - for backward compatability
+     */
+    public boolean isCommitSucceeded() {
+        return _commitSucceeded;
+    }
+    
+    /**
+     * @return the UserPrincipal - for backward compatability
+     */
+    public PrincipalImpl getUserPrincipal() {
+        return _userPrincipal;
+    }
+    
+     /**
+     * @return the groupList - for backward compatability
+     */
+    public String[] getGroupsList() {
+        return Arrays.copyOf(_groupsList, _groupsList.length);
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseProgrammaticLoginPermission.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseProgrammaticLoginPermission.java
new file mode 100644
index 0000000..ae29788
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseProgrammaticLoginPermission.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import java.security.BasicPermission;
+
+
+/**
+ * Permission for using programmatic login.
+ *
+ * <P>This permission is used by ProgrammaticLogin to verify whether
+ * the invoking code has been granted the use of this interface.
+ *
+ * <P>The name of this permission is the name of the method being invoked.
+ *
+ */
+public class BaseProgrammaticLoginPermission extends BasicPermission
+{
+    public BaseProgrammaticLoginPermission(String name)
+    {
+        super(name);
+    }
+
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseRealm.java
new file mode 100644
index 0000000..87c8203
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseRealm.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import java.util.*;
+
+import com.sun.enterprise.security.auth.realm.*;
+
+import com.sun.enterprise.security.util.IASSecurityException;
+import com.sun.enterprise.util.i18n.StringManager;
+
+
+/**
+ * Parent class for iAS Realm classes.
+ *
+ * <P>This class provides default implementation for most of the abstract
+ * methods in com.sun.enterprise.security.auth.realm.Realm. Since most
+ * of these abstract methods are not supported by Realms there is
+ * no need for the subclasses to implement them. The default implementations
+ * provided here generally throw an exception if invoked.
+ *
+ *  @author Harpreet Singh
+ */
+public abstract class BaseRealm extends Realm
+{
+    public static final String JAAS_CONTEXT_PARAM="jaas-context";
+    
+    protected static final StringManager sm =
+        StringManager.getManager(IASRealm.class);
+
+    
+    /**
+     * Returns an AuthenticationHandler object which can be used to 
+     * authenticate within this realm.
+     *
+     * <P>This method return null always, since AuthenticationHandlers
+     * are generally not supported by iAS realms. Subclass can override
+     * if necessary.
+     *
+     * @return An AuthenticationHandler object for this realm (always null)
+     *
+     */
+    public AuthenticationHandler getAuthenticationHandler()
+    {
+        _logger.warning("iasrealm.noauth");
+        return null;
+    }
+
+
+    /**
+     * Returns names of all the users in this particular realm.
+     *
+     * <P>This method always throws a BadRealmException since by default
+     * this operation is not supported. Subclasses which support this
+     * method can override.
+     *
+     * @return enumeration of user names (strings)
+     * @exception com.sun.enterprise.security.auth.realm.BadRealmException if realm data structures are bad
+     *
+     */
+    public Enumeration getUserNames() throws BadRealmException
+    {
+        String msg = sm.getString("iasrealm.notsupported");
+        throw new BadRealmException(msg);
+    }
+
+
+    /**
+     * Returns the information recorded about a particular named user.
+     *
+     * <P>This method always throws a BadRealmException since by default
+     * this operation is not supported. Subclasses which support this
+     * method can override.
+     *
+     * @param name name of the user whose information is desired
+     * @return the user object
+     * @exception com.sun.enterprise.security.auth.realm.NoSuchUserException if the user doesn't exist
+     * @exception com.sun.enterprise.security.auth.realm.BadRealmException if realm data structures are bad
+     *
+     */
+    public User getUser(String name)
+        throws NoSuchUserException, BadRealmException
+    {
+        String msg = sm.getString("iasrealm.notsupported");
+        throw new BadRealmException(msg);
+    }
+
+
+    /**
+     * Returns names of all the groups in this particular realm.
+     *
+     * <P>This method always throws a BadRealmException since by default
+     * this operation is not supported. Subclasses which support this
+     * method can override.
+     *
+     * @return enumeration of group names (strings)
+     * @exception com.sun.enterprise.security.auth.realm.BadRealmException if realm data structures are bad
+     *
+     */
+    public Enumeration getGroupNames()
+        throws BadRealmException
+    {
+        String msg = sm.getString("iasrealm.notsupported");
+        throw new BadRealmException(msg);
+    }
+
+
+    /**
+     * Refreshes the realm data so that new users/groups are visible.
+     *
+     * <P>This method always throws a BadRealmException since by default
+     * this operation is not supported. Subclasses which support this
+     * method can override.
+     *
+     * @exception com.sun.enterprise.security.auth.realm.BadRealmException if realm data structures are bad
+     *
+     */
+    public void refresh() throws BadRealmException
+    {
+        String msg = sm.getString("iasrealm.notsupported");
+        throw new BadRealmException(msg);
+    }
+
+     /**
+     * Adds new user to file realm. User cannot exist already.
+     *
+     * @param name User name.
+     * @param password Cleartext password for the user.
+     * @param groupList List of groups to which user belongs.
+     * @throws BadRealmException If there are problems adding user.
+     *
+     */
+    public  void addUser(String name, char[] password, String[] groupList)
+        throws BadRealmException, IASSecurityException  {
+        String msg = sm.getString("iasrealm.notsupported");
+        throw new BadRealmException(msg);
+    }
+    
+    /**
+     * Adds new user to file realm. User cannot exist already.
+     *
+     * Deprecated - User of the overloaded method with char[] password is encouraged
+     */
+    @Deprecated
+    public  void addUser(String name, String password, String[] groupList)
+        throws BadRealmException, IASSecurityException  {
+        addUser(name, password.toCharArray(), groupList);
+        
+    }
+
+      
+    
+    /**
+     * Remove user from file realm. User must exist.
+     *
+     * @param name User name.
+     * @throws NoSuchUserException If user does not exist.
+     *
+     */
+     public void removeUser(String name)
+        throws NoSuchUserException, BadRealmException {
+        String msg = sm.getString("iasrealm.notsupported");
+        throw new BadRealmException(msg);
+     }
+
+     /**
+     * Update data for an existing user. User must exist.
+     * Deprecated - User of the overloaded method with char[] password is encouraged
+     *
+     */
+     @Deprecated
+    public void updateUser(String name, String newName, String password,
+                           String[] groups)
+        throws NoSuchUserException, BadRealmException,
+                               IASSecurityException {
+        updateUser(name, newName, (password ==null)? null : password.toCharArray(), groups);
+
+    }
+     
+     /**
+     * Update data for an existing user. User must exist.
+     *
+     * @param name Current name of the user to update.
+     * @param newName New name to give this user. It can be the same as
+     *     the original name. Otherwise it must be a new user name which
+     *     does not already exist as a user.
+     * @param password Cleartext password for the user. If non-null the user
+     *     password is changed to this value. If null, the original password
+     *     is retained.
+     * @param groupList List of groups to which user belongs.
+     * @throws BadRealmException If there are problems adding user.
+     * @throws NoSuchUserException If user does not exist.
+     *
+     */
+    public void updateUser(String name, String newName, char[] password,
+                           String[] groups)
+        throws NoSuchUserException, BadRealmException,
+                               IASSecurityException {
+        String msg = sm.getString("iasrealm.notsupported");
+        throw new BadRealmException(msg);
+    }
+    
+    /**
+     * @return true if the realm implementation support User Management (add,remove,update user)
+     */
+    public boolean supportsUserManagement() {
+        //false by default.
+        return false;
+    }
+    
+   /**
+    * Persist the realm data to permanent storage
+    * @throws com.sun.enterprise.security.auth.realm.BadRealmException
+    */
+    public  void persist() throws BadRealmException {
+        //NOOP for realms that do not support UserManagement
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/CNonceCacheFactory.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/CNonceCacheFactory.java
new file mode 100644
index 0000000..1c2b15e
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/CNonceCacheFactory.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import org.glassfish.security.common.CNonceCache;
+import org.jvnet.hk2.annotations.Contract;
+
+/**
+ *
+ * @author vbkumarjayanti
+ */
+@Contract
+public interface CNonceCacheFactory {
+    public static final String CLUSTER_NAME_PROP="cluster_name";
+    public static final String INSTANCE_NAME_PROP="instance_name";
+    public CNonceCache createCNonceCache(String appName, String clusterName,
+            String instanceName, String storeName);
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/CORBAObjectPermission.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/CORBAObjectPermission.java
new file mode 100644
index 0000000..156ce15
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/CORBAObjectPermission.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import java.security.BasicPermission;
+
+
+/**
+ * This object represents the permission to invoke on a set of CORBA objects
+ * that are not EJBs.
+ * The name is the CORBA Object's name (currently only "*" is supported).
+ * The actions are the methods on the object.
+ *
+ * This class extends BasicPermission to support wildcard matching.
+ */
+public class CORBAObjectPermission extends BasicPermission {
+
+    public CORBAObjectPermission() {
+	
+	super("*", "*");
+    }
+
+    public CORBAObjectPermission(String name) {
+
+	super("*", "*");
+
+	// currently only name "*" is supported
+	if ( !name.equals("*") ) {
+	    throw new RuntimeException("CORBAObjectPermission name must be *");
+	}
+    }
+
+    public CORBAObjectPermission(String name, String actions) {
+
+	super("*", actions);
+	
+	// currently only name "*" is supported
+	if ( !name.equals("*") ) {
+	    throw new RuntimeException("CORBAObjectPermission name must be *");
+	}
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/ContainerSecurityLifecycle.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ContainerSecurityLifecycle.java
new file mode 100644
index 0000000..50c7e69
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ContainerSecurityLifecycle.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import org.jvnet.hk2.annotations.Contract;
+
+@Contract
+public interface ContainerSecurityLifecycle {
+   public void onInitialization();
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/EjbSecurityPolicyProbeProvider.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/EjbSecurityPolicyProbeProvider.java
new file mode 100644
index 0000000..dc860c7
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/EjbSecurityPolicyProbeProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import org.glassfish.external.probe.provider.annotations.Probe;
+import org.glassfish.external.probe.provider.annotations.ProbeParam;
+import org.glassfish.external.probe.provider.annotations.ProbeProvider;
+
+
+@ProbeProvider(moduleProviderName="glassfish",moduleName="security", probeProviderName="ejbpolicy")
+public class EjbSecurityPolicyProbeProvider {
+
+    @Probe(name="policyCreationEvent")
+    public void policyCreationEvent(
+            @ProbeParam("contextId") String contextId ) {}
+
+    @Probe(name = "policyCreationStartedEvent")
+    public void policyCreationStartedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "policyCreationEndedEvent")
+    public void policyCreationEndedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/EmbeddedSecurity.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/EmbeddedSecurity.java
new file mode 100644
index 0000000..868e3e9
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/EmbeddedSecurity.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.hk2.api.ServiceLocator;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import org.jvnet.hk2.annotations.Contract;
+
+/**
+ * Utility contact to copy the security related config files
+ * from the passed non-embedded instanceDir to the embedded
+ * server instance's config.
+ * This is implemented by the EmbeddedSecurityUtil class
+ *
+ * @author Nithya Subramanian
+ */
+
+@Contract
+public interface EmbeddedSecurity {
+
+    public void copyConfigFiles(ServiceLocator habitat, File fromInstanceDir, File domainXml) throws IOException, XMLStreamException;
+
+    public String parseFileName(String fullFilePath);
+
+    public boolean isEmbedded(ServerEnvironment se);
+
+    public List<String> getKeyFileNames(SecurityService securityService);
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/GUIErrorDialog.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/GUIErrorDialog.java
new file mode 100644
index 0000000..a7b5457
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/GUIErrorDialog.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * GUIErrorDialog.java
+ * An error dialog box used for FailedLogin
+ *
+ * @author Harpreet Singh
+ * @version 
+ */
+
+package com.sun.enterprise.security;
+import javax.swing.*;
+import java.awt.event.*;
+
+public class GUIErrorDialog extends javax.swing.JDialog {
+    String message;
+    /** Creates new form GUIErrorDialog */
+    public GUIErrorDialog (String message){
+	super (new JFrame (), true);
+	this.message = message;
+	initComponents ();
+	pack ();
+    }
+    /** This method is called from within the constructor to
+     * initialize the form.
+     */
+    private void initComponents() {
+        okButton = new javax.swing.JButton();
+        errorLbl = new javax.swing.JLabel();
+	okButton.setAlignmentX (CENTER_ALIGNMENT);
+	errorLbl.setAlignmentX (CENTER_ALIGNMENT);
+	getContentPane().setLayout (new javax.swing.BoxLayout (getContentPane (),BoxLayout.Y_AXIS));
+        addWindowListener(new java.awt.event.WindowAdapter() {
+            public void windowClosing(java.awt.event.WindowEvent evt) {
+                closeDialog(evt);
+            }
+        });
+        okButton.setActionCommand("okButton");
+        okButton.setText("OK");
+        okButton.addActionListener (new ActionListener (){
+		public void actionPerformed (ActionEvent e){
+		    dispose ();
+		}
+	    });
+	super.addWindowListener (new WindowAdapter (){
+		public void windowClosing (WindowEvent we){
+		    dispose ();
+		}
+	    });
+        errorLbl.setText("Error : "+message);
+	getContentPane().add (errorLbl);
+	getContentPane().add (okButton);
+    }
+
+    /** Closes the dialog */
+    private void closeDialog(java.awt.event.WindowEvent evt) {
+        setVisible (false);
+        dispose ();
+    }
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton okButton;
+    private javax.swing.JLabel errorLbl;
+    // End of variables declaration//GEN-END:variables
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/GUILoginDialog.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/GUILoginDialog.java
new file mode 100644
index 0000000..e5bdd23
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/GUILoginDialog.java
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+
+import com.sun.enterprise.security.ssl.SSLUtils;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.security.auth.callback.*;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+
+import java.util.logging.*;
+
+import com.sun.logging.*;
+import java.util.Arrays;
+import org.glassfish.internal.api.Globals;
+
+
+/**
+ * An implementation of a LoginDialog that presents a swing based 
+ * GUI for querying username and password.
+ * @author Harish Prabandham
+ * @author Harpreet Singh
+ */
+public final class GUILoginDialog implements LoginDialog  {
+
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+
+    private String	entity;
+    private PassphraseDialog passphraseDialog;
+    private CertificateDialog certDialog;
+    private static final LocalStringManagerImpl localStrings =
+	new LocalStringManagerImpl(GUILoginDialog.class);
+
+    /**
+     */
+    public GUILoginDialog () { 
+	this (localStrings.getLocalString("enterprise.security.defaultEntity", "user"));
+    }
+    
+    /**
+     */
+    public GUILoginDialog (String entity) {
+	this.entity = entity;
+	JFrame f = new JFrame();
+	String phrase = localStrings.getLocalString("enterprise.security.loginPhrase", "Login for ");
+	passphraseDialog = new PassphraseDialog(f, phrase + entity + ":");
+	passphraseDialog.setVisible(true);
+    }
+
+    public GUILoginDialog(String entity, Callback[] callbacks) {
+        this.entity = entity;
+	String phrase = localStrings.getLocalString("enterprise.security.loginPhrase", "Login for ");
+	JFrame f = new JFrame();
+	passphraseDialog = new PassphraseDialog(f, phrase + entity + ":", callbacks);
+	passphraseDialog.setVisible(true);
+    }
+
+
+    /**
+     * @return The username of the user.
+     */
+    public String getUserName() {
+	return passphraseDialog.username;
+    }
+
+    /**
+     *@return The password of the user in plain text...
+     */
+    public final char[] getPassword() {
+        char[] temp = passphraseDialog.passphrase;
+        return (temp == null) ? null : Arrays.copyOf(temp, temp.length);
+    }
+}
+
+
+/**
+ * Create a popup dialog box to ask for the passphrase.
+ */
+class PassphraseDialog extends JDialog 
+{
+    private NameCallback nameCallback = null;;
+    private PasswordCallback passwordCallback = null;
+    private ChoiceCallback choiceCallback = null;
+    private JTextField	userField;
+    private JPasswordField	passField;
+    private JList	choiceList;
+    private JFrame frame;
+    private JButton	okButton;
+    private JButton	cancelButton;
+    // buttons for keystore password
+    private JButton     okForKP;
+    private JButton     cancelForKP;
+
+    private static LocalStringManagerImpl localStrings =
+	new LocalStringManagerImpl(PassphraseDialog.class);
+    String username = "";
+    char[] passphrase = null;
+
+    private JPasswordField keystorePassword;
+    private JLabel lbl;
+    // parent panel for keystore password
+    private JPanel pnl = new JPanel (new GridLayout (2, 0));
+    // panel for buttons for keystore password
+    private JPanel bpanel = new JPanel (new FlowLayout ());
+    private JPanel kpPanel = new JPanel (new FlowLayout ());
+    private final String pnlKeyStorePassword = "Keystore Password Box";
+    private final String pnlCertificateList = "Cerificate Chooser";
+    // panel for certificate list
+    private JPanel pnl2 = new JPanel ();
+    /**
+     * Create a dialog box with a frame and title.
+     *
+     * @param frame The parent frame.
+     * @param title The dialog box title.
+     */
+    protected PassphraseDialog (JFrame frame, String title) {
+        super(frame, title, true);
+	this.frame = frame;
+        super.dialogInit();
+	initbox();
+    }
+
+    /**
+     * Create a dialog box with a frame and title.
+     *
+     * @param frame The parent frame.
+     * @param title The dialog box title.
+     */
+    protected PassphraseDialog (JFrame frame,
+				String title,
+				Callback[] callbacks) {
+
+        super(frame, title, true);
+	this.frame = frame;
+        super.dialogInit();
+
+	for(int i = 0; i < callbacks.length; i++) {
+	    if(callbacks[i] instanceof NameCallback) {
+		nameCallback = (NameCallback) callbacks[i];
+	    } else if(callbacks[i] instanceof PasswordCallback) {
+		passwordCallback = (PasswordCallback) callbacks[i];
+	    } else if(callbacks[i] instanceof ChoiceCallback) {
+		choiceCallback = (ChoiceCallback) callbacks[i];
+	    }
+	}
+	initbox();
+    }
+  
+    private void initbox() {
+	GridBagLayout gridbag = new GridBagLayout();
+	GridBagConstraints c = new GridBagConstraints();
+	pnl2.setLayout(gridbag);
+	getContentPane ().setLayout (new CardLayout ());
+	int gridx = 0;
+	int gridy = 0;
+	
+	passField = new JPasswordField(20);
+	userField = new JTextField(20);
+	choiceList = new JList();
+
+	
+	if(nameCallback != null) {
+	    c.gridx = gridx++;
+	    c.gridy = gridy;
+	    c.anchor = GridBagConstraints.CENTER;
+	    c.insets = new Insets(20, 10, 10, 2);
+	    JLabel jl = new JLabel(nameCallback.getPrompt()+": ");
+	    gridbag.setConstraints(jl, c);
+	    pnl2.add(jl);
+	    c.gridx = gridx++;
+	    c.gridy = gridy++;
+	    c.fill = GridBagConstraints.HORIZONTAL;
+	    c.insets = new Insets(20, 3, 10, 10);
+            userField.setText(nameCallback.getDefaultName());
+	    gridbag.setConstraints(userField, c);
+            userField.selectAll();
+	    pnl2.add(userField);
+	}
+
+	// passField.setEchoChar ('*');
+
+	if(passwordCallback != null) {
+	    gridx = 0;
+	    c.gridx = gridx++;
+	    c.gridy = gridy;
+	    c.anchor = GridBagConstraints.CENTER;
+	    c.insets = new Insets(20, 10, 10, 2);
+	    JLabel l = new JLabel(passwordCallback.getPrompt());
+	    gridbag.setConstraints(l, c);
+	    pnl2.add(l);
+	    c.gridx = gridx++;
+	    c.gridy = gridy++;
+	    c.fill = GridBagConstraints.HORIZONTAL;
+	    c.insets = new Insets(20, 3, 10, 10);
+	    gridbag.setConstraints(passField, c);
+	    pnl2.add(passField);
+	}
+	if(choiceCallback != null) {
+	    /* 
+	     * For getting the KeyStore Password from the user
+	     */
+	    lbl =  new JLabel
+		(localStrings.getLocalString
+		 ("enterprise.security.keystore",
+		  "Enter the KeyStore Password "));
+	    // adding the password field
+	    keystorePassword = new JPasswordField (20);
+	    kpPanel.add (lbl);
+	    kpPanel.add (keystorePassword);
+	    /* get the keystore password */
+	    final SSLUtils sslUtils = Globals.get(SSLUtils.class);
+	    // ok button For keystore password
+	    okForKP = new
+		JButton(localStrings.getLocalString
+			( "enterprise.security.ok", " OK "));
+	    okForKP.setActionCommand ("ok");
+	
+	    okForKP.addActionListener (new ActionListener() {
+		public void actionPerformed(ActionEvent ae) {
+		    char[] passKPFromUser = keystorePassword.getPassword();
+		    if (sslUtils.verifyMasterPassword(passKPFromUser)) {
+			okForKP.setEnabled (false);
+			cancelForKP.setEnabled (false);
+			keystorePassword.setEditable (false);
+			CardLayout cl = (CardLayout) (getContentPane ()).getLayout ();
+			cl.show (getContentPane (), pnlCertificateList);
+		    } else {
+			String errmessage = localStrings.getLocalString("enterprise.security.IncorrectKeystorePassword","Incorrect Keystore Password");
+			GUIErrorDialog guierr = new GUIErrorDialog(errmessage);
+			guierr.setVisible(true);
+		    }
+                    Arrays.fill(passKPFromUser, ' ');
+		}
+	    });            
+
+	    cancelForKP = new 
+		JButton (localStrings.getLocalString
+			 ( "enterprise.security.cancel", "Cancel"));
+	    
+	    cancelForKP.setActionCommand ("cancel");
+	    cancelForKP.addActionListener (new ActionListener() {
+		public void actionPerformed(ActionEvent ae) {
+		    if (choiceCallback != null)
+			choiceCallback.setSelectedIndex (-1);
+		    frame.dispose();
+		}
+	    }
+					      );
+	    bpanel.add (okForKP);
+	    bpanel.add (cancelForKP);
+	    pnl.add (kpPanel);
+	    pnl.add (bpanel);
+	    // Adding the certificate lists.
+	    gridx = 0;
+	    c.gridx = gridx++;
+	    c.gridy = gridy;
+	    c.anchor = GridBagConstraints.CENTER;
+	    c.insets = new Insets(20, 10, 10, 2);
+	    JLabel l = new JLabel(choiceCallback.getPrompt());
+	    gridbag.setConstraints(l, c);
+	    pnl2.add(l);
+	    c.gridx = gridx++;
+	    c.gridy = gridy++;
+	    c.fill = GridBagConstraints.HORIZONTAL;
+	    c.insets = new Insets(20, 3, 10, 10);
+
+	    String[] choices = choiceCallback.getChoices();
+	    choiceList.setListData(choices);
+	    
+	    gridbag.setConstraints(choiceList, c);
+	    pnl2.add(choiceList);
+	}
+
+	okButton = new
+	    JButton(localStrings.getLocalString
+		    ( "enterprise.security.ok", " OK "));
+	// XXX I18N
+	okButton.setActionCommand ("ok");
+	okButton.addActionListener (new ActionListener() {
+	    public void actionPerformed(ActionEvent ae) {
+		username = userField.getText();
+		if(username.trim().length() > 0)
+		    nameCallback.setName(username);
+		if(passwordCallback != null) {
+                    char[] pass = passField.getPassword();
+		    //if(passphrase.trim().length() > 0) {
+		    passwordCallback.setPassword(pass);
+		    //}
+		}
+		if(choiceCallback != null) {
+		    int idx = choiceList.getSelectedIndex();
+		    if(idx != -1)
+			choiceCallback.setSelectedIndex(idx);
+		}
+                frame.dispose();
+	    }
+	}
+	    
+				       );
+
+	cancelButton = new JButton
+	    (localStrings.getLocalString
+	     ( "enterprise.security.cancel", "Cancel"));
+	cancelButton.setActionCommand ("cancel");
+	cancelButton.addActionListener (new ActionListener() {
+	    public void actionPerformed(ActionEvent ae) {
+		if (choiceCallback!=null) {
+		    choiceCallback.setSelectedIndex (-1);
+                } else {
+                    username = null;
+                    if (passphrase != null) {
+                        Arrays.fill(passphrase, ' ');
+                    }
+                    frame.dispose();
+                }
+	    }
+	}
+	);
+
+	super.addWindowListener(new WindowAdapter() {
+	    public void windowClosing(WindowEvent we) {
+		//System.out.println("IN WINDOW CLOSING");
+		//_logger.log(Level.FINE,"IN WINDOW CLOSING");
+		// send a fail back
+		if (choiceCallback != null)
+		    choiceCallback.setSelectedIndex (-1);
+		frame.dispose();
+	    }
+	});
+
+	JPanel buttonPanel = new JPanel();
+	buttonPanel.setLayout(gridbag);
+	c.insets = new Insets(5,0,5,15);
+	c.gridx = 0;
+	c.gridy = 0;
+	c.anchor = GridBagConstraints.CENTER;
+	c.fill = GridBagConstraints.NONE;
+	gridbag.setConstraints(okButton, c);
+	buttonPanel.add(okButton);
+	c.gridx = 2;
+	c.insets = new Insets(5,15,5,0);
+	gridbag.setConstraints(cancelButton, c);
+	buttonPanel.add(cancelButton);
+
+	c.gridx = 0;
+	c.gridy = gridy++;
+	c.gridwidth = 2;
+	c.insets = new Insets(0,0,5,0);
+	c.fill = GridBagConstraints.HORIZONTAL;
+	c.anchor = GridBagConstraints.WEST;
+	gridbag.setConstraints(buttonPanel, c);
+	pnl2.add(buttonPanel);
+	getContentPane ().add (pnl, pnlKeyStorePassword);
+	getContentPane ().add (pnl2, pnlCertificateList);
+	CardLayout cl = (CardLayout) (getContentPane ()).getLayout ();
+	if (choiceCallback != null){
+	    /* first get the password to the keystore */
+	    cl.show (getContentPane (), pnlKeyStorePassword);
+	} else {
+	    cl.show (getContentPane (), pnlCertificateList);
+	}
+	pack ();
+	setSize (getPreferredSize ());
+    }
+
+}
+
+/**
+ * Create a popup dialog box to ask for the passphrase.
+ */
+class CertificateDialog extends JDialog 
+{
+    private JTextField	userField;
+    private JList	certList;
+    private JFrame frame;
+    private JButton	okButton;
+    private JButton	cancelButton;
+    private static LocalStringManagerImpl localStrings =
+	new LocalStringManagerImpl(CertificateDialog.class);
+    String username = "";
+    char[] passphrase = new char[0];
+
+    /**
+     * Create a dialog box with a frame and title.
+     *
+     * @param frame The parent frame.
+     * @param title The dialog box title.
+     */
+    protected CertificateDialog (JFrame frame, String title) {
+        super(frame, title, true);
+	this.frame = frame;
+        super.dialogInit();
+	initbox();
+    }
+  
+    private void initbox() {
+	GridBagLayout gridbag = new GridBagLayout();
+	GridBagConstraints c = new GridBagConstraints();
+	getContentPane().setLayout(gridbag);
+
+	int gridx = 0;
+	int gridy = 0;
+
+	String[] list = null;
+	/**/
+	list = new String[5];
+	list[0] = "foo";
+	list[1] = "bar";
+	list[2] = "abc";
+	list[3] = "def";
+	list[4] = "ghi";
+	/**/
+
+	certList = new JList(list);
+	userField = new JTextField(20);
+
+	c.gridx = gridx++;
+	c.gridy = gridy;
+	c.anchor = GridBagConstraints.CENTER;
+	c.insets = new Insets(20, 10, 10, 2);
+	JLabel jl = new JLabel(localStrings.getLocalString("enterprise.security.login.username",
+				"Enter username:"));
+	gridbag.setConstraints(jl, c);
+	getContentPane().add(jl);
+	c.gridx = gridx++;
+	c.gridy = gridy++;
+	c.fill = GridBagConstraints.HORIZONTAL;
+	c.insets = new Insets(20, 3, 10, 10);
+	gridbag.setConstraints(userField, c);
+	getContentPane().add(userField);
+
+	gridx = 0;
+	c.gridx = gridx++;
+	c.gridy = gridy;
+	c.anchor = GridBagConstraints.CENTER;
+	c.insets = new Insets(20, 10, 10, 2);
+	JLabel l = new JLabel(localStrings.getLocalString("enterprise.security.login.password",
+				"Select a certificate:"));
+	gridbag.setConstraints(l, c);
+	getContentPane().add(l);
+	c.gridx = gridx++;
+	c.gridy = gridy++;
+	c.fill = GridBagConstraints.HORIZONTAL;
+	c.insets = new Insets(20, 3, 10, 10);
+	gridbag.setConstraints(certList, c);
+	getContentPane().add(certList);
+
+	okButton = new JButton(localStrings.getLocalString( "enterprise.security.ok", " OK "));		// XXX I18N
+	okButton.setActionCommand ("ok");
+	okButton.addActionListener (new ActionListener() {
+	    public void actionPerformed(ActionEvent ae) {
+		// System.out.println("OK Action");
+		//_logger.log(Level.FINE,"OK Action");
+		username = userField.getText();
+		//int index = certList.getSelectedIndex();
+
+		if((username.trim().length() > 0) &&
+		   (passphrase.length > 0)) {
+		    setVisible(false);
+		}
+	    }
+	}
+	);
+
+	cancelButton = new JButton(localStrings.getLocalString( "enterprise.security.cancel", "Cancel"));		// XXX I18N
+	cancelButton.setActionCommand ("cancel");
+	cancelButton.addActionListener (new ActionListener() {
+	    public void actionPerformed(ActionEvent ae) {
+		// System.out.println("Cancel Action");
+                // _logger.log(Level.FINE,"Cancel Action");
+		// username = null;
+		// passphrase = null;
+		// setVisible(false);
+		java.awt.Toolkit.getDefaultToolkit().beep();
+	    }
+	}
+	);
+
+	super.addWindowListener(new WindowAdapter() {
+	    public void windowClosing(WindowEvent we) {
+		// System.out.println("IN WINDOW CLOSING");
+		// _logger.log(Level.FINE,"IN WINDOW CLOSING");
+		frame.dispose();
+	    }
+	});
+
+	JPanel buttonPanel = new JPanel();
+	buttonPanel.setLayout(gridbag);
+	c.insets = new Insets(5,0,5,15);
+	c.gridx = 0;
+	c.gridy = 0;
+	c.anchor = GridBagConstraints.CENTER;
+	c.fill = GridBagConstraints.NONE;
+	gridbag.setConstraints(okButton, c);
+	buttonPanel.add(okButton);
+	c.gridx = 2;
+	c.insets = new Insets(5,15,5,0);
+	gridbag.setConstraints(cancelButton, c);
+	buttonPanel.add(cancelButton);
+
+	c.gridx = 0;
+	c.gridy = gridy++;
+	c.gridwidth = 2;
+	c.insets = new Insets(0,0,5,0);
+	c.fill = GridBagConstraints.HORIZONTAL;
+	c.anchor = GridBagConstraints.WEST;
+	gridbag.setConstraints(buttonPanel, c);
+	getContentPane().add(buttonPanel);
+
+	pack ();
+	setSize (getPreferredSize ());
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/IRealmManager.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/IRealmManager.java
new file mode 100644
index 0000000..0390967
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/IRealmManager.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+/**
+ * This is an remote interface provided to the RealmManager
+ * This allows the realms to be updated while the server is
+ * running.
+ * @author Harpreet Singh (harpreet.singh@sun.com)
+ */
+public interface IRealmManager extends java.rmi.Remote{
+
+    /** 
+     * This refreshes the realm information. This is used by 
+     * a client program e.g. realmtool. The client manipulates
+     * the realm information and then calls this method. This then
+     * updates the realm information in an already running server.
+     * If the server is not running the call should not be made. 
+     * This interface is obtained by looking up the <i>RealmManager</> 
+     * from the Naming service.
+     * @param String realmName
+     */
+    public void refreshRealms(String realmName) 
+	throws java.rmi.RemoteException;
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/LocalStrings.properties b/nucleus/security/core/src/main/java/com/sun/enterprise/security/LocalStrings.properties
new file mode 100644
index 0000000..213ed0b
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/LocalStrings.properties
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+enterprise.security.defaultEntity=user
+enterprise.security.loginPhrase=Login for 
+enterprise.security.username=Username:
+enterprise.security.password=Password:
+enterprise.security.ok= OK 
+enterprise.security.cancel=Cancel
+enterprise.security.looking_up_authenticator=Looking up authenticator...
+enterprise.security.login_failed=Login Failed.
+enterprise.security.login.username=Enter Username
+enterprise.security.login.password=Enter Password:
+enterprise.security.audit_log_invocation=Audit Log: Invocation
+enterprise.security.failed=Failed
+enterprise.security.keystore=Enter the KeyStore Password
+enterprise.security.IncorrectKeystorePassword=Incorrect keystore password
+enterprise.security.keytool=keytool
+enterprise.security.keytooloptions=Options:
+enterprise.security.plcyload.not14=Policy class is not an instance of java.security.Policy.
+enterprise.security.plcyload.not13=Policy class is not an instance of javax.security.auth.Policy.
+enterprise.security.securityutil.norolemapper=No Security RoleMapper. Role to Principal Information missing. Required to deploy Applications.
+enterprise.security.upgrade.warning=Upgrade from v2 EE  to v3.1 requires manual steps. Please refer to the v3.1 Upgrade Guide for details.
+j2ee.norolemapper=Cannot instantiate the SecurityRoleMapperFactory
+j2ee.startupslow=Cannot write the seed file for fast startup. The next startup will be slow.
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/LoginContext.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/LoginContext.java
new file mode 100644
index 0000000..59ac3ee
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/LoginContext.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import com.sun.enterprise.security.auth.login.common.LoginException;
+import com.sun.enterprise.security.common.AppservAccessController;
+import java.security.PrivilegedAction;
+
+import com.sun.enterprise.security.auth.login.ClientPasswordLoginModule;
+import com.sun.enterprise.security.auth.login.LoginContextDriver;
+import com.sun.enterprise.security.common.SecurityConstants;
+import java.util.logging.*;
+import com.sun.logging.*;
+
+/** 
+ * This class is kept for CTS. Ideally we should move away from it.
+ * The login can be done via the following call:
+ * <pre>
+ * // Initialize the ORB.
+ * try {
+ *   LoginContext lc = new LoginContext();
+ *   lc.login("john", "john123");
+ * } catch (LoginException le) {
+ *   le.printStackTrace();
+ * }
+ *
+ *
+ * </PRE>
+ *
+ * Ideally the login should be done with the system property -Dj2eelogin.name and -Dj2eelogin.password
+ *
+ * @author Harpreet Singh (hsingh@eng.sun.com)
+ */
+
+public final class LoginContext {
+    
+    private static Logger _logger=null;
+    static{
+       _logger = SecurityLoggerInfo.getLogger();
+   }
+
+    private boolean guiAuth = false;
+
+    // declaring this different from the Appcontainer as 
+    // this will be called from standalone clients.
+    public javax.security.auth.callback.CallbackHandler handler = null;
+    
+    /**
+     * Creates the LoginContext with the defauly callback handler
+     */
+    public LoginContext () {
+	handler = new com.sun.enterprise.security.auth.login.LoginCallbackHandler(guiAuth);
+    }
+    
+    /** 
+     * Login method to login username and password
+     */
+    public void login(String user, String pass) throws LoginException{
+	final String username = user;
+	final String password = pass;
+	AppservAccessController.doPrivileged(new PrivilegedAction() {
+	    public java.lang.Object run() {
+		
+		System.setProperty(ClientPasswordLoginModule.LOGIN_NAME,
+				   username);
+		System.setProperty(ClientPasswordLoginModule.LOGIN_PASSWORD, 
+				   password);
+
+		    return null;
+		}
+	    });
+	// Since this is  a private api and the user is not supposed to use
+	// this. We use the default the LoginCallbackHandler.
+	LoginContextDriver.doClientLogin(SecurityConstants.USERNAME_PASSWORD,handler);
+    }
+    
+    /** This method has been provided to satisfy the CTS Porting Package 
+     * requirement for logging in a certificate
+     */
+    public void login(String username, byte[] authData) 
+	throws LoginException{
+    
+	    // do nothing
+    }
+
+}
+
+
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/LoginDialog.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/LoginDialog.java
new file mode 100644
index 0000000..25bad63
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/LoginDialog.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+/**
+ * LoginManager needs implementations of this class for accessing the
+ * username and passwords.
+ * Implementations of LoginDialog can use either character based terminal,
+ * GUI, or any other form of querying to get hold of the username & password
+ * from the user.
+ *
+ * @author Harish Prabandham
+ */
+public interface LoginDialog {
+    /**
+     * @return The username of the user.
+     */
+    public String getUserName();
+    /**
+     *@return The password of the user in plain text...
+     */
+    public char[] getPassword();
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/PolicyLoader.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/PolicyLoader.java
new file mode 100644
index 0000000..0c0ccd0
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/PolicyLoader.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import java.util.logging.*;
+
+//V3:Commented import com.sun.enterprise.server.ApplicationServer;
+import com.sun.enterprise.config.serverbeans.JaccProvider;
+//V3:Commented import com.sun.enterprise.config.serverbeans.ElementProperty;
+//V3:Commented import com.sun.enterprise.config.ConfigContext;
+import org.glassfish.hk2.api.IterableProvider;
+import org.jvnet.hk2.config.types.Property;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.util.i18n.StringManager;
+import java.util.List;
+import org.glassfish.api.admin.ServerEnvironment;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+
+import org.jvnet.hk2.annotations.Service;
+import javax.inject.Singleton;
+
+/**
+ * Loads the Default Policy File into the system.
+ *
+ * @author Harpreet Singh
+ * @author Jyri J. Virkki
+ *
+ */
+@Service
+@Singleton
+public class PolicyLoader{
+    
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private SecurityService securityService;
+    
+    @Inject
+    private IterableProvider<JaccProvider> jaccProviders;
+     
+    private static Logger _logger = null;
+    static {
+        _logger = SecurityLoggerInfo.getLogger();
+    }
+    private static StringManager sm = StringManager.getManager(PolicyLoader.class);
+
+    private static final String POLICY_PROVIDER_14 = 
+        "javax.security.jacc.policy.provider";
+    private static final String POLICY_PROVIDER_13 = 
+        "javax.security.jacc.auth.policy.provider";
+    private static final String POLICY_CONF_FACTORY = 
+        "javax.security.jacc.PolicyConfigurationFactory.provider";
+    private static final String POLICY_PROP_PREFIX =
+        "com.sun.enterprise.jaccprovider.property.";
+    private boolean isPolicyInstalled = false;
+
+    
+    /**
+     * Attempts to install the policy-provider. The policy-provider
+     * element in domain.xml is consulted for the class to use. Note
+     * that if the javax.security.jacc.policy.provider system property
+     * is set it will override the domain.xml configuration. This will
+     * normally not be the case in S1AS.
+     *
+     * <P>The J2EE 1.3 property javax.security.jacc.auth.policy.provider is
+     * checked as a last resort. It should not be set in J2EE 1.4.
+     *
+     */
+    public void loadPolicy() {
+
+        if (isPolicyInstalled) {
+            _logger.log(Level.FINE,
+                        "Policy already installed. Will not re-install.");
+            return;
+        }
+        // get config object
+        JaccProvider jacc = getConfiguredJaccProvider();
+        // set config properties (see method comments)
+        setPolicyConfigurationFactory(jacc);
+        
+        boolean j2ee13 = false;
+        
+
+        // check if system property is set
+        String javaPolicy = System.getProperty(POLICY_PROVIDER_14);
+
+        if (javaPolicy !=null) {
+            // inform user domain.xml is being ignored
+            _logger.log(Level.INFO, SecurityLoggerInfo.policyProviderConfigOverrideMsg,
+                        new String[] { POLICY_PROVIDER_14, javaPolicy } );
+        } else {
+            // otherwise obtain JACC policy-provider from domain.xml
+            if (jacc != null) {
+                javaPolicy = jacc.getPolicyProvider();
+            }
+        }
+        
+        if (javaPolicy == null) {
+            javaPolicy = System.getProperty(POLICY_PROVIDER_13);
+            if (javaPolicy != null) {
+                // warn user j2ee13 property is being used
+                j2ee13 = true;
+                _logger.log(Level.WARNING, SecurityLoggerInfo.policyProviderConfigOverrideWarning,
+                            new String[] { POLICY_PROVIDER_13, javaPolicy} );
+            }
+        }
+
+        // now install the policy provider if one was identified
+        if (javaPolicy != null) {
+
+            try {
+                _logger.log(Level.INFO, SecurityLoggerInfo.policyLoading, javaPolicy);
+                
+                //Object obj = Class.forName(javaPolicy).newInstance();
+                ClassLoader loader = Thread.currentThread().getContextClassLoader();
+                Class javaPolicyClass = loader.loadClass(javaPolicy);
+                Object obj = javaPolicyClass.newInstance();
+                if (j2ee13) {
+                    // Use JDK 1.3 classes if j2ee1 3 property being used
+                    if (!(obj instanceof javax.security.auth.Policy)) {
+                        String msg = 
+                            sm.getString("enterprise.security.plcyload.not13");
+                        throw new RuntimeException(msg);
+                    }
+                    javax.security.auth.Policy policy =
+                        (javax.security.auth.Policy)obj;
+                    javax.security.auth.Policy.setPolicy(policy);
+                    policy.refresh();
+                    
+                } else {
+                    // Otherwise use JDK 1.4 classes.
+                    if (!(obj instanceof java.security.Policy)) {
+                        String msg = 
+                            sm.getString("enterprise.security.plcyload.not14");
+                        throw new RuntimeException(msg);
+                    }
+                    java.security.Policy policy = (java.security.Policy)obj;
+                    java.security.Policy.setPolicy(policy);
+                    //TODO: causing ClassCircularity error when SM ON and
+                    //deployment use library feature and ApplibClassLoader
+                    //it is likely a problem caused by the way classloading is done
+                    //in this case.
+                    if (System.getSecurityManager() == null) {
+                        policy.refresh();
+                    }
+                }
+
+            } catch (Exception e) {
+                _logger.log(Level.SEVERE, SecurityLoggerInfo.policyInstallError,
+                            e.getLocalizedMessage());
+                throw new RuntimeException(e);
+            }
+            // Success.
+            _logger.fine("Policy set to: " + javaPolicy);
+            isPolicyInstalled = true;
+            
+        } else {
+            // no value for policy provider found
+            _logger.warning(SecurityLoggerInfo.policyNotLoadingWarning);
+        }
+    }
+
+
+    /**
+     * Returns a JaccProvider object representing the jacc element from
+     * domain.xml which is configured in security-service.
+     *
+     * @return The config object or null on errors.
+     *
+     */
+    private JaccProvider getConfiguredJaccProvider() {
+        JaccProvider jacc = null;
+        try {
+            String name = securityService.getJacc();
+            jacc = getJaccProviderByName(name);
+            if (jacc == null) {
+                _logger.log(Level.WARNING, SecurityLoggerInfo.policyNoSuchName, name);
+            }
+        } catch (Exception e) {
+            _logger.warning(SecurityLoggerInfo.policyReadingError);
+            jacc = null;
+        }
+        return jacc;
+    }
+
+    private JaccProvider getJaccProviderByName(String name) {
+       if (jaccProviders == null || name == null) {
+           return null;    
+       }
+
+       for (JaccProvider jaccProvider : jaccProviders) {
+           if (jaccProvider.getName().equals(name)) {
+               return jaccProvider;
+           }
+       }
+       return null;
+    }
+    
+    /**
+     * Set internal properties based on domain.xml configuration.
+     *
+     * <P>The POLICY_CONF_FACTORY property is consumed by the jacc-api
+     * as documented in JACC specification. It's value is set here to the
+     * value given in domain.xml <i>unless</i> it is already set in which
+     * case the value is not modified.
+     *
+     * <P>Then and properties associated with this jacc provider from
+     * domain.xml are set as internal properties prefixed with
+     * POLICY_PROP_PREFIX. This is currently a workaround for bug 4846938.
+     * A cleaner interface should be adopted.
+     *
+     */
+    private void setPolicyConfigurationFactory(JaccProvider jacc) {
+
+        if (jacc == null) {
+            return;
+        }
+        // Handle JACC-specified property for factory
+        //TODO:V3 system property being read here
+        String prop = System.getProperty(POLICY_CONF_FACTORY);
+        if (prop != null) {
+            // warn user of override
+            _logger.log(Level.WARNING, SecurityLoggerInfo.policyFactoryOverride,
+                        new String[] { POLICY_CONF_FACTORY, prop } );
+            
+        } else {
+            // use domain.xml value by setting the property to it
+            String factory = jacc.getPolicyConfigurationFactoryProvider();
+            if (factory == null) {
+                _logger.log(Level.WARNING, SecurityLoggerInfo.policyConfigFactoryNotDefined);
+            } else {
+                System.setProperty(POLICY_CONF_FACTORY, factory);
+            }
+        }
+        
+        // Next, make properties of this jacc provider available to provider
+        List<Property> props = jacc.getProperty();
+        for (Property p: props) {
+            String name = POLICY_PROP_PREFIX + p.getName();
+            String value = p.getValue();
+            _logger.finest("PolicyLoader set ["+name+"] to ["+value+"]");
+            System.setProperty(name, value);
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/PrincipalGroupFactory.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/PrincipalGroupFactory.java
new file mode 100644
index 0000000..4de3d21
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/PrincipalGroupFactory.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import org.glassfish.security.common.Group;
+import org.glassfish.security.common.PrincipalImpl;
+import org.jvnet.hk2.annotations.Contract;
+
+/**
+ * Factory for Group and Principal instances.
+ */
+@Contract
+public interface PrincipalGroupFactory {
+
+    PrincipalImpl getPrincipalInstance(String name, String realm);
+
+    Group getGroupInstance(String name, String realm);
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityConfigListener.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityConfigListener.java
new file mode 100644
index 0000000..036fb60
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityConfigListener.java
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import org.jvnet.hk2.config.*;
+import org.jvnet.hk2.config.types.Property;
+
+import javax.inject.Singleton;
+import org.jvnet.hk2.annotations.Service;
+import javax.inject.Inject;
+
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.JaccProvider;
+import com.sun.enterprise.config.serverbeans.AuditModule;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.MessageSecurityConfig;
+
+import com.sun.enterprise.security.audit.BaseAuditManager;
+import com.sun.enterprise.security.auth.realm.Realm;
+import com.sun.enterprise.security.auth.realm.RealmsManager;
+import java.beans.PropertyChangeEvent;
+import java.util.List;
+import java.util.Properties;
+import java.util.logging.Logger;
+import javax.inject.Named;
+import javax.security.auth.login.Configuration;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.hk2.api.PostConstruct;
+
+/**
+ *
+ * @author kumar.jayanti
+ */
+@Service
+@Singleton
+public class SecurityConfigListener implements ConfigListener, PostConstruct {
+    
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    SecurityService securityService;
+    
+    @Inject
+    private Logger logger;
+    
+    @Inject
+    private RealmsManager realmsManager;
+
+    @Inject
+    BaseAuditManager auditManager;
+    
+    private String auditEnabled = null;
+    private String defaultRealm = null;
+    private String jacc = null;
+    private String activateDefaultP2RMapping = null;
+    private String mappedPrincipalClassName = null;
+
+    public SecurityConfigListener() {
+        
+    }
+     /**
+     * Notification that @Configured objects that were injected have changed
+     *
+     * @param events list of changes
+     */
+public UnprocessedChangeEvents changed(PropertyChangeEvent[] events) {
+    // I am not so interested with the list of events, just sort who got added or removed for me.
+    ConfigSupport.sortAndDispatch(events, new Changed() {
+        /**
+         * Notification of a change on a configuration object
+         *
+         * @param type            type of change : ADD mean the changedInstance was added to the parent
+         *                        REMOVE means the changedInstance was removed from the parent, CHANGE means the
+         *                        changedInstance has mutated.
+         * @param changedType     type of the configuration object
+         * @param changedInstance changed instance.
+         */
+        public <T extends ConfigBeanProxy> NotProcessed changed(TYPE type, Class<T> changedType, T changedInstance) {
+            NotProcessed np = null;
+            switch(type) {
+                case ADD : logger.fine("A new " + changedType.getName() + " was added : " + changedInstance);
+                    np = handleAddEvent(changedInstance);
+                    break;
+
+                case CHANGE : logger.fine("A " + changedType.getName() + " was changed : " + changedInstance);
+                    np = handleChangeEvent(changedInstance);
+                    break;
+
+                case REMOVE : logger.fine("A " + changedType.getName() + " was removed : " + changedInstance);
+                    np = handleRemoveEvent(changedInstance);
+                    break;
+            }
+            return np;
+        }
+
+        private <T extends ConfigBeanProxy> NotProcessed handleAddEvent( T instance) {
+            NotProcessed np = null;
+            if(instance instanceof AuthRealm){
+                authRealmCreated((AuthRealm)instance);
+            }else if (instance instanceof JaccProvider){
+                np = new NotProcessed( "Cannot change JACC provider once installed, restart required" );
+                //inject PolicyLoader and try to call loadPolicy
+                //but policyLoader in V2 does not allow reloading of policy provider
+                //once installed. The only option is restart the server
+            }else if (instance instanceof AuditModule){
+                auditModuleCreated((AuditModule)instance);
+            }else if (instance instanceof MessageSecurityConfig){
+                // do nothing since we have a Message security config listener
+            } else if (instance instanceof SecurityService) {
+               //since everything exists the only thing that can be added
+               // in terms of Attrs is the defaultPrincipal and defaultPrinPassword
+               // but they are directly used from securityService in core/security
+            }
+            else {
+                np = new NotProcessed( "unimplemented: unknown instance: " + instance.getClass().getName() );
+            }
+            return np;
+        }
+
+        private <T extends ConfigBeanProxy> NotProcessed handleRemoveEvent(final T instance) {
+            NotProcessed np = null;
+            if(instance instanceof AuthRealm){
+                authRealmDeleted((AuthRealm)instance);
+            }else if (instance instanceof JaccProvider){
+                np = new NotProcessed( "Cannot change JACC provider once installed, restart required" );
+                //inject PolicyLoader and try to call loadPolicy
+                //but policyLoader in V2 does not allow reloading of policy provider
+                //once installed. The only option is restart the server
+            }else if (instance instanceof AuditModule){
+                auditModuleDeleted((AuditModule)instance);
+            }else if (instance instanceof MessageSecurityConfig){
+               //do nothing since we have a message security config listener
+            } else if (instance instanceof SecurityService) {
+               // The only Attrs on securityService whose removal can affect the
+               // security code are those which are stored explicitly
+               // they are getAuditEnabled, getDefaultRealm and getAuditModules
+               // not sure what the effect of removing getDefaultRealm
+            }
+            else {
+                np = new NotProcessed( "unimplemented: unknown instance: " + instance.getClass().getName() );
+            }
+            return np;
+        }
+        
+        private <T extends ConfigBeanProxy> NotProcessed handleChangeEvent(final T instance) {
+            NotProcessed np = null;
+            if(instance instanceof AuthRealm){
+                authRealmUpdated((AuthRealm)instance);
+            }else if (instance instanceof JaccProvider){
+                np = new NotProcessed( "Cannot change JACC provider once installed, restart required" );
+                //inject PolicyLoader and try to call loadPolicy
+                //but policyLoader in V2 does not allow reloading of policy provider
+                //once installed. The only option is restart the server
+            }else if (instance instanceof AuditModule){
+                auditModuleUpdated((AuditModule)instance);
+            }else if (instance instanceof MessageSecurityConfig){
+               //do nothing since we have a message security config listener
+            } else if (instance instanceof SecurityService) {
+               // The only Attrs on securityService whose change in value can affect the
+               // security code are those which are stored explicitly
+               // they are getAuditEnabled, getDefaultRealm and getAuditModules
+               if (defaultRealm != null && 
+                       !defaultRealm.equals(((SecurityService)instance).getDefaultRealm())) {
+                   defaultRealm = ((SecurityService)instance).getDefaultRealm();
+                   Realm.setDefaultRealm(defaultRealm);
+               }
+               if ((auditEnabled != null) &&
+                       !auditEnabled.equals(((SecurityService)instance).getAuditEnabled())) {
+                   boolean auditON = Boolean.parseBoolean(((SecurityService)instance).getAuditEnabled());
+                   auditManager.setAuditOn(auditON);
+               }
+               if (!jacc.equals(((SecurityService)instance).getJacc())) {
+                   np = new NotProcessed( "Cannot change JACC provider once installed, restart required" );
+               }
+               if ((mappedPrincipalClassName != null) && !mappedPrincipalClassName.equals(((SecurityService)instance).getMappedPrincipalClass())) {
+                   np = new NotProcessed( "MappedPrincipalClassname changes for existing applications requires restart and redeployment" );
+               }
+               if (!activateDefaultP2RMapping.equals(((SecurityService)instance).getActivateDefaultPrincipalToRoleMapping())) {
+                   np = new NotProcessed( "DefaultP2R changes for existng applications requires restart and redeployment" );
+               }
+            }
+            else {
+                np = new NotProcessed( "unimplemented: unknown instance: " + instance.getClass().getName() );
+            }
+            return np;
+        }
+    }, logger);
+     return null;
+}
+
+    /**
+     * New auth realm created.
+     * It is called whenever a AuthRealmEvent with action of
+     * AuthRealmEvent.ACTION_CREATE is received.
+     * @throws AdminEventListenerException when the listener is unable to
+     *         process the event.
+     */
+    public static void authRealmCreated(AuthRealm instance){
+        try {
+            createRealm(instance);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * New auth realm created.
+     * It is called whenever a AuthRealmEvent with action of
+     * AuthRealmEvent.ACTION_CREATE is received.
+     * @throws AdminEventListenerException when the listener is unable to
+     *         process the event.
+     */
+    public static void authRealmCreated(Config config, AuthRealm instance){
+        try {
+            createRealm(config, instance);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Auth realm deleted.
+     * It is called whenever a AuthRealmEvent with action of
+     * AuthRealmEvent.ACTION_DELETE is received.
+     * @throws AdminEventListenerException when the listener is unable to
+     *         process the event.
+     */
+    public static void authRealmDeleted(Config config, AuthRealm instance) {
+        try {
+            //the listener firing has been unpredictable earlier
+            //after a CLI delete the listener's were not firing in time
+            //so we added explicit calls to this method from CLI
+            //now with latest builds it looks like listeners also fire
+            //causing a NoSuchRealmException
+            if (!Realm.isValidRealm(config.getName(), instance.getName())) {
+                return;
+            }
+            Realm.unloadInstance(config.getName(), instance.getName());
+        } catch (NoSuchRealmException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+
+    /**
+     * Auth realm deleted.
+     * It is called whenever a AuthRealmEvent with action of
+     * AuthRealmEvent.ACTION_DELETE is received.
+     * @throws AdminEventListenerException when the listener is unable to
+     *         process the event.
+     */
+    public static void authRealmDeleted(AuthRealm instance) {
+        try {
+            //the listener firing has been unpredictable earlier
+            //after a CLI delete the listener's were not firing in time
+            //so we added explicit calls to this method from CLI
+            //now with latest builds it looks like listeners also fire
+            //causing a NoSuchRealmException
+            if (!Realm.isValidRealm(instance.getName())) {
+                return;
+            }
+            Realm.unloadInstance(instance.getName());
+        } catch (NoSuchRealmException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Auth realm updated (attributes change).
+     * It is called whenever a AuthRealmEvent with action of
+     * AuthRealmEvent.ACTION_UPDATE is received.
+     * @throws AdminEventListenerException when the listener is unable to
+     *         process the event.
+     */
+    public void authRealmUpdated(AuthRealm instance) {
+        try {
+            realmsManager.removeFromLoadedRealms(instance.getName());
+            createRealm(instance);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Auth realm updated (attributes change).
+     * It is called whenever a AuthRealmEvent with action of
+     * AuthRealmEvent.ACTION_UPDATE is received.
+     * @throws AdminEventListenerException when the listener is unable to
+     *         process the event.
+     */
+    public void authRealmUpdated(Config config, AuthRealm instance) {
+        try {
+            realmsManager.removeFromLoadedRealms(config.getName(),instance.getName());
+            createRealm(config, instance);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * This method will create or replace existing realm with a new one
+     * in cache.
+     * @param event
+     * @exception for instance, BadRealmException, ConfigException,
+     *            SynchronizationException
+     */
+    private static void createRealm(AuthRealm authRealm) throws Exception {
+        //authRealm cannot be null here
+        String className = authRealm.getClassname();
+        List<Property> elementProps = authRealm.getProperty();
+        Properties props = new Properties();
+        if (elementProps != null) {
+            for (Property p : elementProps) {
+                props.setProperty(p.getName(), p.getValue());
+            }
+        }
+        Realm.instantiate(authRealm.getName(), className, props);
+        Configuration.getConfiguration().refresh();
+    }
+
+    /**
+     * This method will create or replace existing realm with a new one
+     * in cache.
+     * @param event
+     * @exception for instance, BadRealmException, ConfigException,
+     *            SynchronizationException
+     */
+    private static void createRealm(Config config, AuthRealm authRealm) throws Exception {
+        //authRealm cannot be null here
+        String className = authRealm.getClassname();
+        List<Property> elementProps = authRealm.getProperty();
+        Properties props = new Properties();
+        if (elementProps != null) {
+            for (Property p : elementProps) {
+                props.setProperty(p.getName(), p.getValue());
+            }
+        }
+        Realm.instantiate(authRealm.getName(), className, props, config.getName());
+        Configuration.getConfiguration().refresh();
+    }
+
+    public void postConstruct() {
+        if (securityService == null) {
+            //should never happen
+            return;
+        }
+        //the first 3 of them below are not stored anywhere and directly
+        //used from securityService instance available
+        //even defaultPrincipal and defaultPrincipalPassword is directly being
+        //read from securityService.
+        auditEnabled = securityService.getAuditEnabled();
+        defaultRealm = securityService.getDefaultRealm();        
+        jacc = securityService.getJacc();      
+        if(jacc == null) {
+            jacc = "default";
+        }
+        activateDefaultP2RMapping = securityService.getActivateDefaultPrincipalToRoleMapping();
+        mappedPrincipalClassName = securityService.getMappedPrincipalClass();
+        
+    }
+    
+    /**
+     * New audit module created.
+     * It is called whenever a AuditModuleEvent with action of
+     * AuditModuleEvent.ACTION_CREATE is received.
+     */
+    public void auditModuleCreated(AuditModule instance) {
+        try {
+            String classname = instance.getClassname();
+            List<Property> props = instance.getProperty();
+            Properties properties = new Properties();
+            if (props != null) {
+                for (Property p : props) {
+                    properties.put(p.getName(), p.getValue());
+                }
+            }
+            auditManager.addAuditModule(instance.getName(), classname, properties);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Audit module deleted.
+     * It is called whenever a AuditModuleEvent with action of
+     * AuditModuleEvent.ACTION_DELETE is received.
+     */
+    public void auditModuleDeleted(AuditModule instance) {
+       
+        auditManager.removeAuditModule(instance.getName());
+    }
+
+    /**
+     * Audit module updated (attributes change).
+     * It is called whenever a AuditModuleEvent with action of
+     * AuditModuleEvent.ACTION_UPDATE is received.
+     */
+    public void auditModuleUpdated(AuditModule instance) {
+        try {
+
+            List<Property> props = instance.getProperty();
+            Properties properties = new Properties();
+            if (props != null) {
+                for (Property p : props) {
+                    properties.put(p.getName(), p.getValue());
+                }
+            }
+            // we don't have a way to get hold of the Old Module in V3
+            // so we would always delete and create new
+           
+            auditManager.addAuditModule(instance.getName(), instance.getClassname(), properties);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+
+    
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityContext.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityContext.java
new file mode 100644
index 0000000..70d62f4
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityContext.java
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import com.sun.enterprise.security.integration.AppServSecurityContext;
+import com.sun.enterprise.security.common.AppservAccessController;
+import com.sun.enterprise.security.common.AbstractSecurityContext;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import java.security.Principal;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedAction;
+import javax.security.auth.Subject;
+
+import org.glassfish.internal.api.Globals;
+import org.glassfish.security.common.PrincipalImpl;
+import com.sun.enterprise.config.serverbeans.*;
+import com.sun.enterprise.security.auth.login.DistinguishedPrincipalCredential;
+//V3:Comment import com.sun.enterprise.server.ApplicationServer;
+import java.security.AccessController;
+import org.glassfish.api.admin.ServerEnvironment;
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+
+/**
+* This  class that extends AbstractSecurityContext that gets 
+ * stored in Thread Local Storage. If the current thread creates
+ * child threads, the SecurityContext stored in the current 
+ * thread is automatically propagated to the child threads.
+ * 
+ * This class is used on the server side to represent the 
+ * security context.
+ *
+ * Thread Local Storage is a concept introduced in JDK1.2.
+ * @see java.lang.ThreadLocal
+ * @see java.lang.InheritableThreadLocal
+ * 
+ * @author Harish Prabandham
+ * @author Harpreet Singh
+ */
+@Service
+@PerLookup
+public class SecurityContext extends AbstractSecurityContext  {
+   
+    private static Logger _logger=null;
+    static {
+        _logger=SecurityLoggerInfo.getLogger();
+    }
+
+    private static InheritableThreadLocal<SecurityContext> currentSecCtx =
+        new InheritableThreadLocal<SecurityContext>();
+    private static SecurityContext defaultSecurityContext = 
+	generateDefaultSecurityContext();
+
+    private static javax.security.auth.AuthPermission doAsPrivilegedPerm =
+ 	new javax.security.auth.AuthPermission("doAsPrivileged");
+ 
+    // Did the client log in as or did the server generate the context 
+    private boolean SERVER_GENERATED_SECURITY_CONTEXT = false;
+
+
+    /* This creates a new SecurityContext object.
+     * Note: that the docs for Subject state that the internal sets
+     * (eg. the principal set) cannot be modified unless the caller 
+     * has the modifyPrincipals AuthPermission. That said, there may
+     * be some value to setting the Subject read only.
+     * Note: changing the principals in the embedded subject (after
+     * construction will likely cause problem in the principal set 
+     * keyed HashMaps of EJBSecurityManager.
+     * @param username The name of the user/caller principal.
+     * @param subject contains the authenticated principals and credential.
+     */
+    public SecurityContext(String userName, Subject subject) {
+	Subject s = subject;
+	if (s == null) {
+	    s = new Subject();
+            if (_logger.isLoggable(Level.WARNING)) {
+	        _logger.warning(SecurityLoggerInfo.nullSubjectWarning);
+            }
+	} 
+	this.initiator = new PrincipalImpl(userName);
+        final Subject sub = s;
+        this.subject = (Subject)
+            AppservAccessController.doPrivileged(new PrivilegedAction(){
+                public java.lang.Object run() {
+                    sub.getPrincipals().add(initiator);
+                    return sub;
+                }
+            });
+    }
+
+    /**
+     * Create a SecurityContext with given subject having
+     * DistinguishedPrincipalCredential.
+     * This is used for JMAC environment.
+     * @param subject
+     */
+    public SecurityContext(Subject subject) {
+        if (subject == null) {
+            subject = new Subject();
+            if (_logger.isLoggable(Level.WARNING)) {
+                _logger.warning(SecurityLoggerInfo.nullSubjectWarning);
+            }
+	} 
+
+        final Subject fsub = subject;
+        this.subject = subject;
+        this.initiator = (Principal)
+            AppservAccessController.doPrivileged(new PrivilegedAction(){
+                public java.lang.Object run() {
+                    Principal prin = null;
+                    for (Object obj : fsub.getPublicCredentials()) {
+                        if (obj instanceof DistinguishedPrincipalCredential) {
+                            DistinguishedPrincipalCredential dpc =
+                                    (DistinguishedPrincipalCredential) obj;
+                            prin = dpc.getPrincipal();
+                            break;
+                        }
+                    }
+                    // for old auth module
+                    if (prin == null) {
+                        Iterator<Principal> prinIter = fsub.getPrincipals().iterator();
+                        if (prinIter.hasNext()) {
+                            prin = prinIter.next();
+                        }
+                    }
+                    return prin;
+                }
+            });
+
+            postConstruct();
+    }
+    
+    private void initDefaultCallerPrincipal() {
+         if (this.initiator == null) {
+            this.initiator = getDefaultCallerPrincipal();
+        }
+    }
+
+    public SecurityContext(String userName, Subject subject, String realm) {
+	Subject s = subject;
+	if (s == null) {
+	    s = new Subject();
+            if (_logger.isLoggable(Level.WARNING)) {
+	        _logger.warning(SecurityLoggerInfo.nullSubjectWarning);
+            }
+	}
+    PrincipalGroupFactory factory = Globals.getDefaultHabitat().getService(PrincipalGroupFactory.class);
+    if (factory!=null) {
+	    this.initiator = factory.getPrincipalInstance(userName, realm);
+    }
+        final Subject sub = s;
+        this.subject = (Subject)
+            AppservAccessController.doPrivileged(new PrivilegedAction(){
+                public java.lang.Object run() {
+                    sub.getPrincipals().add(initiator);
+                    return sub;
+                }
+            });
+    }
+    
+    /* private constructor for constructing default security context
+     */
+    public SecurityContext() {
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "Default CTOR of SecurityContext called");
+        }
+ 	this.subject = new Subject();
+	// delay assignment of caller principal until it is requested
+ 	this.initiator = null;
+ 	this.setServerGeneratedCredentials();
+        // read only is only done for guest logins.
+        AppservAccessController.doPrivileged(new PrivilegedAction(){
+            @Override
+            public Object run() {
+                subject.setReadOnly();
+                return null;
+            }
+        });
+    }
+    
+    /**
+     * Initialize the SecurityContext and handle the unauthenticated 
+     * principal case
+     */
+    public static SecurityContext init(){
+        SecurityContext sc = currentSecCtx.get();
+        if(sc == null) { // there is no current security context...
+            sc = defaultSecurityContext;
+	}
+        return sc;
+    }
+      
+    public static SecurityContext getDefaultSecurityContext(){
+        //unauthen. Security Context.
+        return defaultSecurityContext; 
+    }
+
+    public static Subject getDefaultSubject(){
+        //Subject of unauthen. Security Context.
+        return defaultSecurityContext.subject; 
+    }
+     
+    // get caller principal of unauthenticated Security Context
+    public static Principal getDefaultCallerPrincipal(){
+        synchronized(SecurityContext.class) {
+	    if (defaultSecurityContext.initiator == null) { 
+		String guestUser = null;
+		try {
+		    guestUser = (String)
+			AppservAccessController.doPrivileged(new PrivilegedExceptionAction() {
+				public java.lang.Object run() throws Exception {
+                                    SecurityService securityService = SecurityServicesUtil.getInstance().getHabitat().getService(SecurityService.class,
+                                            ServerEnvironment.DEFAULT_INSTANCE_NAME);
+                                    if(securityService==null)   return null;
+                                    return securityService.getDefaultPrincipal();
+				}
+			    });
+		} catch (Exception e) {
+		    _logger.log(Level.SEVERE,
+				SecurityLoggerInfo.defaultUserLoginError, e);
+		} finally {
+		    if (guestUser == null) {
+			guestUser = "ANONYMOUS";
+		    }
+		}
+		defaultSecurityContext.initiator = new PrincipalImpl(guestUser);
+	    }
+	}
+	return defaultSecurityContext.initiator;
+    }
+      
+    private static SecurityContext generateDefaultSecurityContext() {
+        synchronized (SecurityContext.class) {
+	    try{
+		return (SecurityContext) 
+		    AppservAccessController.doPrivileged(new PrivilegedExceptionAction() {
+			    public java.lang.Object run() throws Exception{
+				return new SecurityContext();
+			    }
+			});
+	    } catch(Exception e){
+		_logger.log(Level.SEVERE,
+			    SecurityLoggerInfo.defaultSecurityContextError,e);
+	    }
+	}
+        return null;
+    }
+    
+    /**
+     * No need to unmarshall the unauthenticated principal....
+     */
+    public static void reset(SecurityContext sc){
+	setCurrent(sc);
+    }
+
+
+    /**
+     * This method gets the SecurityContext stored in the 
+     * Thread Local Store (TLS) of the current thread. 
+     * @return The current Security Context stored in TLS. It returns
+     * null if SecurityContext could not be found in the current thread.
+     */
+    public static SecurityContext getCurrent() {
+	SecurityContext sc = currentSecCtx.get();
+ 	if (sc == null) {
+	    sc = defaultSecurityContext;
+	}
+ 	return sc;
+    }
+
+    
+    /**
+     * This method sets the SecurityContext stored in the TLS. 
+     * @param sc
+     * The Security Context that should be stored in TLS.
+     * This public static method needs to be protected
+     * such that it can only be called by container code. Otherwise
+     * it can be called by application code to set its subject (which the
+     * EJB security manager will use to create a domain combiner,
+     * and then everything the ejb does will be run as the
+     * corresponding subject.
+     */
+    public static void setCurrent(SecurityContext sc) {
+
+ 	if (sc != null && sc != defaultSecurityContext) {
+ 
+ 	    SecurityContext current = currentSecCtx.get();
+ 
+ 	    if (sc != current) {
+ 
+ 		boolean permitted = false;
+ 
+ 		try {
+		    java.lang.SecurityManager sm = System.getSecurityManager();
+		    if (sm != null) {
+			if(_logger.isLoggable(Level.FINE)){
+			    _logger.fine("permission check done to set SecurityContext");
+			}
+			sm.checkPermission(doAsPrivilegedPerm);
+		    }
+ 		    permitted = true;
+ 		} catch (java.lang.SecurityException se) {
+ 		    _logger.log(Level.SEVERE, SecurityLoggerInfo.securityContextPermissionError, se);
+ 		} catch (Throwable t) {
+ 		    _logger.log(Level.SEVERE, SecurityLoggerInfo.securityContextUnexpectedError, t);
+ 		}
+ 	    
+ 		if (permitted) {
+		    currentSecCtx.set(sc);
+		} else {
+ 		    _logger.severe(SecurityLoggerInfo.securityContextNotChangedError);
+ 		}
+ 	    }
+ 	} else {
+	    currentSecCtx.set(sc);
+	}
+    }
+   
+    public static void setUnauthenticatedContext() {
+ 	currentSecCtx.set(defaultSecurityContext);
+    }
+
+    public boolean didServerGenerateCredentials (){
+	return SERVER_GENERATED_SECURITY_CONTEXT;
+    }
+    
+    private void setServerGeneratedCredentials(){
+	SERVER_GENERATED_SECURITY_CONTEXT = true;
+    }
+
+
+    /**
+     * This method returns the caller principal. 
+     * This information may be redundant since the same information 
+     * can be inferred by inspecting the Credentials of the caller. 
+     * @return The caller Principal. 
+     */
+    public Principal getCallerPrincipal() {
+	return this == defaultSecurityContext ? getDefaultCallerPrincipal() : initiator;
+    }
+
+    
+    public Subject getSubject() {
+	return subject;
+    }
+
+
+    public String toString() {
+	return "SecurityContext[ " + "Initiator: " + 
+	    initiator + "Subject " + subject + " ]";
+    }
+
+    public Set getPrincipalSet() {
+        return subject.getPrincipals();       
+    }
+
+    public void postConstruct() {
+        initDefaultCallerPrincipal();
+    }
+
+    public AppServSecurityContext newInstance(String userName, Subject subject, String realm) {
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "SecurityContext: newInstance method called");
+        }
+        return new SecurityContext(userName, subject, realm);
+    }
+
+    public AppServSecurityContext newInstance(String userName, Subject subject) {
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "SecurityContext: newInstance method called");
+        }
+        return new SecurityContext(userName, subject);
+    }
+
+    public void setCurrentSecurityContext(AppServSecurityContext context) {
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "SecurityContext: setCurrentSecurityContext method called");
+        }
+        if (context == null) {
+            setCurrent(null);
+            return;
+        } 
+        if (context instanceof SecurityContext) {
+            setCurrent((SecurityContext)context);
+            return;
+        }
+        throw new IllegalArgumentException("Expected SecurityContext, found " + context);
+    }
+
+    public AppServSecurityContext getCurrentSecurityContext() {
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "SecurityContext: getCurrent() method called");
+        }
+        return getCurrent();
+    }
+
+    public void setUnauthenticatedSecurityContext() {
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "SecurityContext: setUnauthenticatedSecurityContext method called");
+        }
+        setUnauthenticatedContext();
+    }
+
+    public void setSecurityContextWithPrincipal(Principal principal) {
+        SecurityContext ctx = getSecurityContextForPrincipal(principal);
+        setCurrent(ctx);
+    }
+    
+    //Moved from J2EEInstanceListener.java
+    private SecurityContext getSecurityContextForPrincipal(final Principal p) {
+        if (p == null) {
+            return null;
+        } else if (p instanceof SecurityContextProxy) {
+            return ((SecurityContextProxy) p).getSecurityContext();
+        } else {
+            return AccessController.doPrivileged(new PrivilegedAction<SecurityContext>() {
+                public SecurityContext run() {
+                    Subject s = new Subject();
+                    s.getPrincipals().add(p);
+                    return new SecurityContext(p.getName(), s);
+                }
+            });
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityContextProxy.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityContextProxy.java
new file mode 100644
index 0000000..a176a6e
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityContextProxy.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+/**
+ * acts as a security context proxy
+ */
+public interface SecurityContextProxy {
+    SecurityContext getSecurityContext();
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityLifecycle.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityLifecycle.java
new file mode 100644
index 0000000..66683f6
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityLifecycle.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import com.sun.enterprise.security.audit.AuditManager;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+import org.jvnet.hk2.annotations.Optional;
+import org.glassfish.hk2.api.PostConstruct;
+import org.glassfish.hk2.api.PreDestroy;
+import org.glassfish.hk2.api.ServiceLocator;
+
+import com.sun.enterprise.security.auth.realm.RealmsManager;
+import com.sun.enterprise.security.common.Util;
+import com.sun.enterprise.security.ssl.SSLUtils;
+import org.glassfish.internal.api.ServerContext;
+import org.glassfish.api.event.EventListener;
+import org.glassfish.api.event.EventTypes;
+import org.glassfish.api.event.Events;
+import javax.inject.Inject;
+
+import org.jvnet.hk2.annotations.Service;
+import javax.inject.Singleton;
+import org.jvnet.hk2.config.ConfigListener;
+
+/**
+ * This class extends default implementation of ServerLifecycle interface.
+ * It provides security initialization and setup for the server.
+ * @author  Shing Wai Chan
+ */
+@Service
+@Singleton
+public class SecurityLifecycle implements  PostConstruct, PreDestroy {
+    
+    @Inject
+    private ServerContext sc;
+    
+    //@Inject 
+    //private RealmConfig realmConfig;
+    
+    @Inject 
+    private PolicyLoader policyLoader;
+    
+    @Inject
+    private SecurityServicesUtil secServUtil;
+    
+    @Inject 
+    private Util util;
+    
+    @Inject
+    private SSLUtils sslUtils;
+    
+    @Inject
+    private SecurityConfigListener configListener;
+    
+    @Inject
+    private ServiceLocator habitat;
+
+    @Inject
+    private RealmsManager realmsManager;
+
+    @Inject @Optional
+    private ContainerSecurityLifecycle eeSecLifecycle;
+
+    private EventListener listener = null;
+
+    private static final String SYS_PROP_LOGIN_CONF = "java.security.auth.login.config";
+    private static final String SYS_PROP_JAVA_SEC_POLICY =  "java.security.policy";
+ 
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+
+    public SecurityLifecycle() {
+	try {
+
+            if (Util.isEmbeddedServer()) {
+                //If the user-defined login.conf/server.policy are set as system properties, then they are given priority
+                if (System.getProperty(SYS_PROP_LOGIN_CONF) == null) {
+                    System.setProperty(SYS_PROP_LOGIN_CONF, Util.writeConfigFileToTempDir("login.conf").getAbsolutePath());
+                }
+                if (System.getProperty(SYS_PROP_JAVA_SEC_POLICY) == null) {
+                    System.setProperty(SYS_PROP_JAVA_SEC_POLICY, Util.writeConfigFileToTempDir("server.policy").getAbsolutePath());
+                }
+            }
+            
+            // security manager is set here so that it can be accessed from
+            // other lifecycles, like PEWebContainer
+            java.lang.SecurityManager secMgr = System.getSecurityManager();
+            if (_logger.isLoggable(Level.INFO)) {
+                if (secMgr != null) {
+                    _logger.info(SecurityLoggerInfo.secMgrEnabled);
+                } else {
+                    _logger.info(SecurityLoggerInfo.secMgrDisabled);
+                }
+            }
+	} catch(Exception ex) {
+            _logger.log(Level.SEVERE, "java_security.init_securitylifecycle_fail", ex);
+            throw new RuntimeException(ex.toString(), ex);
+	}
+    }   
+
+    // override default
+    public void onInitialization() {
+
+        try {
+             if (_logger.isLoggable(Level.INFO)) {
+                 _logger.log(Level.INFO, SecurityLoggerInfo.secServiceStartupEnter);
+             }
+
+             
+
+            //TODO:V3 LoginContextDriver has a static variable dependency on BaseAuditManager
+            //And since LoginContextDriver has too many static methods that use BaseAuditManager
+            //we have to make this workaround here.
+             //Commenting this since this is being handles in LoginContextDriver
+        //    LoginContextDriver.AUDIT_MANAGER = secServUtil.getAuditManager();
+
+            //replaced with SharedSecureRandom API
+            //secServUtil.initSecureSeed();
+
+            // jacc
+            //registerPolicyHandlers();
+            // assert(policyLoader != null);
+            policyLoader.loadPolicy();
+
+            realmsManager.createRealms();
+            // start the audit mechanism
+            AuditManager auditManager = secServUtil.getAuditManager();
+            auditManager.loadAuditModules();
+
+            //Audit the server started event
+            auditManager.serverStarted();
+            
+            // initRoleMapperFactory is in J2EEServer.java and not moved to here
+            // this is because a DummyRoleMapperFactory is register due
+            // to invocation of ConnectorRuntime.createActiveResourceAdapter
+            // initRoleMapperFactory is called after it
+            //initRoleMapperFactory();
+           
+           if (_logger.isLoggable(Level.INFO)) {
+                 _logger.log(Level.INFO, SecurityLoggerInfo.secServiceStartupExit);
+             }
+
+        } catch(Exception ex) {
+            throw new SecurityLifecycleException(ex);
+        }
+    }
+
+    
+
+/*    private void registerPolicyHandlers()
+            throws javax.security.jacc.PolicyContextException {
+        PolicyContextHandler pch = PolicyContextHandlerImpl.getInstance();
+        PolicyContext.registerHandler(PolicyContextHandlerImpl.ENTERPRISE_BEAN,
+            pch, true);
+        PolicyContext.registerHandler(PolicyContextHandlerImpl.SUBJECT, pch, true);
+        PolicyContext.registerHandler(PolicyContextHandlerImpl.EJB_ARGUMENTS,
+            pch, true);
+        *//*V3 Commented: PolicyContext.registerHandler(PolicyContextHandlerImpl.SOAP_MESSAGE,
+            pch, true);
+         *//*
+        PolicyContext.registerHandler(PolicyContextHandlerImpl.HTTP_SERVLET_REQUEST,
+            pch, true);
+        PolicyContext.registerHandler(PolicyContextHandlerImpl.REUSE, pch, true);
+    }*/
+
+    @Override
+    public void postConstruct() {
+        onInitialization();
+        listener = new AuditServerShutdownListener();
+        Events events = habitat.getService(Events.class);
+        events.register(listener);
+
+    }
+
+    @Override
+    public void preDestroy() {
+        //DO Nothing ?
+        //TODO:V3 need to see if something needs cleanup
+       
+    }
+    
+    //To audit the server shutdown event
+    public class AuditServerShutdownListener implements EventListener {
+        @Override
+        public void event(Event event) {
+            if (EventTypes.SERVER_SHUTDOWN.equals(event.type())) {
+                secServUtil.getAuditManager().serverShutdown();
+            }
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityLifecycleException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityLifecycleException.java
new file mode 100644
index 0000000..b541342
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityLifecycleException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+/**
+ *
+ * 
+ */
+class SecurityLifecycleException extends RuntimeException {
+
+    public SecurityLifecycleException(Exception ex) {
+        this.initCause(ex);
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityLoggerInfo.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityLoggerInfo.java
new file mode 100644
index 0000000..6980747
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityLoggerInfo.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import java.util.logging.Logger;
+import org.glassfish.logging.annotation.LogMessageInfo;
+import org.glassfish.logging.annotation.LogMessagesResourceBundle;
+import org.glassfish.logging.annotation.LoggerInfo;
+
+
+public class SecurityLoggerInfo {
+    public static final String LOGMSG_PREFIX = "NCLS-SECURITY";
+    
+    @LogMessagesResourceBundle
+    public static final String SHARED_LOGMESSAGE_RESOURCE = "com.sun.enterprise.security.LogMessages";
+    
+    @LoggerInfo(subsystem = "SECURITY", description = "Core Security", publish = true)
+    public static final String SECURITY_LOGGER = "javax.enterprise.system.core.security";
+    private static final Logger securityLogger = Logger.getLogger(
+                SECURITY_LOGGER, SHARED_LOGMESSAGE_RESOURCE);
+
+    public static Logger getLogger() {
+        return securityLogger;
+    }
+    
+    //Common Security messages
+    @LogMessageInfo(
+            message = "Caught exception.",
+            cause ="Unknown.",
+            action ="Check the server logs and contact Oracle support.",
+            level = "WARNING")
+    public static final String securityExceptionError = LOGMSG_PREFIX + "-01000";
+    
+    @LogMessageInfo(
+            message = "Java security manager is enabled.",
+            level = "INFO")
+    public static final String secMgrEnabled = LOGMSG_PREFIX + "-01001";
+    
+    @LogMessageInfo(
+            message = "Java security manager is disabled.",
+            level = "INFO")
+    public static final String secMgrDisabled = LOGMSG_PREFIX + "-01002";
+    
+    @LogMessageInfo(
+            message = "An I/O error occurred during copying of server config files.",
+            cause ="Copying server config files.",
+            action ="Check the server logs and contact Oracle support.",
+            level = "SEVERE")
+    public static final String ioError = LOGMSG_PREFIX + "-01004";
+    
+    @LogMessageInfo(
+            message = "XML processing error occurred during copying of server config files.",
+            cause = "The XML file(s) may not be well formed.",
+            action = "Make sure the XML file(s) are well formed.",
+            level = "SEVERE")
+    public static final String xmlStreamingError = LOGMSG_PREFIX + "-01005";
+    
+    // Security service messages
+    @LogMessageInfo(
+            message = "Entering Security Startup Service.",
+            level = "INFO")
+    public static final String secServiceStartupEnter = LOGMSG_PREFIX + "-01010";
+    
+    @LogMessageInfo(
+            message = "Security Service(s) started successfully.",
+            level = "INFO")
+    public static final String secServiceStartupExit = LOGMSG_PREFIX + "-01011";
+    
+    @LogMessageInfo(
+            message = "Error obtaining keystore and truststore files for embedded server.",
+            cause = "Saving the keystore and/or truststore to the temporary directory.",
+            action = "Check if the user.home directory is writable.",
+            level = "SEVERE")
+    public static final String obtainingKeyAndTrustStoresError = LOGMSG_PREFIX + "-01012";
+    
+    @LogMessageInfo(
+            message = "An I/O error occurred while copying the security config files.",
+            cause = "Copying security files to instanceRoot/config.",
+            action = "Check the server logs and contact Oracle support.",
+            level = "WARNING")
+    public static final String copyingSecurityConfigFilesIOError = LOGMSG_PREFIX + "-01013";
+    
+    @LogMessageInfo(
+            message = "An error occurred while upgrading the security config files.",
+            cause = "Upgrade security config files from a previous version.",
+            action = "Check the server logs and contact Oracle support.",
+            level = "SEVERE")
+    public static final String securityUpgradeServiceException = LOGMSG_PREFIX + "-01014";
+    
+    @LogMessageInfo(
+            message = "Upgrade from v2 EE  to v3.1 requires manual steps. Please refer to the v3.1 Upgrade Guide for details.",
+            cause = "Upgrade security config files from a previous version.",
+            action = "Please refer to the v3.1 Upgrade Guide for details.",
+            level = "WARNING")
+    public static final String securityUpgradeServiceWarning = LOGMSG_PREFIX + "-01015";
+    
+    // General login processing messages: start 1050
+    @LogMessageInfo(
+            message = "Certificate authentication requires certificate realm.",
+            cause = "Unknown realm type.",
+            action = "Check server configuration",
+            level = "WARNING")
+    public static final String certLoginBadRealmError = LOGMSG_PREFIX + "-01050";
+    
+    
+    //Realms and Login Modules: start at 1100
+    @LogMessageInfo(
+            message = "Disabled realm [{0}] due to errors.",
+            cause ="No realms available.",
+            action ="Check the server logs and contact Oracle support.",
+            level = "WARNING")
+    public static final String realmConfigDisabledError = LOGMSG_PREFIX + "-01100";
+    
+    @LogMessageInfo(
+            message = "No realms available. Authentication services disabled.",
+            cause ="No realms available.",
+            action ="Check the server logs and contact Oracle support.",
+            level = "SEVERE")
+    public static final String noRealmsError = LOGMSG_PREFIX + "-01101";
+    
+    @LogMessageInfo(
+            message = "Error while obtaining private subject credentials: {0}",
+            cause = "Private Credentials of Subject not available.",
+            action = "Please check if the private credentials are available.",
+            level = "WARNING")
+    public static final String privateSubjectCredentialsError = LOGMSG_PREFIX + "-01104";
+    
+    @LogMessageInfo(
+            message = "A PasswordCredential was required but not provided.",
+            cause = "PasswordCredential was required, but not supplied.",
+            action = "Please check if the password is provided.",
+            level = "SEVERE")
+    public static final String noPwdCredentialProvidedError = LOGMSG_PREFIX + "-01105";   
+    
+    @LogMessageInfo(
+            message = "Realm [{0}] of classtype [{1}] successfully created.",
+            level = "INFO")    
+    public static final String realmCreated = LOGMSG_PREFIX + "-01115";
+    
+    @LogMessageInfo(
+            message = "Realm [{0}] successfully updated.",
+            level = "INFO")    
+    public static final String realmUpdated = LOGMSG_PREFIX + "-01117";
+    
+    @LogMessageInfo(
+            message = "Realm [{0}] successfully deleted.",
+            level = "INFO")    
+    public static final String realmDeleted = LOGMSG_PREFIX + "-01119";
+    
+
+    // JACC and policy: start at 1140
+    @LogMessageInfo(
+            message = "Policy provider configuration overridden by property {0} with value {1}.",
+            level = "INFO")    
+    public static final String policyProviderConfigOverrideMsg = LOGMSG_PREFIX + "-01140"; 
+    
+    @LogMessageInfo(
+            message = "Requested jacc-provider [{0}] is not configured in domain.xml.",
+            level = "WARNING")    
+    public static final String policyNoSuchName = LOGMSG_PREFIX + "-01141";
+
+    @LogMessageInfo(
+            message = "Error while reading policy-provider in domain.xml.",
+            level = "WARNING")    
+    public static final String policyReadingError = LOGMSG_PREFIX + "-01142";
+    
+    @LogMessageInfo(
+            message = "Loading policy provider {0}.",
+            level = "INFO")    
+    public static final String policyLoading = LOGMSG_PREFIX + "-01143"; 
+    
+    @LogMessageInfo(
+            message = "Error while installing policy provider: {0}.",
+            cause = "Setting the system wide policy.",
+            action = "Make sure there's sufficient permission to set the policy.",
+            level = "SEVERE")    
+    public static final String policyInstallError = LOGMSG_PREFIX + "-01144";
+    
+    @LogMessageInfo(
+            message = "No policy provider defined. Will use the default JDK Policy implementation.",
+            level = "WARNING")    
+    public static final String policyNotLoadingWarning = LOGMSG_PREFIX + "-01145";
+    
+    @LogMessageInfo(
+            message = "Policy configuration factory overridden by property {0} with value {1}",
+            level = "WARNING")    
+    public static final String policyFactoryOverride = LOGMSG_PREFIX + "-01146";
+    
+    @LogMessageInfo(
+            message = "Policy configuration factory not defined.",
+            level = "WARNING")    
+    public static final String policyConfigFactoryNotDefined = LOGMSG_PREFIX + "-01147";
+    
+    @LogMessageInfo(
+            message = "Policy provider configuration overridden by property {0} with value {1}.",
+            level = "WARNING")    
+    public static final String policyProviderConfigOverrideWarning = LOGMSG_PREFIX + "-01149";
+    
+    @LogMessageInfo(
+            message = "Failed to get the group names for user {0} in realm {1}: {2}.",
+            cause = "Operation now allowed",
+            action = "Check the server logs and contact Oracle support",
+            level = "WARNING")
+    public static final String invalidOperationForRealmError = LOGMSG_PREFIX + "-01150";
+    
+    @LogMessageInfo(
+            message = "Failed to get the group names for user {0} in realm {1}: {2}.",
+            cause = "Obtain the group names for a nonexistent user",
+            action = "Make sure the user is valid",
+            level = "WARNING")
+    public static final String noSuchUserInRealmError = LOGMSG_PREFIX + "-01151";
+    
+    @LogMessageInfo(
+            message = "ERROR: Unknown credential provided. Class: [{0}].",
+            level = "INFO")
+    public static final String unknownCredentialError = LOGMSG_PREFIX + "-05019";  
+    
+    @LogMessageInfo(
+            message = "Exception in getting security context.",
+            cause = "There was an exception obtaining the default security context.",
+            action = "Check the server logs and contact Oracle support",
+            level = "SEVERE")
+    public static final String defaultSecurityContextError = LOGMSG_PREFIX + "-05036";
+    
+    @LogMessageInfo(
+            message = "Default user login error.",
+            cause = "There was an exception while authenticating the default caller principal.",
+            action = "Check the server logs and contact Oracle support.",
+            level = "SEVERE")
+    public static final String defaultUserLoginError = LOGMSG_PREFIX + "-05038";
+    
+    @LogMessageInfo(
+            message = "Exception entering name and password for security.",
+            cause = "An exception occurred while processing username and password for security.",
+            action = "An exception occurred while processing username and password for security.",
+            level = "SEVERE")
+    public static final String usernamePasswordEnteringSecurityError = LOGMSG_PREFIX + "-05039";
+    
+    @LogMessageInfo(
+            message = "Exception in security accesscontroller action.",
+            cause = "Running a privileged action",
+            action = "Check the server logs and contact Oracle support",
+            level = "SEVERE")
+    public static final String securityAccessControllerActionError = LOGMSG_PREFIX + "-05043";
+   
+    
+    @LogMessageInfo(
+            message = "Audit: Authentication refused for [{0}].",
+            level = "INFO")
+    public static final String auditAtnRefusedError = LOGMSG_PREFIX + "-05046";
+    
+    @LogMessageInfo(
+            message = "doAsPrivileged AuthPermission required to set SecurityContext.",
+            cause = "Setting the SecurityContext in the current thread",
+            action = "Check the server logs and contact Oracle support",
+            level = "SEVERE")
+    public static final String securityContextPermissionError = LOGMSG_PREFIX + "-05048";
+    
+    @LogMessageInfo(
+            message = "Unexpected exception while attempting to set SecurityContext.",
+            cause = "There was an unexpected exception while setting the security context.",
+            action = "Check the server logs and contact Oracle support.",
+            level = "SEVERE")
+    public static final String securityContextUnexpectedError = LOGMSG_PREFIX + "-05049";
+    
+    @LogMessageInfo(
+            message = "Could not change the SecurityContext.",
+            cause = "Changing the current SecurityContext.",
+            action = "Check the server logs and contact Oracle support",
+            level = "SEVERE")
+    public static final String securityContextNotChangedError = LOGMSG_PREFIX + "-05050";
+    
+    @LogMessageInfo(
+            message = "Subject is null.",
+            cause = "null Subject used in SecurityContext construction.",
+            action = "Make sure the Subject is not null",
+            level = "WARNING")
+    public static final String nullSubjectWarning = LOGMSG_PREFIX + "-05052";
+    
+    @LogMessageInfo(
+            message = "Role mapping conflicts found in application {0}. Some roles may not be mapped.",
+            level = "INFO")
+    public static final String roleMappingConflictError = LOGMSG_PREFIX + "-05055";
+   
+    @LogMessageInfo(
+            message = "Error converting certificate {0}: {1}",
+            level = "INFO")
+    public static final String convertingCertError = LOGMSG_PREFIX + "-05056";
+    
+    @LogMessageInfo(
+            message = "Failed to instantiate the SecurityLifeCycle.",
+            cause = "Unknown",
+            action = "Check the server logs and contact Oracle support",
+            level = "SEVERE")
+    public static final String secMgrInitFailure = LOGMSG_PREFIX + "-05101";
+    
+    @LogMessageInfo(
+            message = "Error enabling secure admin.",
+            cause = "Enable secure admin",
+            action = "Check your command usage",
+            level = "SEVERE")
+    public static final String enablingSecureAdminError = LOGMSG_PREFIX + "-05200";
+    
+    @LogMessageInfo(
+            message = "Error disabling secure admin.",
+            cause = "Disable secure admin",
+            action = "Check your command usage",
+            level = "SEVERE")
+    public static final String disablingSecureAdminError = LOGMSG_PREFIX + "-05201";
+    
+    @LogMessageInfo(
+            message = "IIOP Security - error importing a name: ${0}.",
+            cause = "Importing a name in IIOP",
+            action = "Check the server logs and contact Oracle support",
+            level = "SEVERE")
+    public static final String iiopImportNameError = LOGMSG_PREFIX + "-05300";
+    
+    @LogMessageInfo(
+            message = "IIOP Security - error creating an exported name: ${0}.",
+            cause = "Creating an exported name in IIOP",
+            action = "Check the server logs and contact Oracle support",
+            level = "SEVERE")
+    public static final String iiopCreateExportedNameError = LOGMSG_PREFIX + "-05301";
+    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityManager.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityManager.java
new file mode 100644
index 0000000..0de6555
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityManager.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import java.security.Principal;
+import java.security.PrivilegedExceptionAction;
+import java.lang.reflect.Method;
+
+import javax.security.auth.Subject;
+import org.glassfish.api.invocation.ComponentInvocation;
+
+/**
+ * This interface is used by the Container to manage access to EJBs.
+ * The container has a reference to an implementation of this 
+ * interface.
+ * @author Harish Prabandham
+ */
+public interface SecurityManager {
+
+    /**
+     * @param The Invocation object containing the details of the invocation.
+     * @return true if the client is allowed to invoke the EJB, false otherwise.
+     */
+    public boolean authorize(ComponentInvocation inv);
+
+    /**
+     * @return The Principal of the client who made the current 
+     * invocation.
+     */
+    public Principal getCallerPrincipal();
+
+    /**
+     * @return A boolean true/false depending on whether or not the caller 
+     * has the specified role.
+     * @param The EJB developer specified "logical role".
+     */
+    public boolean isCallerInRole(String  role);
+
+
+    /** This sets up the security context - if not set
+     * and does run-as related login if required
+     * @param ComponentInvocation
+     */
+    public void preInvoke (ComponentInvocation inv);
+
+    /**
+     * This method is used by the  Invocation Manager to remove
+     * the run-as identity information that was set up using the 
+     * preInvoke
+     * @param ComponentInvocation
+     */
+    public void postInvoke (ComponentInvocation inv);
+
+    /**
+     * Call this method to clean up all the bookeeping
+     * data-structures in the SM.
+     */
+    public void destroy();
+
+    /**
+     * This will return the subject associated with the current
+     * call. If the run as subject is in effect. It will return that
+     * subject. This is done to support the JACC specification which says
+     * if the runas principal is in effect, that principal should be used
+     * for making a component call.
+     * @return Subject the current subject. Null if this is not the
+     * runas case
+     */
+    public Subject getCurrentSubject();
+
+    /**
+     * Purge ThreadLocals held by javax.security.jacc.PolicyContext
+     */
+    public void resetPolicyContext();
+    
+    
+    /* This method is used by SecurityUtil runMethod to run the
+     * action as the subject encapsulated in the cuurent
+     * SecurityContext.
+     */
+      
+    public Object doAsPrivileged(PrivilegedExceptionAction pea) 
+ 	throws Throwable;
+
+    public Object invoke(Method beanClassMethod, boolean isLocal, Object o, Object[] oa)
+            throws Throwable;
+     
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityRoleMapperFactoryGen.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityRoleMapperFactoryGen.java
new file mode 100644
index 0000000..3ba95ac
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityRoleMapperFactoryGen.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * SecurityRoleMapperFactoryGen.java
+ *
+ * Created on September 23, 2009, 12:34 PM
+ */
+
+package com.sun.enterprise.security;
+
+import java.lang.ref.WeakReference;
+import org.glassfish.deployment.common.SecurityRoleMapperFactory;
+import org.glassfish.internal.api.Globals;
+
+/**
+ *
+ * @author nasradu8
+ */
+public class SecurityRoleMapperFactoryGen {
+
+    private static WeakReference<SecurityRoleMapperFactory> securityRoleMapperFactory = new WeakReference<SecurityRoleMapperFactory>(null);
+
+    private static synchronized SecurityRoleMapperFactory _getSecurityRoleMapperFactory() {
+        if (securityRoleMapperFactory.get() == null) {
+            securityRoleMapperFactory = new WeakReference<SecurityRoleMapperFactory>(Globals.get(SecurityRoleMapperFactory.class));
+        }
+        return securityRoleMapperFactory.get();
+    }
+
+    public static SecurityRoleMapperFactory getSecurityRoleMapperFactory() {
+        if (securityRoleMapperFactory.get() != null) {
+            return securityRoleMapperFactory.get();
+        }
+        return _getSecurityRoleMapperFactory();
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityServicesUtil.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityServicesUtil.java
new file mode 100644
index 0000000..de774c5
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityServicesUtil.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2008, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.enterprise.security;
+
+import com.sun.enterprise.security.audit.AuditManager;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import org.glassfish.api.admin.ServerEnvironment;
+import java.util.logging.Logger;
+import javax.security.auth.callback.CallbackHandler;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.glassfish.api.admin.ProcessEnvironment;
+import org.glassfish.api.admin.ProcessEnvironment.ProcessType;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.internal.api.Globals;
+
+@Service
+@Singleton
+public class SecurityServicesUtil {
+
+    private static ServiceLocator habitat = Globals.getDefaultHabitat();
+    
+    private static final LocalStringManagerImpl _localStrings =
+            new LocalStringManagerImpl(SecurityServicesUtil.class);
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+    // Using SharedSecureRandom from internal-api instead.
+    // SecureRandom number used for HTTPS and IIOP/SSL.
+    // This number is accessed by iiop/IIOPSSLSocketFactory
+    // & web/security/SSLSocketFactory classes.
+    //public static final SecureRandom secureRandom = new SecureRandom();
+
+    @Inject
+    private ProcessEnvironment processEnv;
+    
+    @Inject
+    private ServerEnvironment env;
+
+    @Inject 
+    private AuditManager auditManager;
+    
+//    static {
+//        secureRandom.setSeed(System.currentTimeMillis());
+//    }
+
+    //the appclient CBH
+    private CallbackHandler callbackHandler;
+    
+    /**
+     * replacing all of this with SharedSecureRandom
+     * So on restart, all your seed material comes from a new time that varies
+     * little from something guessable, plus something you repeat every run?
+     * Seems weak to me.  Why do you want to keep the seed around?
+     * There are some situations where this might be needed,
+     * but if you're just looking for as random numbers as possible,
+     * I don't think this is not a good way to achieve it.
+     * code moved from J2EEServer.run()
+     */
+//    public void initSecureSeed() {
+//
+//        File secureSeedFile = null;
+//        if (Util.isEmbeddedServer()) {
+//            try {
+//                secureSeedFile = Util.writeConfigFileToTempDir("secure.seed");
+//
+//            } catch (IOException ex) {
+//                String errmsg =
+//                        "IOException while constructing embedded config file";
+//                _logger.log(Level.WARNING, errmsg);
+//            }
+//        } else {
+//            secureSeedFile = new File(env.getConfigDirPath(), "secure.seed");
+//        }
+//
+//        // read the secure random from the file
+//        long seed = readSecureSeed(secureSeedFile);
+//        secureRandom.setSeed(seed);
+//        // generate a new one for the next startup
+//        seed = secureRandom.nextLong();
+//        writeSecureSeed(secureSeedFile, seed);
+//        secureSeedFile = null;
+//    }
+
+    /** read the secure random number from the file.
+     *  If the seed is not present, the default expensive SecureRandom seed
+     *  generation algorithm is invoked to return a new seed number
+     *  @param fname the file to be read - here secure.seed file.
+     */
+//    private long readSecureSeed(File fname) {
+//        byte[] seed;
+//        try {
+//            BufferedReader fis = new BufferedReader(new FileReader(fname));
+//            try {
+//                String line = fis.readLine();
+//                fis.close();
+//                // returning a long value.
+//                Long lseed = new Long(line);
+//                return lseed.longValue();
+//            } catch (IOException e) {
+//                if (fis != null) {
+//                    fis.close();
+//                }
+//            }
+//        } catch (Throwable e) {  // IASRI 4666401 if all fails just create new
+//        }
+//        // BEGIN IASRI 4703002
+//        // In order to work around JVM bug 4709460 avoid internal seeding.
+//        // (Call setSeed again (see static block) to attempt to add some
+//        // minimal randomness; setSeed calls are cumulative)
+//
+//        secureRandom.setSeed(System.currentTimeMillis());
+//        long newSeed = secureRandom.nextLong();
+//        return newSeed;
+//    }
+
+    /** write the new secure seed to the secure.seed file to speed up
+     * startup the next time the server is started.
+     * @param fname secure.seed file
+     * @param seed seed the value of the 8 byte seed.
+     */
+//    private void writeSecureSeed(File fname, long seed) {
+//        try {
+//            FileOutputStream fos = new FileOutputStream(fname);
+//            String sseed = Long.toString(seed);
+//            fos.write(sseed.getBytes());
+//            fos.close();
+//        } catch (IOException e) {
+//            String errmsg =
+//                    _localStrings.getLocalString("j2ee.startupslow",
+//                    "Cannot write the seed file for fast startup. The next startup will be slow.");
+//
+//            _logger.log(Level.WARNING, errmsg);
+//        }
+//
+//    }
+
+    public ServiceLocator getHabitat() {
+        return habitat;
+    }
+    
+    public AuditManager getAuditManager() {
+        return auditManager;
+    }
+
+    public static SecurityServicesUtil getInstance() {
+        // return my singleton service
+        if (habitat == null) {
+            return null;
+        }
+        return habitat.getService(SecurityServicesUtil.class);
+    }
+
+    public ProcessEnvironment getProcessEnv() {
+        return processEnv;
+    }
+    
+    public boolean isACC() {
+        return processEnv.getProcessType().equals(ProcessType.ACC);
+    }
+    public boolean isServer() {
+        return processEnv.getProcessType().isServer();
+    }
+    public boolean isNotServerOrACC() {
+        return processEnv.getProcessType().equals(ProcessType.Other);
+    }
+
+    public CallbackHandler getCallbackHandler() {
+        return callbackHandler;
+    }
+
+    public void setCallbackHandler(CallbackHandler callbackHandler) {
+        this.callbackHandler = callbackHandler;
+    }
+    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityUpgradeService.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityUpgradeService.java
new file mode 100644
index 0000000..9f3fd92
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityUpgradeService.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import com.sun.enterprise.config.serverbeans.*;
+import java.beans.PropertyVetoException;
+import java.io.File;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.api.admin.config.ConfigurationUpgrade;
+import javax.inject.Inject;
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PostConstruct;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+import org.jvnet.hk2.config.types.Property;
+
+
+/**
+ *The only thing that needs to added Extra for SecurityService migration
+ * is the addition of the new JACC provider. This would be required when
+ * migrating from V2, for V3-Prelude it is already present.
+ *
+ * The rest of the security related upgrade is handled implicitly by the actions of the
+ * upgrade service itself.
+ * 
+ */
+
+@Service
+public class SecurityUpgradeService implements ConfigurationUpgrade, PostConstruct {
+
+    @Inject
+    Configs configs;
+
+    @Inject
+    ServerEnvironment env;
+
+    private static final String DIR_GENERATED_POLICY = "generated" + File.separator + "policy";
+    private static final String DIR_CONFIG = "config";
+    private static final String JKS = ".jks";
+    private static final String NSS = ".db";
+  //  private static final String KEYSTORE = "keystore.jks";
+  //  private static final String TRUSTSTORE = "cacerts.jks";
+
+    private static final String JDBC_REALM_CLASSNAME = "com.sun.enterprise.security.ee.auth.realm.jdbc.JDBCRealm";
+    public static final String PARAM_DIGEST_ALGORITHM = "digest-algorithm";
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+
+    
+    public void postConstruct()  {
+        for (Config config : configs.getConfig()) {
+            SecurityService service = config.getSecurityService();
+            if (service != null) {
+                upgradeJACCProvider(service);
+            }
+        }
+
+        //Clear up the old policy files for applications
+        String instanceRoot = env.getInstanceRoot().getAbsolutePath();
+        File genPolicyDir = new File(instanceRoot, DIR_GENERATED_POLICY);
+        if(genPolicyDir != null) {
+            File[] applicationDirs = genPolicyDir.listFiles();
+            if(applicationDirs != null) {
+                for(File policyDir:applicationDirs) {
+                    deleteFile(policyDir);
+                }
+            }
+        }
+
+        //Update an existing JDBC realm-Change the digest algorithm to MD5 if none exists
+        //Since the default algorithm is SHA-256 in v3.1, but was MD5 prior to 3.1
+
+        for (Config config : configs.getConfig()) {
+            SecurityService service = config.getSecurityService();
+            List<AuthRealm> authRealms = service.getAuthRealm();
+
+            try {
+                for (AuthRealm authRealm : authRealms) {
+                    if (JDBC_REALM_CLASSNAME.equals(authRealm.getClassname())) {
+                        Property digestAlgoProp = authRealm.getProperty(PARAM_DIGEST_ALGORITHM);
+                        if (digestAlgoProp != null) {
+                            String digestAlgo = digestAlgoProp.getValue();
+                            if (digestAlgo == null || digestAlgo.isEmpty()) {
+                                digestAlgoProp.setValue("MD5");
+                            }
+                        } else {
+                            ConfigSupport.apply(new SingleConfigCode<AuthRealm>() {
+                                public Object run(AuthRealm updatedAuthRealm) throws PropertyVetoException, TransactionFailure {
+                                    Property prop1 = updatedAuthRealm.createChild(Property.class);
+                                    prop1.setName(PARAM_DIGEST_ALGORITHM);
+                                    prop1.setValue("MD5");
+                                    updatedAuthRealm.getProperty().add(prop1);
+                                    return null;
+                                }
+                            }, authRealm);
+                        }
+                    }
+                }
+            } catch (PropertyVetoException pve) {
+                _logger.log(Level.SEVERE, SecurityLoggerInfo.securityUpgradeServiceException, pve);
+                throw new RuntimeException(pve);
+            } catch (TransactionFailure tf) {
+               _logger.log(Level.SEVERE, SecurityLoggerInfo.securityUpgradeServiceException, tf);
+                throw new RuntimeException(tf);
+
+            }
+        }
+
+        //Detect an NSS upgrade scenario and point to the steps wiki
+
+        if (requiresSecureAdmin()) {
+
+            _logger.log(Level.WARNING, SecurityLoggerInfo.securityUpgradeServiceWarning);
+        }
+
+    }
+
+
+    /*
+     * Method to detect an NSS install.
+     */
+
+    public boolean requiresSecureAdmin() {
+
+        String instanceRoot = env.getInstanceRoot().getAbsolutePath();
+        File configDir = new File(instanceRoot, "config");
+        //default KS password
+
+
+        if (configDir.isDirectory()) {
+            for (File configFile : configDir.listFiles()) {
+                    if (configFile.getName().endsWith(NSS)) {
+                        return true;
+                    }
+                }
+            }
+
+        return false;
+    }
+
+    private void upgradeJACCProvider(SecurityService securityService) {
+        try {
+            List<JaccProvider> jaccProviders = securityService.getJaccProvider();
+            for (JaccProvider jacc : jaccProviders) {
+                if ("com.sun.enterprise.security.jacc.provider.SimplePolicyConfigurationFactory".equals(jacc.getPolicyConfigurationFactoryProvider())) {
+                    //simple policy provider already present
+                    return;
+                }
+            }
+            ConfigSupport.apply(new SingleConfigCode<SecurityService>() {
+                @Override
+                public Object run(SecurityService secServ) throws PropertyVetoException, TransactionFailure {
+                    JaccProvider jacc = secServ.createChild(JaccProvider.class);
+                    //add the simple provider to the domain's security service
+                    jacc.setName("simple");
+                    jacc.setPolicyConfigurationFactoryProvider("com.sun.enterprise.security.jacc.provider.SimplePolicyConfigurationFactory");
+                    jacc.setPolicyProvider("com.sun.enterprise.security.jacc.provider.SimplePolicyProvider");
+                    secServ.getJaccProvider().add(jacc);
+                    return secServ;
+                }
+            }, securityService);
+        } catch (TransactionFailure ex) {
+            Logger.getAnonymousLogger().log(Level.SEVERE, null, ex);
+            throw new RuntimeException(ex);
+        }
+
+    }
+
+
+    private boolean deleteFile(File path) {
+        if (path != null && path.exists()) {
+            if (path.isDirectory()) {
+                File[] files = path.listFiles();
+                for(File file:files) {
+                    if(file.isDirectory()){
+                        deleteFile(file);
+                        if(file.delete())
+                            continue;
+                    }
+                    else {
+                        if(file.delete())
+                            continue;
+                    }
+                }
+            }
+            if(!path.delete()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/TextLoginDialog.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/TextLoginDialog.java
new file mode 100644
index 0000000..85d3f5e
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/TextLoginDialog.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import com.sun.enterprise.security.ssl.SSLUtils;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.logging.*;
+import javax.security.auth.callback.*;
+
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.logging.*;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import org.glassfish.internal.api.Globals;
+
+/**
+ * This implementation of LoginDialog
+ * If these are not set, then it queries the user in the command window.
+ *
+ * @author Harish Prabandham
+ */
+public final class TextLoginDialog implements LoginDialog {
+
+    private static Logger _logger = null;
+
+    static {
+        _logger = SecurityLoggerInfo.getLogger();
+    }
+    private String username = null;
+    private char[] password = null;
+    private static LocalStringManagerImpl localStrings =
+            new LocalStringManagerImpl(TextLoginDialog.class);
+
+    public TextLoginDialog(Callback[] callbacks) {
+        try {
+            for (int i = 0; i < callbacks.length; i++) {
+                if (callbacks[i] instanceof NameCallback) {
+                    NameCallback nc = (NameCallback) callbacks[i];
+                    System.err.print(nc.getPrompt());
+                    if (nc.getDefaultName() != null) {
+                        System.err.print("[" + nc.getDefaultName() + "]: ");
+                    } else {
+                        System.err.print(": ");
+                    }
+
+                    System.err.flush();
+                    username = (new BufferedReader(new InputStreamReader(System.in))).readLine();
+                    if ((nc.getDefaultName() != null) && ((username == null) || (username.trim().length() == 0))) {
+                        username = nc.getDefaultName();
+                    }
+                    nc.setName(username);
+
+                } else if (callbacks[i] instanceof PasswordCallback) {
+                    PasswordCallback pc = (PasswordCallback) callbacks[i];
+                    char[] passwd = null;
+                    Object consoleObj = null;
+                    Method readPasswordMethod = null;
+                    try {
+                        Method consoleMethod = System.class.getMethod("console");
+                        consoleObj = consoleMethod.invoke(null);
+                        readPasswordMethod =
+                                consoleObj.getClass().getMethod(
+                                "readPassword", String.class,
+                                Array.newInstance(Object.class, 1).getClass());
+                    } catch (Exception ex) {
+                    }
+
+                    if (consoleObj != null && readPasswordMethod != null) {
+                        passwd = (char[]) readPasswordMethod.invoke(
+                                consoleObj, "%s",
+                                new Object[]{pc.getPrompt()});
+                    } else {
+                        System.err.print(pc.getPrompt());
+                        System.err.flush();
+                        passwd = readPassword(System.in);
+                    }
+                    if (passwd != null) {
+                        pc.setPassword(passwd);
+                        Arrays.fill(passwd, ' ');
+                    }
+                } else if (callbacks[i] instanceof ChoiceCallback) {
+                    ChoiceCallback cc = (ChoiceCallback) callbacks[i];
+                    /* Get the keystore password to see if the user is
+                     * authorized to see the list of certificates
+                     */
+                    String lbl = (localStrings.getLocalString("enterprise.security.keystore",
+                            "Enter the KeyStore Password "));
+                    SSLUtils sslUtils = Globals.get(SSLUtils.class);
+                    System.out.println(lbl
+                            + " : (max 3 tries)");
+                    int cnt = 0;
+                    for (cnt = 0; cnt < 3; cnt++) {
+                        // Let the user try putting password thrice
+                        System.out.println(lbl + " : ");
+			String s = (new BufferedReader(new InputStreamReader(System.in))).readLine();
+			if (s != null) {
+                            char[] kp = s.toCharArray();
+                            if (sslUtils.verifyMasterPassword(kp)) {
+                                break;
+                            } else {
+                                String errmessage = localStrings.getLocalString("enterprise.security.IncorrectKeystorePassword", "Incorrect Keystore Password");
+                                System.err.println(errmessage);
+                            }
+                            Arrays.fill(kp, ' ');
+			}
+                    }
+                    if (cnt >= 3) {
+                        cc.setSelectedIndex(-1);
+                    } else {
+                        System.err.println(cc.getPrompt());
+                        System.err.flush();
+                        String[] choices = cc.getChoices();
+                        for (int j = 0; j < choices.length; j++) {
+                            System.err.print("[" + j + "] ");
+                            System.err.println(choices[j]);
+                        }
+                        String line =
+                                (new BufferedReader(new InputStreamReader(System.in))).readLine();
+
+			if (line != null) {
+                            int sel = Integer.parseInt(line);
+                            cc.setSelectedIndex(sel);
+			}
+                    }
+                }
+            }
+        } catch (Exception e) {
+            _logger.log(Level.SEVERE,
+                    SecurityLoggerInfo.usernamePasswordEnteringSecurityError, e);
+        }
+
+    }
+
+    /**
+     * @return The username of the user.
+     */
+    public String getUserName() {
+        return username;
+    }
+
+    /**
+     *@return The password of the user in plain text...
+     */
+    public final char[] getPassword() {
+        return (password == null) ? null : Arrays.copyOf(password, password.length);
+    }
+
+    private static char[] readPassword(InputStream in) throws IOException {
+        char[] lineBuffer;
+        char[] buf;
+        int i;
+
+        buf = lineBuffer = new char[128];
+        int room = buf.length;
+        int offset = 0;
+        int c;
+
+        loop:
+        while (true) {
+            switch (c = in.read()) {
+                case -1:
+                case '\n':
+                    break loop;
+
+                case '\r':
+                    int c2 = in.read();
+                    if ((c2 != '\n') && (c2 != -1)) {
+                        if (!(in instanceof PushbackInputStream)) {
+                            in = new PushbackInputStream(in);
+                        }
+                        ((PushbackInputStream) in).unread(c2);
+                    } else {
+                        break loop;
+
+                        
+                    }
+                default:
+                    if (--room < 0) {
+                        buf = new char[offset + 128];
+                        room = buf.length - offset - 1;
+                        System.arraycopy(lineBuffer, 0, buf, 0, offset);
+                        Arrays.fill(lineBuffer, ' ');
+                        lineBuffer = buf;
+                    }
+                    buf[offset++] = (char) c;
+                    break;
+            }
+        }
+
+        if (offset == 0) {
+            return null;
+        }
+
+        char[] ret = new char[offset];
+        System.arraycopy(buf, 0, ret, 0, offset);
+        Arrays.fill(buf, ' ');
+
+        return ret;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/UsernamePasswordStore.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/UsernamePasswordStore.java
new file mode 100644
index 0000000..4d653f3
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/UsernamePasswordStore.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import com.sun.enterprise.security.common.ClientSecurityContext;
+import java.util.logging.*;
+import com.sun.logging.*;
+import java.util.Arrays;
+
+
+/**
+ * This class is used to share information between either of the following scenarios
+ * 1. Different points of execution of a single thread
+ * 2. Different threads that wish to share the username and password information
+ * 
+ * Which of the above two condition is applicable depends upon the system property key
+ *        "com.sun.appserv.iiopclient.perthreadauth";
+ * When set to true, scenario #1 above applies and the username/password 
+ * information is not shared between threads.
+ * When set to false, scenario #2 above applies and the username/password
+ * information stored by one thread is global and visible to all threads.
+ */
+public final class UsernamePasswordStore {
+    
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+
+    private static final boolean isPerThreadAuth = 
+            Boolean.getBoolean(ClientSecurityContext.IIOP_CLIENT_PER_THREAD_FLAG);
+
+    private static ThreadLocal localUpc =
+        isPerThreadAuth ? new ThreadLocal() : null;
+    private static UsernamePasswordStore sharedUpc;
+
+    private final String username;
+    private final char[] password;
+
+    /**
+     * This creates a new UsernamePasswordStore object.
+     * The constructor is marked as private.
+     *
+     * @param username
+     * @param password
+     */
+    private UsernamePasswordStore(String username, char[] password) {
+        //Copy the password to another reference before storing it to the
+        //instance field.
+        char[] passwordCopy = (password == null) ? null : Arrays.copyOf(password, password.length);
+	this.password = passwordCopy;
+        this.username = username;
+        
+    }
+
+    /**
+     * This method returns a UsernamePasswordStore, that is
+     * either thread-local or global depending on the system property
+     * IIOP_PER_THREAD_CLIENT_FLAG. 
+     * This method is marked as private.
+     *
+     * @return The current UsernamePasswordStore
+     */
+    private static UsernamePasswordStore get() {
+        if (isPerThreadAuth) {
+            return (UsernamePasswordStore) localUpc.get();
+        } else {
+            synchronized (UsernamePasswordStore.class) {
+                return sharedUpc;
+            }
+        }
+    }
+
+    /**
+     * This method sets the username and password as thread-local or global variable
+     *
+     * @param username 
+     * @param password
+     */
+    public static void set(String username, char[] password) {
+        if (isPerThreadAuth) {
+            localUpc.set(new UsernamePasswordStore(username, password));
+        } else {
+            synchronized (UsernamePasswordStore.class) {
+                sharedUpc = new UsernamePasswordStore(username, password);
+            }
+        }
+    } 
+
+    /**
+     * Clears the username and password, that might have been previously stored,
+     * either globally or locally to each thread.
+     */
+    public static void reset() {
+        if (isPerThreadAuth) {
+            localUpc.set(null);
+        } else {
+            synchronized (UsernamePasswordStore.class) {
+                sharedUpc = null;
+            }
+        }
+    }
+    
+    /**
+     * Clears the username and password only is they were stored locally
+     * to each thread
+     */
+    public static void resetThreadLocalOnly() {
+        if (isPerThreadAuth) {
+            localUpc.set(null);
+        }
+    }
+
+    /**
+     * Returns the username, that was previously stored.
+     *
+     * @return The username set previously or null if not set
+     */
+    public static String getUsername() {
+        UsernamePasswordStore ups = UsernamePasswordStore.get();
+        if( ups != null )
+            return ups.username;
+        else 
+            return null;
+    }
+
+    
+    /**
+     * Returns the password, that was previously stored.
+     *
+     * @return The password set previously or null if not set
+     */
+    public static char[] getPassword() {
+        UsernamePasswordStore ups = UsernamePasswordStore.get();
+        if( ups != null ) {
+             //Copy the password to another reference before returning it
+            char[] passwordCopy = (ups.password == null) ? null : Arrays.copyOf(ups.password, ups.password.length);
+            return passwordCopy;
+        }
+        else 
+            return null;
+    }
+
+}
+
+
+
+
+
+
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/WebSecurityDeployerProbeProvider.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/WebSecurityDeployerProbeProvider.java
new file mode 100644
index 0000000..5291125
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/WebSecurityDeployerProbeProvider.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import org.glassfish.external.probe.provider.annotations.Probe;
+import org.glassfish.external.probe.provider.annotations.ProbeParam;
+import org.glassfish.external.probe.provider.annotations.ProbeProvider;
+
+
+@ProbeProvider(moduleProviderName = "glassfish", moduleName = "security", probeProviderName = "web")
+public class WebSecurityDeployerProbeProvider {
+
+
+    /*@Probe(name = "webDeploymentStartedEvent")
+    public void webDeploymentStartedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "webDeploymentEndedEvent")
+    public void webDeploymentEndedEvent(
+            @ProbeParam("appName") String appName) {
+    }*/
+
+    @Probe(name = "policyCreationStartedEvent")
+    public void policyCreationStartedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "policyCreationEndedEvent")
+    public void policyCreationEndedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+/*    @Probe(name = "webUndeploymentStartedEvent")
+    public void webUndeploymentStartedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "webUndeploymentEndedEvent")
+    public void webUndeploymentEndedEvent(
+            @ProbeParam("appName") String appName) {
+    }*/
+
+    @Probe(name = "policyDestructionStartedEvent")
+    public void policyDestructionStartedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "policyDestructionEndedEvent")
+    public void policyDestructionEndedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "securityManagerCreationEvent")
+    public void securityManagerCreationEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "securityManagerCreationStartedEvent")
+    public void securityManagerCreationStartedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "securityManagerCreationEndedEvent")
+    public void securityManagerCreationEndedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "securityManagerDestructionEvent")
+    public void securityManagerDestructionEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "securityManagerDestructionStartedEvent")
+    public void securityManagerDestructionStartedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "securityManagerDestructionEndedEvent")
+    public void securityManagerDestructionEndedEvent(
+            @ProbeParam("appName") String appName) {
+    }
+
+    @Probe(name = "policyCreationEvent")
+    public void policyCreationEvent(
+            @ProbeParam("contextId") String appName) {
+    }
+
+    @Probe(name = "policyDestructionEvent")
+    public void policyDestructionEvent(
+            @ProbeParam("contextId") String appName) {
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/WebSecurityDeployerStatsProvider.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/WebSecurityDeployerStatsProvider.java
new file mode 100644
index 0000000..0250d7c
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/WebSecurityDeployerStatsProvider.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security;
+
+import org.glassfish.external.statistics.CountStatistic;
+import org.glassfish.external.statistics.impl.CountStatisticImpl;
+import org.glassfish.gmbal.Description;
+import org.glassfish.gmbal.AMXMetadata;
+import org.glassfish.gmbal.ManagedAttribute;
+import org.glassfish.gmbal.ManagedObject;
+import org.glassfish.external.probe.provider.annotations.ProbeListener;
+import org.glassfish.external.probe.provider.annotations.ProbeParam;
+
+/**
+ *
+ * @author nithyasubramanian
+ */
+@AMXMetadata(type="web-security-deployer-mon", group="monitoring", isSingleton=false)
+@ManagedObject
+@Description( "Web application Security Deployment statistics" )
+public class WebSecurityDeployerStatsProvider {
+    
+    //Commenting the TimeStatistics to be implemented later
+
+   /* TimeStatisticImpl deploymentTime = new TimeStatisticImpl(0, 0, 0, 0, "DeploymentTime", "milliseconds", "Deployment Time", 0, 0);
+
+    TimeStatisticImpl generationTime = new TimeStatisticImpl(0, 0, 0, 0, "GenerationTime", "milliseconds", "Generation Time", 0, 0);
+
+    TimeStatisticImpl undeploymentTime = new TimeStatisticImpl(0, 0, 0, 0, "UndeploymentTime", "milliseconds", "Undeployment Time", 0, 0);
+
+    TimeStatisticImpl removalTime = new TimeStatisticImpl(0, 0, 0, 0, "RemovalTime", "milliseconds", "Removal Time", 0, 0);*/
+
+    CountStatisticImpl secMgrCount = new CountStatisticImpl("WebSecurityManagerCount", "count", "No of Web security managers");
+
+    CountStatisticImpl policyConfCount= new CountStatisticImpl("WebPolicyConfigurationCount", "count", "No of Policy Configuration Objects");
+
+ /*   @ManagedAttribute(id="depolymenttime")
+    public TimeStatistic getDeploymentTime() {
+        return deploymentTime.getStatistic();
+    }
+
+    @ManagedAttribute(id="generationtime")
+    public TimeStatistic getGenerationTime() {
+        return generationTime.getStatistic();
+    }
+
+    @ManagedAttribute(id="undepolymenttime")
+    public TimeStatistic getUndeploymentTime() {
+        return undeploymentTime.getStatistic();
+    }
+
+
+    @ManagedAttribute(id="removaltime")
+    public TimeStatistic getRemovalTime() {
+        return removalTime.getStatistic();
+    }*/
+
+    @ManagedAttribute(id="websecuritymanagercount")
+    public CountStatistic getWebSMCount() {
+        return secMgrCount;
+
+    }
+
+    @ManagedAttribute(id="webpolicyconfigurationcount")
+    public CountStatistic getPCCount() {
+        return policyConfCount;
+    }
+/*   @ProbeListener("glassfish:core:web:webDeploymentStartedEvent")
+    public void webDeploymentStartedEvent(@ProbeParam("appName")String appName){
+       deploymentTime.setStartTime(System.currentTimeMillis());
+    }
+
+    @ProbeListener("glassfish:core:web:webDeploymentEndedEvent")
+    public void webDeploymentEndedEvent(@ProbeParam("appName")String appName){
+
+    }*/
+
+    @ProbeListener("glassfish:security:web:securityManagerCreationEvent")
+    public void securityManagerCreationEvent(
+            @ProbeParam("appName") String appName) {
+        secMgrCount.increment();
+    }
+
+    @ProbeListener("glassfish:security:web:securityManagerDestructionEvent")
+    public void securityManagerDestructionEvent(
+            @ProbeParam("appName") String appName) {
+        secMgrCount.decrement();
+    }
+
+    @ProbeListener("glassfish:security:web:policyCreationEvent")
+    public void policyConfigurationCreationEvent(
+            @ProbeParam("contextId") String contextId) {
+        policyConfCount.increment();
+    }
+
+    @ProbeListener("glassfish:security:web:policyDestructionEvent")
+    public void policyConfigurationDestructionEvent(
+            @ProbeParam("contextId") String contextId) {
+        policyConfCount.decrement();
+    }
+
+
+
+
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/DisableSecureAdminCommand.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/DisableSecureAdminCommand.java
new file mode 100644
index 0000000..073449e
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/DisableSecureAdminCommand.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.admin.cli;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.security.SecurityLoggerInfo;
+
+import java.util.Iterator;
+import org.glassfish.api.I18n;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RestEndpoint;
+import org.glassfish.api.admin.RestEndpoints;
+import org.glassfish.api.admin.RuntimeType;
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+
+/**
+ * Adjusts the DAS configuration to turn off secure admin, as if by
+ * executing these commands:
+ * <pre>
+ * {@code
+
+asadmin -s set configs.config.server-config.network-config.network-listeners.network-listener.admin-listener.protocol=admin-listener
+
+asadmin -s delete-protocol sec-admin-listener
+asadmin -s delete-protocol admin-http-redirect
+asadmin -s delete-protocol pu-protocol
+}
+ * 
+ * @author Tim Quinn
+ */
+@Service(name = "disable-secure-admin")
+@PerLookup
+@I18n("disable.secure.admin.command")
+@ExecuteOn({RuntimeType.DAS,RuntimeType.INSTANCE})
+@RestEndpoints({
+    @RestEndpoint(configBean=Domain.class,
+        opType=RestEndpoint.OpType.POST, 
+        path="disable-secure-admin", 
+        description="disable-secure-admin")
+})
+@AccessRequired(resource="domain/secure-admin", action="disable")
+public class DisableSecureAdminCommand extends SecureAdminCommand {
+
+    @Override
+    protected String transactionErrorMessageKey() {
+        return SecurityLoggerInfo.disablingSecureAdminError;
+    }
+
+    @Override
+    Iterator<Work<TopLevelContext>> secureAdminSteps() {
+        return reverseStepsIterator(secureAdminSteps);
+    }
+
+    @Override
+    Iterator<Work<ConfigLevelContext>> perConfigSteps() {
+        return reverseStepsIterator(perConfigSteps);
+    }
+
+    /**
+     * Iterator which returns array elements from back to front.
+     * @param <T>
+     * @param steps
+     * @return
+     */
+    private <T extends SecureAdminCommand.Context> Iterator<Work<T>> reverseStepsIterator(Step<T>[] steps) {
+        return new Iterator<Work<T>> () {
+            private Step<T>[] steps;
+            private int nextSlot;
+
+            @Override
+            public boolean hasNext() {
+                return nextSlot >= 0;
+            }
+
+            /**
+             * Returns the disable work associated with the next step we should
+             * process for disabling secure admin.
+             */
+            @Override
+            public Work<T> next() {
+                return steps[nextSlot--].disableWork();
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+
+            Iterator<Work<T>> init(Step<T>[] steps) {
+                this.steps = steps;
+                nextSlot = this.steps.length - 1;
+                return this;
+            }
+
+        }.init(steps);
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/EnableSecureAdminCommand.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/EnableSecureAdminCommand.java
new file mode 100644
index 0000000..c663af5
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/EnableSecureAdminCommand.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.admin.cli;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.SecureAdmin;
+import com.sun.enterprise.config.serverbeans.SecureAdminHelper;
+import com.sun.enterprise.config.serverbeans.SecureAdminHelper.SecureAdminCommandException;
+import com.sun.enterprise.config.serverbeans.SecureAdminPrincipal;
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.security.ssl.SSLUtils;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.UUID;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RestEndpoint;
+import org.glassfish.api.admin.RestEndpoints;
+import org.glassfish.api.admin.RuntimeType;
+import javax.inject.Inject;
+import org.glassfish.api.admin.AccessRequired;
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.TransactionFailure;
+
+/**
+ * Records that secure admin is to be used and adjusts each admin listener
+ * configuration in the domain to use secure admin.
+ *
+ * The command changes the admin-listener set-up within each separate
+ * configuration as if by running
+ * these commands:
+ * <pre>
+ * {@code
+        ###
+	### create new protocol for secure admin
+	###
+	asadmin create-protocol --securityenabled=true sec-admin-listener
+	asadmin create-http --default-virtual-server=__asadmin sec-admin-listener
+	#asadmin create-network-listener --listenerport 4849 --protocol sec-admin-listener sec-admin-listener
+	asadmin create-ssl --type network-listener --certname s1as --ssl2enabled=false --ssl3enabled=false --clientauthenabled=false sec-admin-listener
+        asadmin set configs.config.server-config.network-config.protocols.protocol.sec-admin-listener.ssl.client-auth=want
+	asadmin set configs.config.server-config.network-config.protocols.protocol.sec-admin-listener.ssl.classname=com.sun.enterprise.security.ssl.GlassfishSSLImpl
+
+
+	###
+	### create the port redirect config
+	###
+	asadmin create-protocol --securityenabled=false admin-http-redirect
+	asadmin create-http-redirect --secure-redirect true admin-http-redirect
+	#asadmin create-http-redirect --secure-redirect true --redirect-port 4849 admin-http-redirect
+	asadmin create-protocol --securityenabled=false pu-protocol
+	asadmin create-protocol-finder --protocol pu-protocol --targetprotocol sec-admin-listener --classname org.glassfish.grizzly.config.portunif.HttpProtocolFinder http-finder
+	asadmin create-protocol-finder --protocol pu-protocol --targetprotocol admin-http-redirect --classname org.glassfish.grizzly.config.portunif.HttpProtocolFinder admin-http-redirect
+
+	###
+	### update the admin listener
+	###
+	asadmin set configs.config.server-config.network-config.network-listeners.network-listener.admin-listener.protocol=pu-protocol
+ * }
+ *
+ *
+ * @author Tim Quinn
+ */
+@Service(name = "enable-secure-admin")
+@PerLookup
+@I18n("enable.secure.admin.command")
+@ExecuteOn({RuntimeType.DAS,RuntimeType.INSTANCE})
+@RestEndpoints({
+    @RestEndpoint(configBean=Domain.class,
+        opType=RestEndpoint.OpType.POST, 
+        path="enable-secure-admin", 
+        description="enable-secure-admin")
+})
+@AccessRequired(resource="domain/secure-admin", action="enable")
+public class EnableSecureAdminCommand extends SecureAdminCommand {
+
+    @Param(optional = true, defaultValue = SecureAdmin.Duck.DEFAULT_ADMIN_ALIAS)
+    public String adminalias;
+
+    @Param(optional = true, defaultValue = SecureAdmin.Duck.DEFAULT_INSTANCE_ALIAS)
+    public String instancealias;
+
+    @Inject
+    private SSLUtils sslUtils;
+
+    @Inject
+    private SecureAdminHelper secureAdminHelper;
+
+    private KeyStore keystore = null;
+
+    @Override
+    public void run() throws TransactionFailure, SecureAdminCommandException {
+        try {
+            ensureNoAdminUsersWithEmptyPassword();
+        } catch (SecureAdminCommandException ex) {
+            throw ex;
+        } catch (Exception ex) {
+            throw new TransactionFailure((ex.getMessage() != null ? ex.getMessage() : ""));
+        }
+            super.run();
+    }
+
+    private void ensureNoAdminUsersWithEmptyPassword() throws SecureAdminCommandException {
+        boolean isAdminUserWithoutPassword;
+        try {
+            isAdminUserWithoutPassword = secureAdminHelper.isAnyAdminUserWithoutPassword();
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+        if (isAdminUserWithoutPassword) {
+            throw new SecureAdminCommandException(Strings.get("adminsWithEmptyPW"));
+        }
+        
+    }
+
+    
+    @Override
+    Iterator<Work<TopLevelContext>> secureAdminSteps() {
+        return stepsIterator(secureAdminSteps);
+    }
+
+    @Override
+    Iterator<Work<ConfigLevelContext>> perConfigSteps() {
+        return stepsIterator(perConfigSteps);
+    }
+
+    /**
+     * Iterator which returns array elements from front to back.
+     * @param <T>
+     * @param steps
+     * @return
+     */
+    private <T  extends SecureAdminCommand.Context> Iterator<Work<T>> stepsIterator(Step<T>[] steps) {
+        return new Iterator<Work<T>> () {
+            private Step<T>[] steps;
+            private int nextSlot;
+
+            @Override
+            public boolean hasNext() {
+                return nextSlot < steps.length;
+            }
+
+            @Override
+            public Work<T> next() {
+                return steps[nextSlot++].enableWork();
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+
+            Iterator<Work<T>> init(Step<T>[] values) {
+                this.steps = values;
+                nextSlot  = 0;
+                return this;
+            }
+
+        }.init(steps);
+    }
+    
+    @Override
+    protected boolean updateSecureAdminSettings(
+            final SecureAdmin secureAdmin_w) {
+        /*
+         * Apply the values for the aliases.  We do this whether the user
+         * gave explicit values or not, because we need to do some work
+         * even for the default aliases.
+         */
+        try {
+            final List<String> badAliases = new ArrayList<String>();
+            secureAdmin_w.setDasAlias(processAlias(adminalias, 
+                    SecureAdmin.Duck.DEFAULT_ADMIN_ALIAS, 
+                    secureAdmin_w, badAliases));
+            secureAdmin_w.setInstanceAlias(processAlias(instancealias, 
+                    SecureAdmin.Duck.DEFAULT_INSTANCE_ALIAS,
+                    secureAdmin_w, badAliases));
+            
+            ensureSpecialAdminIndicatorIsUnique(secureAdmin_w);
+            
+            if (badAliases.size() > 0) {
+                throw new SecureAdminCommandException(
+                        Strings.get("enable.secure.admin.badAlias",
+                        badAliases.size(), badAliases.toString()));
+            }
+            ensureSpecialAdminIndicatorIsUnique(secureAdmin_w);
+            return true;
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private String processAlias(String alias, final String defaultAlias, final SecureAdmin secureAdmin_w,
+            Collection<String> badAliases) throws IOException, KeyStoreException {
+        boolean isAliasOK;
+        /*
+         * Do not validate the default aliases.  The user might be using
+         * password-based inter-process authentication in which case the aliases
+         * might not even be present in the keystore and/or truststore.  
+         */
+        if (alias.equals(defaultAlias)) {
+            isAliasOK = true;
+        } else {
+            isAliasOK = validateAlias(alias);
+            if ( ! isAliasOK) {
+                badAliases.add(alias);
+            }
+        }
+        if (isAliasOK) {
+            /*
+             * If there is no SecureAdminPrincipal for the DN corresponding
+             * to the specified alias then add one now.
+             */
+            ensureSecureAdminPrincipalForAlias(alias,
+                    secureAdmin_w);
+        }
+        return alias;   
+    }
+
+    @Override
+    protected String transactionErrorMessageKey() {
+        return SecurityLoggerInfo.enablingSecureAdminError;
+    }
+
+    private void ensureSpecialAdminIndicatorIsUnique(final SecureAdmin secureAdmin_w) {
+        if (secureAdmin_w.getSpecialAdminIndicator().equals(SecureAdmin.Util.ADMIN_INDICATOR_DEFAULT_VALUE)) {
+            /*
+             * Set the special admin indicator to a unique identifier.
+             */
+             final UUID uuid = UUID.randomUUID();
+             secureAdmin_w.setSpecialAdminIndicator(uuid.toString());
+        }
+    }
+    
+    /**
+     * Makes sure there is a SecureAdminPrincipal entry for the specified
+     * alias.  If not, one is added in the context of the current
+     * transaction.
+     * 
+     * @param alias the alias to check for
+     * @param secureAdmin_w SecureAdmin instance (already in a transaction)
+     */
+    private void ensureSecureAdminPrincipalForAlias(final String alias,
+            final SecureAdmin secureAdmin_w) {
+        SecureAdminPrincipal p = getSecureAdminPrincipalForAlias(alias, secureAdmin_w);
+        if (p != null) {
+            return;
+        }
+        try {
+            /*
+             * Create a new SecureAdminPrincipal.
+             */
+            final String dn = secureAdminHelper.getDN(alias, true);
+            p = secureAdmin_w.createChild(SecureAdminPrincipal.class);
+            p.setDn(dn);
+            secureAdmin_w.getSecureAdminPrincipal().add(p);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+    
+    private SecureAdminPrincipal getSecureAdminPrincipalForAlias(final String alias,
+            final SecureAdmin secureAdmin_w) {
+        try {
+            final String dnForAlias = secureAdminHelper.getDN(alias, true);
+            for (SecureAdminPrincipal p : secureAdmin_w.getSecureAdminPrincipal()) {
+                if (p.getDn().equals(dnForAlias)) {
+                    return p;
+                }
+            }
+            return null;
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+    
+    private synchronized KeyStore keyStore() throws IOException {
+        if (keystore == null) {
+            keystore = sslUtils.getKeyStore();
+        }
+        return keystore;
+    }
+
+    private boolean validateAlias(final String alias) throws IOException, KeyStoreException  {
+        return keyStore().containsAlias(alias);
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminCommand.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminCommand.java
new file mode 100644
index 0000000..c8efef7
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminCommand.java
@@ -0,0 +1,963 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.admin.cli;
+
+import com.sun.enterprise.config.serverbeans.AdminService;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Configs;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.JmxConnector;
+import com.sun.enterprise.config.serverbeans.SecureAdmin;
+import com.sun.enterprise.config.serverbeans.SecureAdminHelper.SecureAdminCommandException;
+import com.sun.enterprise.security.SecurityLoggerInfo;
+
+import org.glassfish.grizzly.config.dom.FileCache;
+import org.glassfish.grizzly.config.dom.Http;
+import org.glassfish.grizzly.config.dom.HttpRedirect;
+import org.glassfish.grizzly.config.dom.NetworkConfig;
+import org.glassfish.grizzly.config.dom.NetworkListener;
+import org.glassfish.grizzly.config.dom.PortUnification;
+import org.glassfish.grizzly.config.dom.Protocol;
+import org.glassfish.grizzly.config.dom.ProtocolFinder;
+import org.glassfish.grizzly.config.dom.Protocols;
+import org.glassfish.grizzly.config.dom.Ssl;
+import java.beans.PropertyVetoException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.glassfish.api.ActionReport;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import javax.inject.Inject;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.Transaction;
+import org.jvnet.hk2.config.TransactionFailure;
+
+/**
+ * Provides common behavior for the enable and disable secure admin commands.
+ * <p>
+ * This class, and the concrete subclasses EnableSecureAdminCommand and
+ * DisableSecureAdminComment, define what must be done in terms of steps.
+ * Each step has enable work and disable work.  This class builds 
+ * arrays of steps, one array which operates at the domain level and one which
+ * operates at the config level.  The enable work of these steps is run in order through
+ * the array to fully
+ * enable secure admin, and the disable work of these steps are run in REVERSE
+ * order to fully disable secure admin.
+ * <p>
+ * I have defined the steps and their enable and disable work here, together
+ * in some inner classes, rather than separately in the EnableSecureAdminCommand
+ * and DisableSecureAdminCommand classes to try to keep common details together.
+ * The concrete subclasses can override a few methods, in particular overriding
+ * methods which return an Iterator over the steps to be performed.  This way we
+ * have a single array of all the steps, with each class returning a forward-running
+ * or reverse-running iterator over those steps.
+ *
+ * @author Tim Quinn
+ */
+public abstract class SecureAdminCommand implements AdminCommand {
+
+    final static String SEC_ADMIN_LISTENER_PROTOCOL_NAME = "sec-admin-listener";
+    private final static String REDIRECT_PROTOCOL_NAME = "admin-http-redirect";
+    public final static String ADMIN_LISTENER_NAME = "admin-listener";
+    static final String DAS_CONFIG_NAME = "server-config";
+    final static String PORT_UNIF_PROTOCOL_NAME = "pu-protocol";
+    
+    static final Logger logger = SecurityLoggerInfo.getLogger();
+
+
+    @Inject
+    protected Domain domain;
+
+    /**
+     * Applies changes other than whether secure admin is enabled or disabled
+     * to the secure-admin element.
+     * <p>
+     * This method is primarily for the enable processing to apply the
+     * admin and/or instance alias values, if specified on the enable-secure-admin
+     * command, to the secure-admin element.
+     *
+     * @param secureAdmin_w
+     * @return
+     */
+    boolean updateSecureAdminSettings(
+            final SecureAdmin secureAdmin_w) throws TransactionFailure {
+        /*
+         * Default implementation - currently used by DisableSecureAdminCommand
+         * and overridden by EnableSecureAdminCommand.
+         */
+        return true;
+    }
+
+    interface Context {
+    }
+
+    /**
+     * Work to be performed - either for enable or disable - in a step.
+     * @param <T>
+     */
+    interface Work<T extends Context> {
+        boolean run(final T context) throws TransactionFailure;
+    }
+
+    /**
+     * A step to be performed during enabling or disabling secure admin.
+     *
+     * @param <T> either TopLevelContext or ConfigLevelContext, depending on
+     * whether the step applies per-domain or per-config.
+     */
+    interface Step<T extends Context> {
+        Work<T> enableWork();
+        Work<T> disableWork();
+    }
+
+//    interface TopLevelStep {
+//        TopLevelWork enableWork();
+//        TopLevelWork disableWork();
+//    }
+
+//    /**
+//     * The contract for performing the work associate with a single step of
+//     * enabling or disabling secure admin.
+//     */
+//    interface SecureAdminWork<T> {
+//        boolean run(
+//                Transaction t,
+//                AdminCommandContext context,
+//                T writeableConfigBean) throws TransactionFailure;
+//    }
+//
+//    /**
+//     * Enabling or disabling secure admin each involves multiple steps.
+//     * Each step has some logic run during enable and some logic run during disable
+//     * @param <T>
+//     */
+//    interface SecureAdminStep<T> {
+//        SecureAdminWork<T> enableWork();
+//        SecureAdminWork<T> disableWork();
+//    }
+
+    static class AbstractContext implements Context {
+    }
+
+    /**
+     * Keeps track of whether we've found writable versions of various 
+     * ConfigBeans.
+     */
+    static class TopLevelContext extends AbstractContext {
+
+        private final Transaction t;
+        private final Domain d;
+        private Domain d_w = null;
+
+        private SecureAdmin secureAdmin_w = null;
+
+        TopLevelContext(
+                final Transaction t,
+                final Domain d) {
+            this.t = t;
+            this.d = d;
+        }
+
+
+        Domain writableDomain() throws TransactionFailure {
+            if (d_w == null) {
+                d_w = t.enroll(d);
+            }
+            return d_w;
+        }
+
+        /*
+         * Gets the SecureAdmin object in writeable form, from the specified
+         * domain if the SecureAdmin object already exists or by creating a new
+         * one attached to the domain if one does not already exist.
+         */
+        SecureAdmin writableSecureAdmin() throws TransactionFailure {
+            if (secureAdmin_w == null) {
+
+                /*
+                 * Create the secure admin node if it is not already there.
+                 */
+                SecureAdmin secureAdmin = d.getSecureAdmin();
+                if (secureAdmin == null) {
+                    secureAdmin_w = writableDomain().createChild(SecureAdmin.class);
+                    writableDomain().setSecureAdmin(secureAdmin_w);
+                } else {
+                    /*
+                     * It already existed, so join it to the transaction.
+                     */
+                    secureAdmin_w = t.enroll(secureAdmin);
+                }
+            }
+            return secureAdmin_w;
+        }
+    }
+
+    /**
+     * Tracks writable config beans for each configuration.
+     */
+    static class ConfigLevelContext extends AbstractContext {
+
+        private static final String CLIENT_AUTH_VALUE = "want";
+        private static final String SSL3_ENABLED_VALUE = "false";
+        private static final String CLASSNAME_VALUE = "com.sun.enterprise.security.ssl.GlassfishSSLImpl";
+        
+        private final Transaction t;
+        private final Config config_w;
+        private final TopLevelContext topLevelContext;
+
+        private Protocols protocols_w = null;
+        private Map<String,Protocol> namedProtocols_w = new
+                HashMap<String,Protocol>();
+
+        private JmxConnector jmxConnector_w = null;
+        private Ssl jmxConnectorSsl_w = null;
+
+        ConfigLevelContext(
+                final TopLevelContext topLevelContext,
+                final Config config_w) {
+            this.topLevelContext = topLevelContext;
+            this.t = topLevelContext.t;
+            this.config_w = config_w;
+        }
+
+        /**
+         * Prepares a given Ssl configuration instance so the connection 
+         * represented by the Ssl's parent configuration object operates
+         * securely, using SSL.
+         * 
+         * @param ssl_w writeable Ssl instance to be modified
+         * @param certNickname the cert nickname to be used by the connection to identify itself
+         * @return 
+         */
+        private static Ssl initSsl(final Ssl ssl_w, final String certNickname) {
+            ssl_w.setClientAuth(CLIENT_AUTH_VALUE);
+            ssl_w.setSsl3Enabled(SSL3_ENABLED_VALUE);
+            ssl_w.setClassname(CLASSNAME_VALUE);
+            ssl_w.setCertNickname(certNickname);
+            ssl_w.setRenegotiateOnClientAuthWant(true);
+            return ssl_w;
+        }
+        
+        private static String chooseCertNickname(
+                final String configName,
+                final String dasAlias,
+                final String instanceAlias) throws TransactionFailure {
+            return (configName.equals(DAS_CONFIG_NAME) ? dasAlias : instanceAlias);
+        }
+        
+        private JmxConnector writeableJmxConnector() throws TransactionFailure {
+            if (jmxConnector_w == null) {
+                final AdminService adminService = config_w.getAdminService();
+                if (adminService == null) {
+                    return null;
+                }
+                final JmxConnector jmxC = adminService.getSystemJmxConnector();
+                if (jmxC == null) {
+                    return null;
+                }
+                jmxConnector_w = t.enroll(jmxC);
+            }
+            return jmxConnector_w;
+        }
+        
+        private Ssl writeableJmxSSL() throws TransactionFailure, PropertyVetoException {
+            if (jmxConnectorSsl_w == null) {
+                final JmxConnector jmxC_w = writeableJmxConnector();
+                if (jmxC_w == null) {
+                    return null;
+                }
+                Ssl jmxConnectorSsl = jmxC_w.getSsl();
+                if (jmxConnectorSsl == null) {
+                    jmxConnectorSsl = jmxC_w.createChild(Ssl.class);
+                    jmxC_w.setSsl(jmxConnectorSsl);
+                    jmxConnectorSsl_w = jmxConnectorSsl;
+                } else {
+                    jmxConnectorSsl_w = t.enroll(jmxConnectorSsl);
+                }
+            }
+            return jmxConnectorSsl_w;
+        }
+        private Protocols writableProtocols() throws TransactionFailure {
+            if (protocols_w == null) {
+                final NetworkConfig nc = config_w.getNetworkConfig();
+                if (nc == null) {
+                    return null;
+                }
+                final Protocols p = nc.getProtocols();
+                protocols_w = t.enroll(p);
+            }
+            return protocols_w;
+        }
+
+        private Protocol writableProtocol(final String protocolName,
+                final boolean isSecure) throws TransactionFailure {
+            Protocol p_w = namedProtocols_w.get(protocolName);
+            if (p_w == null) {
+                /*
+                 * Try to find an existing entry for this protocol.
+                 */
+                final Protocol p_r = findProtocol(protocolName);
+                if (p_r == null) {
+                    final Protocols ps_w = writableProtocols();
+                    if (ps_w == null) {
+                        return null;
+                    }
+                    p_w = ps_w.createChild(Protocol.class);
+                    p_w.setName(protocolName);
+                    ps_w.getProtocol().add(p_w);
+                } else {
+                    p_w = t.enroll(p_r);
+                }
+                namedProtocols_w.put(protocolName, p_w);
+            }
+            p_w.setSecurityEnabled(Boolean.toString(isSecure));
+            return p_w;
+        }
+
+        private Protocol findProtocol(final String protocolName) {
+            final NetworkConfig nc = config_w.getNetworkConfig();
+            if (nc == null) {
+                return null;
+            }
+            final Protocols ps = nc.getProtocols();
+            if (ps == null) {
+                return null;
+            }
+            return ps.findProtocol(protocolName);
+        }
+
+        private void deleteProtocol(
+                    final String protocolName) throws TransactionFailure {
+                final Protocols ps_w = writableProtocols();
+                if (ps_w == null) {
+                    return;
+                }
+                final Protocol doomedProtocol = ps_w.findProtocol(protocolName);
+                if (doomedProtocol != null) {
+                    ps_w.getProtocol().remove(doomedProtocol);
+                }
+            }
+    }
+
+    /**
+     * Updates the secure-admin element itself.
+     * <p>
+     * The concrete command implementation classes implement updateSecureAdminSettings
+     * differently but they expose the same method signature, so onEnable and
+     * onDisable just invoke the same method.
+     */
+    private Step<TopLevelContext> perDomainStep = new Step<TopLevelContext>() {
+
+        /**
+         * Sets enabled=true/false on the secure-admin element.
+         */
+        private void updateSecureAdminEnabledSetting(
+                final SecureAdmin secureAdmin_w,
+                final boolean newEnabledValue) {
+            secureAdmin_w.setEnabled(Boolean.toString(newEnabledValue));
+        }
+
+        /*
+         * Both the enable and disable steps for the "secure admin element only"
+         * task set the enabled value and then let the concrete command
+         * subclass do any additional work.
+         */
+        class TopLevelWork implements Work<TopLevelContext> {
+
+            private final boolean newEnabledState;
+
+            TopLevelWork(final boolean newEnabledState) {
+                this.newEnabledState = newEnabledState;
+            }
+
+            @Override
+            public boolean run(final TopLevelContext context) throws TransactionFailure {
+                final SecureAdmin secureAdmin_w = context.writableSecureAdmin();
+                updateSecureAdminEnabledSetting(
+                        secureAdmin_w, newEnabledState);
+                /*
+                 * The subclass might have overridden updateSecureAdminSettings.
+                 * Give it a change to run logic specific to enable or disable.
+                 */
+                return SecureAdminCommand.this.updateSecureAdminSettings(secureAdmin_w);
+            }
+        }
+        
+        @Override
+        public Work<TopLevelContext> enableWork() {
+            return new TopLevelWork(true);
+            };
+
+        @Override
+        public Work<TopLevelContext> disableWork() {
+            return new TopLevelWork(false);
+        }
+    };
+
+    /**
+     * Manages the jmx-connector settings.
+     */
+    private Step<ConfigLevelContext> jmxConnectorStep = new Step<ConfigLevelContext>() {
+
+        /**
+         * Sets the jmx-connector security-enabled to true and creates and
+         * initializes the child ssl element.
+         */
+        @Override
+        public Work<ConfigLevelContext> enableWork() {
+            return new Work<ConfigLevelContext>() {
+
+                @Override
+                public boolean run(ConfigLevelContext context) throws TransactionFailure {
+                    /*
+                     * Make sure the JMX connector is enabled for secure operation.
+                     * Then make sure the JMX Connector's SSL child is present
+                     * and correctly set up.
+                     */
+                    final JmxConnector jmxConnector_w = context.writeableJmxConnector();
+                    if (jmxConnector_w == null) {
+                        return false;
+                    }
+                    try {
+                        jmxConnector_w.setSecurityEnabled("true");
+                        final Ssl ssl_w = context.writeableJmxSSL();
+                        ConfigLevelContext.initSsl(ssl_w, ConfigLevelContext.chooseCertNickname(
+                                context.config_w.getName(),
+                                context.topLevelContext.writableSecureAdmin().dasAlias(),
+                                context.topLevelContext.writableSecureAdmin().instanceAlias()));
+                        return true;
+                    } catch (Exception ex) {
+                        throw new RuntimeException(ex);
+                    }
+                }
+                
+            };
+        }
+
+        @Override
+        public Work<ConfigLevelContext> disableWork() {
+            return new Work<ConfigLevelContext>() {
+
+                @Override
+                public boolean run(ConfigLevelContext context) throws TransactionFailure {
+                    /*
+                     * Remove the SSL child of the JMX configuration.  Then
+                     * turn off the security-enabled attribute of the JMX config.
+                     */
+                    final JmxConnector jmxC_w = context.writeableJmxConnector();
+                    try {
+                        jmxC_w.setSsl(null);
+                        jmxC_w.setSecurityEnabled("false");
+                        return true;
+                    } catch (PropertyVetoException ex) {
+                        throw new RuntimeException(ex);
+                    }
+                }
+                
+            };
+        }
+    };
+    
+    /**
+     * Manages the sec-admin-listener protocol.
+     */
+    private Step<ConfigLevelContext> secAdminListenerProtocolStep = new Step<ConfigLevelContext>() {
+
+        private static final String ASADMIN_VIRTUAL_SERVER_NAME = "__asadmin";
+
+        private static final String AUTH_LAYER_NAME = "HttpServlet";
+        private static final String PROVIDER_ID_VALUE = "GFConsoleAuthModule";
+
+        private Http writeableHttpWithFileCacheChild(final Transaction t,
+                final Protocol secAdminListenerProtocol_w) throws TransactionFailure {
+            /*
+             * Because of the calling context, the secAdminListenerProtocol is already
+             * writeable -- it was just created moments ago and has not yet
+             * been committed.
+             */
+            Http http_w;
+            Http http = secAdminListenerProtocol_w.getHttp();
+            if (http == null) {
+                http_w = secAdminListenerProtocol_w.createChild(Http.class);
+                secAdminListenerProtocol_w.setHttp(http_w);
+            } else {
+                http_w = t.enroll(http);
+            }
+            http_w.setDefaultVirtualServer(ASADMIN_VIRTUAL_SERVER_NAME);
+            http_w.setEncodedSlashEnabled("true");
+            
+            final FileCache cache = http_w.createChild(FileCache.class);
+//            cache.setEnabled("false");
+            http_w.setFileCache(cache);
+                    
+            return http_w;
+        }
+
+        private Ssl writeableSsl(final Transaction t,
+                final Protocol secAdminListenerProtocol_w,
+                final String certNickname) throws TransactionFailure {
+            Ssl ssl_w = null;
+            Ssl ssl = secAdminListenerProtocol_w.getSsl();
+            if (ssl == null) {
+                ssl_w = secAdminListenerProtocol_w.createChild(Ssl.class);
+                secAdminListenerProtocol_w.setSsl(ssl_w);
+            } else {
+                ssl_w = t.enroll(ssl);
+            }
+            return ConfigLevelContext.initSsl(ssl_w, certNickname);
+        }
+        
+        @Override
+        public Work<ConfigLevelContext> enableWork() {
+            return new Work<ConfigLevelContext>() {
+
+                @Override
+                public boolean run(final ConfigLevelContext context) throws TransactionFailure {
+                    /*
+                     * Get an existing or new writeable sec-admin-listener protocol.
+                     */
+                    final Protocol secAdminListenerProtocol_w =
+                            context.writableProtocol(SEC_ADMIN_LISTENER_PROTOCOL_NAME,
+                            true);
+
+                    /*
+                     * It seems possible to create configs without network listeners
+                     * and children.  In that case it's not a real config so we
+                     * will skip it.
+                     */
+                    if (secAdminListenerProtocol_w == null) {
+                        return false;
+                    }
+                    
+                    /*
+                     * Get an existing or create a new writeable http child under the new protocol.
+                     */
+                    writeableHttpWithFileCacheChild(context.t, secAdminListenerProtocol_w);
+
+                    /*
+                     * Get an existing or create a new writeable ssl child under the new protocol.
+                     * Which cert nickname we set depends on whether this is the DAS's config
+                     * we're working on or an instance's.  
+                     */
+                    writeableSsl(context.t, secAdminListenerProtocol_w,
+                            ConfigLevelContext.chooseCertNickname(
+                                context.config_w.getName(),
+                                context.topLevelContext.writableSecureAdmin().dasAlias(),
+                                context.topLevelContext.writableSecureAdmin().instanceAlias()));
+
+                    return true;
+                }
+            };
+        }
+
+        @Override
+        public Work<ConfigLevelContext> disableWork() {
+            return new Work<ConfigLevelContext>() {
+
+                @Override
+                public boolean run(ConfigLevelContext context) throws TransactionFailure {
+
+
+                    context.deleteProtocol(SEC_ADMIN_LISTENER_PROTOCOL_NAME);
+
+                    return true;
+                }
+            };
+        }
+    };
+
+    private enum ProtocolFinderInfo {
+        HTTP_FINDER("http-finder", SEC_ADMIN_LISTENER_PROTOCOL_NAME),
+        ADMIN_HTTP_REDIRECT_FINDER("admin-http-redirect", REDIRECT_PROTOCOL_NAME);
+
+        private final String name;
+        private final String protocolName;
+        private final String classname = "org.glassfish.grizzly.config.portunif.HttpProtocolFinder";
+
+        private ProtocolFinderInfo(final String name, final String protocolName) {
+            this.name = name;
+            this.protocolName = protocolName;
+        }
+
+    }
+
+    private Step<ConfigLevelContext> secAdminPortUnifAndRedirectStep = new Step<ConfigLevelContext>() {
+
+        private final static String PORT_UNIF_PROTOCOL_NAME = "pu-protocol";
+        private final static String UNSECURE_ADMIN_LISTENER_PROTOCOL_NAME = "admin-listener";
+
+        private final static String HTTP_FINDER_PROTOCOL_FINDER_NAME = "http-finder";
+        private final static String ADMIN_HTTP_REDIRECT_FINDER_NAME = "admin-http-redirect";
+
+        private final static String PROTOCOL_FINDER_CLASSNAME = "org.glassfish.grizzly.config.portunif.HttpProtocolFinder";
+
+
+        private HttpRedirect writeableHttpRedirect(
+                final Transaction t,
+                final Protocol adminHttpRedirectProtocol_w) throws TransactionFailure {
+            HttpRedirect redirect = adminHttpRedirectProtocol_w.getHttpRedirect();
+            HttpRedirect redirect_w;
+            if (redirect == null) {
+                redirect_w = adminHttpRedirectProtocol_w.createChild(HttpRedirect.class);
+                adminHttpRedirectProtocol_w.setHttpRedirect(redirect_w);
+            } else {
+                redirect_w = t.enroll(redirect);
+            }
+            redirect_w.setSecure(Boolean.TRUE.toString());
+            return redirect_w;
+        }
+
+        private PortUnification writeablePortUnification(
+                final Transaction t,
+                final Protocol protocol_w) throws TransactionFailure {
+            PortUnification pu_w;
+            PortUnification pu = protocol_w.getPortUnification();
+            if (pu == null) {
+                pu_w = protocol_w.createChild(PortUnification.class);
+                protocol_w.setPortUnification(pu_w);
+            } else {
+                pu_w = t.enroll(pu);
+            }
+            return pu_w;
+        }
+
+        private ProtocolFinder writeableProtocolFinder(
+                final Transaction t,
+                final PortUnification pu_w,
+                final ProtocolFinderInfo finderInfo) throws TransactionFailure {
+            ProtocolFinder pf_w = null;
+            for (ProtocolFinder pf : pu_w.getProtocolFinder()) {
+                if (pf.getName().equals(finderInfo.name)) {
+                    pf_w = t.enroll(pf);
+                    break;
+                }
+            }
+            if (pf_w == null) {
+                pf_w = pu_w.createChild(ProtocolFinder.class);
+                pu_w.getProtocolFinder().add(pf_w);
+            }
+            pf_w.setName(finderInfo.name);
+            pf_w.setClassname(finderInfo.classname);
+            pf_w.setProtocol(finderInfo.protocolName);
+            return pf_w;
+        }
+
+        private NetworkListener writableNetworkListener(
+                final Transaction t,
+                final Config config_w,
+                final String listenerName) throws TransactionFailure {
+            NetworkListener nl_w = null;
+            final NetworkConfig nc = config_w.getNetworkConfig();
+            if (nc == null) {
+                return null;
+            }
+            NetworkListener nl = nc.getNetworkListener(listenerName);
+            if (nl == null) {
+                return null;
+            } else {
+                nl_w = t.enroll(nl);
+            }
+            return nl_w;
+        }
+
+        
+
+        private void assignAdminListenerProtocol(
+                final Transaction t,
+                final Config config_w,
+                final String protocolName) throws TransactionFailure {
+            final NetworkListener nl_w = writableNetworkListener(t, config_w, ADMIN_LISTENER_NAME);
+            if (nl_w != null) {
+                nl_w.setProtocol(protocolName);
+            }
+        }
+
+        @Override
+        public Work<ConfigLevelContext> enableWork() {
+            return new Work<ConfigLevelContext>() {
+
+                @Override
+                public boolean run(ConfigLevelContext context) throws TransactionFailure {
+                    /*
+                     * Get an existing or new writeable admin-http-redirect protocol.
+                     */
+
+                    final Protocol adminHttpRedirectProtocol_w =
+                            context.writableProtocol(
+                            REDIRECT_PROTOCOL_NAME,
+                            false);
+
+                    if (adminHttpRedirectProtocol_w == null) {
+                        return true;
+                    }
+
+                    writeableHttpRedirect(
+                            context.t, adminHttpRedirectProtocol_w);
+
+                    final Protocol puProtocol_w = context.writableProtocol(
+                            PORT_UNIF_PROTOCOL_NAME,
+                            false);
+
+                    final PortUnification portUnif_w = writeablePortUnification(
+                            context.t, puProtocol_w);
+
+                    writeableProtocolFinder(
+                            context.t, portUnif_w, ProtocolFinderInfo.HTTP_FINDER);
+
+                    writeableProtocolFinder(
+                            context.t, portUnif_w, ProtocolFinderInfo.ADMIN_HTTP_REDIRECT_FINDER);
+
+                    assignAdminListenerProtocol(context.t, context.config_w, PORT_UNIF_PROTOCOL_NAME);
+                    
+                    return true;
+                }
+            };
+        }
+
+        @Override
+        public Work<ConfigLevelContext> disableWork() {
+            return new Work<ConfigLevelContext>() {
+
+            @Override
+                public boolean run(final ConfigLevelContext context) throws TransactionFailure {
+                    final Config config_w = context.config_w;
+                    final Transaction t = context.t;
+                    assignAdminListenerProtocol(t, config_w, UNSECURE_ADMIN_LISTENER_PROTOCOL_NAME);
+
+                    context.deleteProtocol(PORT_UNIF_PROTOCOL_NAME);
+                    context.deleteProtocol(REDIRECT_PROTOCOL_NAME);
+                    return true;
+                }
+
+            };
+        }
+
+    };
+
+//    /**
+//     * Details for managing the protocol associated directly with the
+//     * admin listener.  This logic takes care of creating
+//     * the sec-admin-listener protocol and assoociating it with
+//     * the admin listener, or deleting the sec-admin-listener protocol and
+//     * associating the admin listener back with the original protocol.
+//     */
+//    private SecureAdminWork adminListenerProtocolSetting = new SecureAdminWork<Config>() {
+//
+//        private final static String ADMIN_LISTENER_NETWORK_LISTENER_NAME = "admin-listener";
+//        private final static String ORIGINAL_ADMIN_LISTENER_PROTOCOL_NAME = "admin-listener";
+//
+//
+//        @Override
+//        public boolean onEnable(
+//                final Transaction t,
+//                final AdminCommandContext context,
+//                final Config tConfig) throws TransactionFailure {
+//            writeableAdminNetworkListener(tConfig).
+//                    setProtocol(SEC_ADMIN_LISTENER_PROTOCOL_NAME);
+//            return true;
+//        }
+//
+//        @Override
+//        public boolean onDisable(
+//                final Transaction t,
+//                final AdminCommandContext context,
+//                final Config tConfig
+//                ) throws TransactionFailure {
+//            writeableAdminNetworkListener(tConfig).
+//                    setProtocol(ORIGINAL_ADMIN_LISTENER_PROTOCOL_NAME);
+//            return true;
+//        }
+//
+//        private NetworkListener writeableAdminNetworkListener(
+//                final Config tConfig) throws TransactionFailure {
+//            return tConfig.getNetworkConfig().
+//                    getNetworkListener(ADMIN_LISTENER_NETWORK_LISTENER_NAME);
+//        }
+
+//        private NetworkListener writeableAdminNetworkListener(
+//                final Transaction t,
+//                final Config tConfig) throws TransactionFailure {
+//            ConfigSupport.apply(new SingleConfigCode<NetworkListener>() {
+//                @Override
+//                public Object run(NetworkListener nl) throws PropertyVetoException, TransactionFailure {
+//
+//                    try {
+//
+//                        for (Config c : configs.getConfig()) {
+//                            final MessagePart partForThisConfig = report.getTopMessagePart().addChild();
+//
+//                            /*
+//                             * Again, delegate to update the admin
+//                             * listener configuration.
+//                             */
+//                            updateAdminListenerConfig(context, t, c, partForThisConfig);
+//                        }
+//
+//                        t.commit();
+//                    } catch (RetryableException ex) {
+//                        throw new RuntimeException(ex);
+//                    }
+//
+//                    return Boolean.TRUE;
+//                }
+//            }, tConfig.getNetworkConfig().getNetworkListener(ADMIN_LISTENER_NETWORK_LISTENER_NAME));
+//        }
+//
+//    };
+
+    /**
+     * Tasks executed once per enable or disable.
+     */
+    final Step<TopLevelContext>[] secureAdminSteps =
+            new Step[] {
+        perDomainStep
+    };
+
+    
+    /**
+     * Tasks executed once per config during an enable or disable.
+     */
+    final Step<ConfigLevelContext>[] perConfigSteps =
+            new Step[] {
+        secAdminListenerProtocolStep,
+        secAdminPortUnifAndRedirectStep,
+        jmxConnectorStep
+    };
+
+    /**
+     * Returns the error key for finding a message describing an error
+     * during the operation - either enable or disable.
+     * <p>
+     * Each concrete subclass overrides this to supply the relevant message key.
+     *
+     * @return the message key corresponding to the error message to display
+     */
+    protected abstract String transactionErrorMessageKey();
+
+    /**
+     * Returns an Iterator over the work (enable work for enable-secure-admin,
+     * disable for disable-secure-admin) for the steps related to
+     * just the top-level secure-admin element.
+     *
+     * @return
+     */
+    abstract Iterator<Work<TopLevelContext>> secureAdminSteps();
+
+    /**
+     * Returna an Iterator over the work related to each configuration that
+     * has to be modified.
+     *
+     * @return
+     */
+    abstract Iterator<Work<ConfigLevelContext>> perConfigSteps();
+
+    /**
+     * Performs the enable/disable logic for secure admin.
+     * <p>
+     * This is separate from the execute method so it can be invoked during
+     * upgrade.
+     * 
+     * @throws TransactionFailure
+     */
+    public void run() throws TransactionFailure, SecureAdminCommandException {
+        ConfigSupport.apply(new SingleConfigCode<Domain>() {
+            @Override
+            public Object run(Domain domain_w) throws PropertyVetoException, TransactionFailure {
+
+                // get the transaction
+                final Transaction t = Transaction.getTransaction(domain_w);
+                final TopLevelContext topLevelContext = 
+                        new TopLevelContext(t, domain_w);
+                if (t!=null) {
+
+                    /*
+                     * Do the work on just the secure-admin element.
+                     */
+                    for (Iterator<Work<TopLevelContext>> it = secureAdminSteps(); it.hasNext();) {
+                        final Work<TopLevelContext> step = it.next();
+                        if ( ! step.run(topLevelContext) ) {
+                            t.rollback();
+                            return Boolean.FALSE;
+                        }
+                    }
+
+                    /*
+                     * Now apply the required changes to the admin listener
+                     * in the configurations.  Include all configs, because even
+                     * though the non-DAS configs default to use SSL the user
+                     * might have specified a different alias to use and that 
+                     * value must be set in the SSL element for the 
+                     * secure admin listener.
+                     */
+                    final Configs configs = domain_w.getConfigs();
+                    for (Config c : configs.getConfig()) {
+                        final Config c_w = t.enroll(c);
+                        ConfigLevelContext configLevelContext = 
+                                new ConfigLevelContext(topLevelContext, c_w);
+                        for (Iterator<Work<ConfigLevelContext>> it = perConfigSteps(); it.hasNext();) {
+                            final Work<ConfigLevelContext> step = it.next();
+                            if ( ! step.run(configLevelContext)) {
+                                t.rollback();
+                                return Boolean.FALSE;
+                            }
+                        }
+                    }
+                }
+
+                return Boolean.TRUE;
+            }
+        }, domain);
+    }
+    /**
+     * Executes the particular xxx-secure-admin command (enable or disable).
+     * @param context
+     */
+    @Override
+    public void execute(final AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+
+        try {
+            report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+            run();
+            report.setMessage(Strings.get("restartReq"));
+        } catch (TransactionFailure ex) {
+            report.failure(context.getLogger(), Strings.get(transactionErrorMessageKey()), ex);
+        } catch (SecureAdminCommandException ex) {
+            report.failure(context.getLogger(), ex.getLocalizedMessage());
+        }
+    }
+    
+    /*
+     * Executes the command with no action report.  Primarily useful from the
+     * upgrade class (which does not have a convenient action report).
+     */
+    void execute() throws TransactionFailure, SecureAdminCommandException {
+        try {
+            run();
+        } catch (TransactionFailure ex) {
+            logger.log(Level.SEVERE, Strings.get(transactionErrorMessageKey()), ex);
+            throw ex;
+        } catch (SecureAdminCommandException ex) {
+            logger.log(Level.SEVERE, ex.getLocalizedMessage());
+            throw ex;
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminConfigMonitor.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminConfigMonitor.java
new file mode 100644
index 0000000..0766b3e
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminConfigMonitor.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.admin.cli;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.SecureAdmin;
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import java.beans.PropertyChangeEvent;
+import java.util.logging.Logger;
+
+import org.glassfish.hk2.runlevel.RunLevel;
+import org.glassfish.internal.api.PostStartupRunLevel;
+import javax.inject.Inject;
+
+import org.jvnet.hk2.annotations.Service;
+import org.jvnet.hk2.config.Changed;
+import org.jvnet.hk2.config.Changed.TYPE;
+import org.jvnet.hk2.config.ConfigBeanProxy;
+import org.jvnet.hk2.config.ConfigListener;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.NotProcessed;
+import org.jvnet.hk2.config.UnprocessedChangeEvents;
+
+/**
+ * Tracks changes to secure admin configuration, basically so it can report
+ * restart-required.
+ *
+ * @author Tim Quinn
+ */
+@Service
+@RunLevel(PostStartupRunLevel.VAL)
+public class SecureAdminConfigMonitor implements ConfigListener {
+
+    private static final String restartRequiredMsg = Strings.get("secure.admin.change.requires.restart");
+
+    /*
+     * Must inject Domain to get notifications of SecureAdmin changes.  We
+     * cannot inject SecureAdmin itself because it might be null and that
+     * bothers some components.
+     */
+    @Inject
+    private Domain domain;
+
+    private Logger logger = SecurityLoggerInfo.getLogger();
+
+    
+    @Override
+    public UnprocessedChangeEvents changed(final PropertyChangeEvent[] events) {
+        return ConfigSupport.sortAndDispatch(
+            events, new Changed() {
+                @Override
+                public <T extends ConfigBeanProxy> NotProcessed changed(TYPE type,
+                    Class<T> tClass, T t) {
+                    if (t instanceof Domain) {
+                        return processDomain(type, (Domain) t, events);
+                    } else if (t instanceof SecureAdmin) {
+                        return processSecureAdmin(type, (SecureAdmin) t, events);
+                    }
+                    return null;
+                }
+            }, logger);
+    }
+
+    private NotProcessed processDomain(final TYPE type, final Domain d,
+            final PropertyChangeEvent[] events) {
+        for (PropertyChangeEvent event : events) {
+            if (   (event.getOldValue() instanceof SecureAdmin && type == Changed.TYPE.REMOVE)
+                || (event.getNewValue() instanceof SecureAdmin && type == Changed.TYPE.ADD) ) {
+                return new NotProcessed(restartRequiredMsg);
+            }
+        }
+        return null;
+    }
+
+    private NotProcessed processSecureAdmin(final TYPE type, final SecureAdmin sa,
+            final PropertyChangeEvent[] events) {
+        /*
+         * Any change to the secure admin config requires a restart.
+         */
+        return new NotProcessed(restartRequiredMsg);
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminConfigUpgrade.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminConfigUpgrade.java
new file mode 100644
index 0000000..bea48d7
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminConfigUpgrade.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.admin.cli;
+
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Configs;
+import com.sun.enterprise.config.serverbeans.HttpService;
+import com.sun.enterprise.config.serverbeans.SecureAdmin;
+import com.sun.enterprise.config.serverbeans.SecureAdminHelper.SecureAdminCommandException;
+import com.sun.enterprise.config.serverbeans.VirtualServer;
+import com.sun.enterprise.security.SecurityUpgradeService;
+import com.sun.enterprise.universal.process.ProcessManager;
+import com.sun.enterprise.universal.process.ProcessManagerException;
+import com.sun.enterprise.util.net.NetUtils;
+import org.glassfish.grizzly.config.dom.NetworkConfig;
+import org.glassfish.grizzly.config.dom.NetworkListener;
+import org.glassfish.grizzly.config.dom.NetworkListeners;
+import org.glassfish.grizzly.config.dom.Protocol;
+import org.glassfish.grizzly.config.dom.Ssl;
+import java.beans.PropertyVetoException;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.UnknownHostException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.api.admin.config.ConfigurationUpgrade;
+import org.glassfish.config.support.GrizzlyConfigSchemaMigrator;
+import javax.inject.Inject;
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PostConstruct;
+import org.glassfish.internal.api.Globals;
+import org.glassfish.security.common.MasterPassword;
+import org.jvnet.hk2.config.RetryableException;
+import org.jvnet.hk2.config.Transaction;
+import org.jvnet.hk2.config.TransactionFailure;
+
+/**
+ * Upgrades older config to current.
+ * 
+ * In 3.1.2 GlassFish uses SSL for DAS-to-instance traffic regardless of 
+ * whether the user enables secure admin.  This means that the upgrade must
+ * always:
+ * <ol>
+ * <li>Create the secure-admin element.
+ * <li>Add the glassfish-instance private key to the keystore and the 
+ * corresponding self-signed cert to the truststore.
+ * <li>Add secure-admin-principal children to secure-admin, one for alias s1as and
+ * one for glassfish-instance.
+ * <li>Add the Grizzly config for the non-DAS admin listener configurations to use port unification
+ * and redirection (and SSL).
+ * <li>If it seems the user has configured the old domain to use secure admin
+ * traffic then run the enable-secure-admin command.
+ * </ol>
+ *
+ * @author Tim Quinn
+ */
+@Service
+public class SecureAdminConfigUpgrade extends SecureAdminUpgradeHelper implements ConfigurationUpgrade, PostConstruct {
+
+    public SecureAdminConfigUpgrade() {
+        
+    }
+    private final static String ADMIN_LISTENER_NAME = "admin-listener";
+    
+    /*
+     * Constants used for creating a missing network-listener during upgrade.
+     * Ideally this will be handled in the grizzly upgrade code.
+     */
+    private final static String ASADMIN_LISTENER_PORT = "${ASADMIN_LISTENER_PORT}";
+    private final static String ASADMIN_LISTENER_TRANSPORT = "tcp";
+    private final static String ASADMIN_LISTENER_THREADPOOL = "http-thread-pool";
+
+    private final static String ASADMIN_VS_NAME = "__asadmin";
+        
+    private static final Logger logger = Logger.getAnonymousLogger();
+
+    // Thanks to Jerome for suggesting this injection to make sure the
+    // Grizzly migration runs before this migration
+    @Inject
+    private GrizzlyConfigSchemaMigrator grizzlyMigrator;
+
+    @Inject
+    private SecurityUpgradeService securityUpgradeService;
+
+    @Inject
+    private Configs configs;
+    
+    @Inject
+    private ServerEnvironment serverEnv;
+    
+    /**
+     * Inject this to make sure it is initialized.  It is used by 
+     * SecuritySupportImpl, but because SecuritySupportImpl is not a service
+     * hk2 does not operate on it and would not automatically initialize
+     * MasterPassword.
+     */
+    @Inject
+    private MasterPassword masterPassword;
+    
+    private Map<String,Config> writableConfigs = new HashMap<String,Config>();
+    
+    @Override
+    public void postConstruct() {
+        /*
+         * Make sure the darn Globals is set up, because it's used downstream
+         * from SecuritySupportImpl.
+         */
+        if (Globals.getDefaultHabitat() == null) {
+            Globals.setDefaultHabitat(habitat);
+        }
+        String stage = null;
+        try {
+            stage = "adding admin-listener to non-DAS configuration";
+            ensureNonDASConfigsHaveAdminNetworkListener();
+            logger.log(Level.INFO, "Added admin-listener network listeners to non-DAS configurations");
+
+            stage = "upgrading config for secure DAS-to-instance admin traffic";
+            setupNewDefaultConfig();
+            
+            /*
+             * See if we need to set up secure admin during the upgrade.
+             */
+            if (requiresSecureAdmin()) {
+                final EnableSecureAdminCommand enableSecureAdminCommand =
+                        habitat.getService(EnableSecureAdminCommand.class);
+                stage = "upgrading secure admin set-up";
+                try {
+                    enableSecureAdminCommand.run();
+                    logger.log(Level.INFO, "Upgraded secure admin set-up");
+                } catch (SecureAdminCommandException ex) {
+                    logger.log(Level.INFO,
+                                "Attempt to upgrade secure admin set-up failed",
+                                ex);
+                    throw ex;
+                }
+            } else {
+                logger.log(Level.INFO, "No secure admin set-up was detected in the original configuration so no upgrade of it was needed");
+            }
+            commit();
+        } catch (Exception ex) {
+            logger.log(Level.SEVERE, "Error " + stage, ex);
+            rollback();
+        }
+    }
+
+    private void setupNewDefaultConfig() throws 
+            IOException, NoSuchAlgorithmException, CertificateException, 
+            KeyStoreException, UnrecoverableKeyException, ProcessManagerException, TransactionFailure, RetryableException, PropertyVetoException {
+        /*
+         * In 3.1.2 the default config has a secure-admin element with child secure-admin-principal
+         * elements for the s1as and glassfish-instance aliases.  The keystore
+         * contains private keys for s1as and glassfish-instance (new in 3.x)
+         * and the truststore contains the self-signed certs for those two
+         * aliases.
+         */
+        ensureKeyPairForInstanceAlias();
+        
+        /*
+         * Add the secure-admin-principal children below secure-admin, one for
+         * the DAS alias and one for the instance alias.
+         */
+        ensureSecureAdminReady();
+        prepareDASConfig();
+//        prepareNonDASConfigs();
+    }
+    
+    private boolean requiresSecureAdmin() {
+        return isOriginalAdminSecured() || securityUpgradeService.requiresSecureAdmin();
+    }
+
+    private void prepareDASConfig() throws TransactionFailure, PropertyVetoException {
+        final Config dasConfig = writableConfig(configs.getConfigByName(DAS_CONFIG_NAME));
+        final NetworkConfig nc = dasConfig.getNetworkConfig();
+        final NetworkListener nl_w = transaction().enroll(nc.getNetworkListener(SecureAdminCommand.ADMIN_LISTENER_NAME));
+        nl_w.setProtocol(SecureAdminCommand.ADMIN_LISTENER_NAME);
+    }
+    
+//    private void prepareNonDASConfigs() throws TransactionFailure, PropertyVetoException {
+//        for (Config c : configs.getConfig()) {
+//            if (c.getName().equals(DAS_CONFIG_NAME)) {
+//                continue;
+//            }
+//            ensureConfigReady(c, SecureAdminCommand.PORT_UNIF_PROTOCOL_NAME);
+//        }
+//    }
+    
+    private void ensureConfigReady(final Config c, final String adminListenerProtocol) throws TransactionFailure, PropertyVetoException {
+        final NetworkConfig nc = c.getNetworkConfig();
+        final NetworkListener nl = nc.getNetworkListener(SecureAdminCommand.ADMIN_LISTENER_NAME);
+        if (nl != null) {
+            return;
+        }
+
+        /*
+         * Create an admin-listener for this configuration.
+         */
+        final Config config_w = writableConfig(c);
+        
+        createAdminNetworkListener(transaction(), nc, adminListenerProtocol);
+        createAdminVirtualServer(transaction(), config_w);
+    }
+    
+    private Config writableConfig(final Config c) throws TransactionFailure {
+        Config result = writableConfigs.get(c.getName());
+        if (result == null) {
+            result = transaction().enroll(c);
+            writableConfigs.put(c.getName(), result);
+        }
+        return result;
+    }
+    
+    private void ensureNonDASConfigsHaveAdminNetworkListener() throws TransactionFailure, PropertyVetoException {
+
+        for (Config c : configs.getConfig()) {
+            if (c.getName().equals(DAS_CONFIG_NAME)) {
+                continue;
+            }
+            ensureConfigReady(c, SecureAdminCommand.PORT_UNIF_PROTOCOL_NAME);
+        }
+    }
+    
+    
+
+    private NetworkListener createAdminNetworkListener(
+            final Transaction t,
+            final NetworkConfig nc,
+            final String adminListenerProtocolName) throws TransactionFailure {
+        final NetworkListeners nls_w = t.enroll(nc.getNetworkListeners());
+        final NetworkListener nl_w = nls_w.createChild(NetworkListener.class);
+        nls_w.getNetworkListener().add(nl_w);
+        nl_w.setName(ADMIN_LISTENER_NAME);
+        nl_w.setProtocol(adminListenerProtocolName);
+        nl_w.setPort(ASADMIN_LISTENER_PORT);
+        nl_w.setTransport(ASADMIN_LISTENER_TRANSPORT);
+        nl_w.setThreadPool(ASADMIN_LISTENER_THREADPOOL);
+        return nl_w;
+    }
+    
+    private VirtualServer createAdminVirtualServer(
+            final Transaction t,
+            final Config config_w) throws TransactionFailure, PropertyVetoException {
+        final HttpService hs_w = t.enroll(config_w.getHttpService());
+        final VirtualServer vs_w = hs_w.createChild(VirtualServer.class);
+        hs_w.getVirtualServer().add(vs_w);
+        vs_w.setId(ASADMIN_VS_NAME);
+        vs_w.setNetworkListeners(ADMIN_LISTENER_NAME);
+        return vs_w;
+    }
+    
+    
+    
+    private boolean isOriginalAdminSecured() {
+        /*
+         * The Grizzly conversion has already occurred.  So look for
+         * 
+         * <server-config>
+         *   <network-config>
+         *     <protocols>
+         *       <protocol name="admin-listener">
+         *         <ssl ...>
+         *
+         */
+         final Config serverConfig;
+         final NetworkConfig nc;
+         final Protocol p;
+         final Ssl ssl ;
+         if ((serverConfig = configs.getConfigByName(SecureAdminUpgradeHelper.DAS_CONFIG_NAME)) == null) {
+             return false;
+         }
+
+         if ((nc = serverConfig.getNetworkConfig()) == null) {
+             return false;
+         }
+
+         if ((p = nc.findProtocol(ADMIN_LISTENER_NAME)) == null) {
+             return false;
+         }
+
+         
+         if ((ssl = p.getSsl()) == null) {
+             return false;
+         }
+         return true;
+    }
+
+    private void ensureKeyPairForInstanceAlias() throws IOException, NoSuchAlgorithmException, CertificateException, KeyStoreException, UnrecoverableKeyException, ProcessManagerException {
+        /*
+         * No need to add glassfish-instance to the keystore if it already exists.
+         */
+        final KeyStore ks = sslUtils().getKeyStore();
+        if (ks.containsAlias(SecureAdmin.Duck.DEFAULT_INSTANCE_ALIAS)) {
+            return;
+        }
+        
+        /*
+         * This is ugly but effective.  We need to add a new private key to 
+         * the keystore and a new self-signed cert to the truststore.  To do so
+         * we run keytool commands to change the on-disk stores, then we 
+         * cause the in-memory copies to reload.
+         */
+        final File keyStoreFile = serverEnv.getJKS();
+        final File trustStoreFile = new File(serverEnv.getConfigDirPath(), "cacerts.jks");
+        final String pw = masterPassword();
+        
+        ProcessManager pm = new ProcessManager(new String[]{
+            "keytool",
+            "-genkey",
+            "-keyalg", "RSA",
+            "-keystore", keyStoreFile.getAbsolutePath(),
+            "-alias", SecureAdmin.Duck.DEFAULT_INSTANCE_ALIAS,
+            "-dname", getCertificateDN(),
+            "-validity", "3650",
+            "-keypass", pw,
+            "-storepass", pw,});
+        pm.execute();
+        if (pm.getExitValue() != 0) {
+            final String err = pm.getStdout();
+            throw new RuntimeException(err);
+        }
+        
+        final File tempCertFile = new File(serverEnv.getConfigDirPath(),"temp.cer");
+        tempCertFile.deleteOnExit();
+        pm = new ProcessManager(new String[] {
+            "keytool",
+            "-exportcert",
+            "-keystore", keyStoreFile.getAbsolutePath(),
+            "-alias", SecureAdmin.Duck.DEFAULT_INSTANCE_ALIAS,
+            "-keypass", pw,
+            "-storepass", pw,
+            "-file", tempCertFile.getAbsolutePath()
+        });
+        pm.execute();
+        
+        if (pm.getExitValue() != 0) {
+            throw new RuntimeException(pm.getStderr());
+        }
+        
+        pm = new ProcessManager(new String[] {
+            "keytool",
+            "-importcert",
+            "-noprompt",
+            "-trustcacerts",
+            "-storepass", pw,
+            "-keypass", pw,
+            "-keystore", trustStoreFile.getAbsolutePath(),
+            "-file", tempCertFile.getAbsolutePath(),
+            "-alias", SecureAdmin.Duck.DEFAULT_INSTANCE_ALIAS
+        });
+        pm.execute();
+        if ( ! tempCertFile.delete()) {
+            logger.log(Level.FINE, "Unable to delete temp file {0}; continuing", tempCertFile.getAbsolutePath());
+        }
+        
+        if (pm.getExitValue() != 0) {
+            throw new RuntimeException(pm.getStderr());
+        }
+        
+        /*
+         * Reload the keystore and truststore from disk.
+         */
+        reload(sslUtils().getKeyStore(), keyStoreFile, pw);
+        reload(sslUtils().getTrustStore(), serverEnv.getTrustStore(), pw);
+    }
+    
+    private void reload(final KeyStore keystore, final File keystoreFile, final String pw) throws 
+            FileNotFoundException, IOException, NoSuchAlgorithmException, CertificateException {
+        
+        InputStream is = null;
+        try {
+            is = new BufferedInputStream(new FileInputStream(keystoreFile));
+            keystore.load(is, pw.toCharArray());
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+        }
+    }
+    
+    private String masterPassword() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
+//        /*
+//         * Crude way to get the master password of the keystore.
+//         */
+//        if (masterPassword == null) {
+//            masterPassword = habitat.getService(MasterPassword.class);
+//        }
+//        return masterPassword.getMasterPasswordAdapter().getPasswordForAlias("s1as");
+        String masterPW = "changeit";
+        final String pwFileArg = startupArg("-passwordfile");
+        if (pwFileArg != null) {
+            final String masterPWFromPWFile = pwProps(pwFileArg).getProperty("AS_ADMIN_MASTERPASSWORD");
+            if (masterPWFromPWFile != null) {
+                masterPW = masterPWFromPWFile;
+            }
+        }
+        return masterPW;
+    }
+    
+    private Properties pwProps(final String pwFilePath) throws IOException {
+        Properties result = new Properties();
+        InputStream is = null;
+        try {
+            is = new BufferedInputStream(new FileInputStream(pwFilePath));
+            result.load(is);
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+            return result;
+        }
+    }
+    
+    private static String CERTIFICATE_DN_PREFIX = "CN=";
+
+    private static String CERTIFICATE_DN_SUFFIX =
+        ",OU=GlassFish,O=Oracle Corporation,L=Santa Clara,ST=California,C=US";
+
+    private static final String INSTANCE_CN_SUFFIX = "-instance";
+
+    private String getCertificateDN() throws UnknownHostException {
+        String cn;
+        try {
+            cn = NetUtils.getCanonicalHostName();
+        } catch(Exception e) {
+            cn = "localhost";
+        }
+        /*
+         * Use the suffix, if provided, in creating the DN (by augmenting
+         * the CN).
+         */
+        String x509DistinguishedName = CERTIFICATE_DN_PREFIX + cn +
+                INSTANCE_CN_SUFFIX + CERTIFICATE_DN_SUFFIX;
+        return x509DistinguishedName;  //must be of form "CN=..., OU=..."
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminHelperImpl.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminHelperImpl.java
new file mode 100644
index 0000000..637f619
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminHelperImpl.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.admin.cli;
+
+import com.sun.enterprise.config.serverbeans.AdminService;
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.SecureAdminHelper;
+import com.sun.enterprise.security.auth.realm.BadRealmException;
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import com.sun.enterprise.security.auth.realm.NoSuchUserException;
+import com.sun.enterprise.security.auth.realm.file.FileRealm;
+import com.sun.enterprise.security.auth.realm.file.FileRealmUser;
+import com.sun.enterprise.security.ssl.SSLUtils;
+import com.sun.enterprise.security.store.DomainScopedPasswordAliasStore;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import org.glassfish.api.admin.ServerEnvironment;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+
+/**
+ * Various utility methods which support secure admin operations.
+ * 
+ * @author Tim Quinn
+ */
+@Service
+@PerLookup
+public class SecureAdminHelperImpl implements SecureAdminHelper {
+
+    private static final char[] emptyPassword = new char[0];
+    private final static String DOMAIN_ADMIN_GROUP_NAME = "asadmin";
+    
+
+    @Inject
+    private SSLUtils sslUtils;
+    
+    @Inject
+    private DomainScopedPasswordAliasStore domainPasswordAliasStore;
+    
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private volatile AdminService as;
+
+    /**
+     * Returns the correct DN to use for a given secure admin principal, mapping
+     * the alias (if it's an alias specified) to the DN for the corresponding 
+     * cert in the key store.
+     * 
+     * @param value user-provided value (alias name or the actual DN)
+     * @param isAlias whether the value is an alias
+     * @return DN to use 
+     * @throws IOException if there is an error accessing the key store
+     * @throws KeyStoreException if the keystore has not been initialized
+     * @throws IllegalArgumentException if the cert for the specified alias as fetched from the key store is not an X509 certificate
+     */
+    @Override
+    public String getDN(final String value, final boolean isAlias) throws IOException, KeyStoreException {
+        if (isAlias) {
+            final KeyStore keyStore = sslUtils.getKeyStore();
+            if (keyStore == null) {
+                throw new RuntimeException(Strings.get("noKeyStore"));
+            }
+            final Certificate cert = keyStore.getCertificate(value);
+            if (cert == null) {
+                throw new IllegalArgumentException(Strings.get("noAlias", value));
+            }
+            if ( ! (cert instanceof X509Certificate)) {
+                throw new IllegalArgumentException(Strings.get("certNotX509Certificate", value));
+            }
+            return (((X509Certificate) cert).getSubjectX500Principal().getName());
+        } else {
+            return value;
+        }
+    }
+
+    /**
+     * Makes sure the username is a valid admin username and that the password
+     * alias is defined.  This method does NOT make sure that the password
+     * associated with the username and the password associated with the 
+     * password alias are the same.
+     * 
+     * @param username user-provided username
+     * @param passwordAlias name of the password alias 
+     */
+    @Override
+    public void validateInternalUsernameAndPasswordAlias(String username, String passwordAlias) {
+        try {
+            validateUser(username);
+            validatePasswordAlias(passwordAlias);
+        } catch (Exception ex) {
+            throw new RuntimeException(Strings.get("errVal"), ex);
+        }
+    }
+    
+    private void validateUser(final String username) throws BadRealmException, NoSuchRealmException {
+        final FileRealm fr = adminRealm();
+        try {
+            FileRealmUser fru = (FileRealmUser)fr.getUser(username);
+            if (isInAdminGroup(fru)) {
+                return;
+            }
+            /*
+             * The user is valid but is not in the admin group.
+             */
+            throw new RuntimeException(Strings.get("notAdminUser", username));
+        } catch (NoSuchUserException ex) {
+            /*
+             * The user is not valid, but use the same error as if the user
+             * IS present but is not an admin user.  This provides a would-be
+             * intruder a little less information by not distinguishing 
+             * between a valid user that's not an admin user and an
+             * invalid user.
+             */
+            throw new RuntimeException(Strings.get("notAdminUser", username));
+        }
+    }
+    
+    private boolean isInAdminGroup(final FileRealmUser user) {
+        for (String group : user.getGroups()) {
+            if (group.equals(DOMAIN_ADMIN_GROUP_NAME)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    private void validatePasswordAlias(final String passwordAlias) 
+            throws CertificateException, NoSuchAlgorithmException, 
+            KeyStoreException, NoSuchAlgorithmException, IOException {
+            
+        if ( ! domainPasswordAliasStore.containsKey(passwordAlias)) {
+            throw new RuntimeException(Strings.get("noAlias", passwordAlias));
+        }
+    }
+    private FileRealm adminRealm() throws BadRealmException, NoSuchRealmException {
+        final AuthRealm ar = as.getAssociatedAuthRealm();
+        if (FileRealm.class.getName().equals(ar.getClassname())) {
+            String adminKeyFilePath = ar.getPropertyValue("file");
+            FileRealm fr = new FileRealm(adminKeyFilePath);
+            return fr;
+        }
+        return null;
+    }
+    
+    /**
+     * Returns whether at least one admin user has an empty password.
+     * 
+     * @return true if at least one admin user has an empty password; false otherwise 
+     * @throws BadRealmException
+     * @throws NoSuchRealmException
+     * @throws NoSuchUserException 
+     */
+    @Override
+    public boolean isAnyAdminUserWithoutPassword() throws Exception {
+        final FileRealm adminRealm = adminRealm();
+        /*
+         * If the user has configured the admin realm to use a realm other than 
+         * the default file realm bypass the check that makes sure no admin users have
+         * an empty password.
+         */
+        if (adminRealm == null) {
+            return false;
+        }
+        for (final Enumeration<String> e = adminRealm.getUserNames(); e.hasMoreElements(); ) {
+            final String username = e.nextElement();
+            /*
+                * Try to authenticate this user with an empty password.  If it 
+                * works we can stop.
+                */
+            final String[] groupNames = adminRealm.authenticate(username, emptyPassword);
+            if (groupNames != null) {
+                for (String groupName : groupNames) {
+                    if (DOMAIN_ADMIN_GROUP_NAME.equals(groupName)) {
+                        return true;
+                    }
+                }
+            }
+                    
+        }
+        return false;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminStartupCheck.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminStartupCheck.java
new file mode 100644
index 0000000..f733f2c
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminStartupCheck.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.admin.cli;
+
+import org.glassfish.api.StartupRunLevel;
+import org.glassfish.hk2.api.PostConstruct;
+import org.glassfish.hk2.runlevel.RunLevel;
+import org.jvnet.hk2.annotations.Service;
+/**
+ *
+ * Starting in GlassFish 3.1.2, the DAS uses SSL to send admin requests to
+ * instances regardless of whether the user has enabled secure admin.  For this to
+ * work correctly when upgrading from earlier 3.x releases, there are some changes 
+ * to the configuration that must be in place.  This start-up service makes
+ * sure that the config is correct as quickly as possible to avoid degrading
+ * start-up performance. (Upgrades from 2.x are handled by the SecureAdminConfigUpgrade
+ * upgrade service.)
+ * <p>
+ * For 3.1.2 and later the configuration needs to include:
+ * <pre>
+ * {@code
+ * <secure-admin special-admin-indicator="xxx">
+ *   at least one <secure-admin-principal> element; if none, supply these defaults:
+ * 
+ *   <secure-admin-principal dn="dn-for-DAS"/>
+ *   <secure-admin-principal dn="dn-for-instances"/>
+ * }
+ * </pre>
+ * 
+ * Further, the sec-admin-listener set-up needs to be added (if not already there)
+ * for the non-DAS configurations.  Note that the work to configure the
+ * listeners and related protocols are already implemented by SecureAdminCommand,
+ * so this class delegates much of its work to that logic.
+ * 
+ * @author Tim Quinn
+ */
+@Service
+@RunLevel(StartupRunLevel.VAL)
+public class SecureAdminStartupCheck extends SecureAdminUpgradeHelper implements PostConstruct {
+
+    @Override
+    public void postConstruct() {
+        try {
+            /*
+             * If a formal upgrade is in progress then this Startup service
+             * will be invoked first.  The upgrade should take care of things,
+             * so this becomes a no-op.
+             */
+            if (isFormalUpgrade()) {
+                return;
+            }
+            ensureSecureAdminReady();
+            ensureNonDASConfigsReady();
+            commit();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        
+    }
+    
+    private boolean isFormalUpgrade() {
+        return Boolean.valueOf(startupArg("-upgrade"));
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminUpgradeHelper.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminUpgradeHelper.java
new file mode 100644
index 0000000..cddd9b5
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/SecureAdminUpgradeHelper.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.admin.cli;
+
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.SecureAdmin;
+import com.sun.enterprise.config.serverbeans.SecureAdminHelper;
+import com.sun.enterprise.config.serverbeans.SecureAdminPrincipal;
+import com.sun.enterprise.module.bootstrap.StartupContext;
+import com.sun.enterprise.security.admin.cli.SecureAdminCommand.ConfigLevelContext;
+import com.sun.enterprise.security.admin.cli.SecureAdminCommand.TopLevelContext;
+import com.sun.enterprise.security.admin.cli.SecureAdminCommand.Work;
+import com.sun.enterprise.security.ssl.SSLUtils;
+import java.io.IOException;
+import java.security.KeyStoreException;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.UUID;
+import org.glassfish.grizzly.config.dom.NetworkConfig;
+import org.glassfish.grizzly.config.dom.Protocol;
+import javax.inject.Inject;
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.jvnet.hk2.config.RetryableException;
+import org.jvnet.hk2.config.Transaction;
+import org.jvnet.hk2.config.TransactionFailure;
+
+/**
+ * Common logic for formal upgrade (i.e., start-domain --upgrade) and
+ * silent upgrade (starting a newer version of GlassFish using an older version's
+ * domain.xml).
+ * 
+ * @author Tim Quinn
+ */
+@Service
+@PerLookup
+public class SecureAdminUpgradeHelper {
+    
+    protected final static String DAS_CONFIG_NAME = "server-config";
+    
+    @Inject
+    protected Domain domain;
+    
+    @Inject
+    protected ServiceLocator habitat;
+    
+    @Inject
+    protected StartupContext startupContext;
+    
+    private Transaction t = null;
+    
+    private SecureAdmin secureAdmin = null;
+    
+    private TopLevelContext topLevelContext = null;
+    private SecureAdminHelper secureAdminHelper = null;
+    private SSLUtils sslUtils = null;
+    
+    private Properties startupArgs = null;
+    
+    
+    final protected Transaction transaction() {
+        if (t == null) {
+            t = new Transaction();
+        }
+        return t;
+    }
+    
+    private TopLevelContext topLevelContext() {
+        if (topLevelContext == null) {
+            topLevelContext = new TopLevelContext(transaction(), domain);
+        }
+        return topLevelContext;
+    }
+    
+    final protected void commit() throws RetryableException, TransactionFailure {
+        if (t != null) { 
+            t.commit();
+        }
+    }
+    
+    final protected void rollback() {
+        if (t != null) {
+            t.rollback();
+        }
+    }
+    
+    final protected String specialAdminIndicator() {
+        final UUID uuid = UUID.randomUUID();
+        return uuid.toString();
+    }
+    
+    final protected SecureAdmin secureAdmin() throws TransactionFailure {
+        if (secureAdmin == null) {
+            secureAdmin = domain.getSecureAdmin();
+            if (secureAdmin == null) {
+                secureAdmin = /* topLevelContext(). */writableSecureAdmin(); 
+                secureAdmin.setSpecialAdminIndicator(specialAdminIndicator());
+            }
+        }
+        return secureAdmin;
+    }
+    
+    final protected Domain writableDomain() throws TransactionFailure {
+        return topLevelContext().writableDomain();
+    }
+    
+    final protected SecureAdmin writableSecureAdmin() throws TransactionFailure {
+        return topLevelContext().writableSecureAdmin();
+    }
+    
+    final protected SecureAdminHelper secureAdminHelper() {
+        if (secureAdminHelper == null) {
+            secureAdminHelper = habitat.getService(SecureAdminHelper.class);
+        }
+        return secureAdminHelper;
+    }
+    
+    final protected SSLUtils sslUtils() {
+        if (sslUtils == null) {
+            sslUtils = habitat.getService(SSLUtils.class);
+        }
+        return sslUtils;
+    }
+    
+    final protected void ensureSecureAdminReady() throws TransactionFailure, IOException, KeyStoreException {
+        if (secureAdmin().getSpecialAdminIndicator().isEmpty()) {
+            /*
+             * Set the indicator to a unique value so we can distinguish
+             * one domain from another.
+             */
+            writableSecureAdmin().setSpecialAdminIndicator(specialAdminIndicator());
+        }
+        if (secureAdmin().getSecureAdminPrincipal().isEmpty() &&
+            secureAdmin().getSecureAdminInternalUser().isEmpty()) {
+            /*
+             * Add principal(s) for the aliases.
+             */
+            addPrincipalForAlias(secureAdmin().dasAlias());
+            addPrincipalForAlias(secureAdmin().instanceAlias());
+        }
+    }
+
+    final protected String startupArg(final String argName) {
+        if (startupArgs == null) {
+            if (startupContext != null) {
+                startupArgs = startupContext.getArguments();
+            } else {
+                startupArgs = new Properties(); // shouldn't happen
+            }
+        }
+        return startupArgs.getProperty(argName);
+    }
+    
+    private void addPrincipalForAlias(final String alias) throws IOException, KeyStoreException, TransactionFailure {
+        final SecureAdminPrincipal p = writableSecureAdmin().createChild(SecureAdminPrincipal.class);
+        p.setDn(secureAdminHelper().getDN(alias, true));
+        writableSecureAdmin().getSecureAdminPrincipal().add(p);
+    }
+    
+    final protected void ensureNonDASConfigsReady() throws TransactionFailure {
+        for (Config c : domain.getConfigs().getConfig()) {
+            if ( ! c.getName().equals(SecureAdminCommand.DAS_CONFIG_NAME)) {
+                if (!ensureConfigReady(c)) {
+                    break;
+                }
+            }
+        }
+    }
+    
+    final protected void ensureDASConfigReady() {
+        
+    }
+    
+    private boolean ensureConfigReady(final Config c) throws TransactionFailure {
+        /*
+         * See if this config is already set up for secure admin.
+         */
+        final NetworkConfig nc = c.getNetworkConfig();
+        if (nc == null) {
+            /*
+             * If there is no network config for this configuration then it is
+             * probably a test configuration of some sort.  In any case, there
+             * is no lower-level network protocols to verify so declare this
+             * config to be OK.
+             */
+            return true;
+        }
+        Protocol secAdminProtocol = nc.getProtocols().findProtocol(SecureAdminCommand.SEC_ADMIN_LISTENER_PROTOCOL_NAME);
+        if (secAdminProtocol != null) {
+            return true;
+        }
+        final EnableSecureAdminCommand enableCmd = new EnableSecureAdminCommand();
+        final Config c_w = transaction().enroll(c);
+        ConfigLevelContext configLevelContext = 
+                new ConfigLevelContext(topLevelContext(), c_w);
+        for (Iterator<Work<ConfigLevelContext>> it = enableCmd.perConfigSteps(); it.hasNext();) {
+            final Work<ConfigLevelContext> step = it.next();
+            if ( ! step.run(configLevelContext)) {
+                rollback();
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/Strings.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/Strings.java
new file mode 100644
index 0000000..9e5ef63
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/admin/cli/Strings.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.admin.cli;
+
+import com.sun.enterprise.universal.i18n.LocalStringsImpl;
+
+/**
+ * Strings -- Get your Strings here.
+ * One file with Strings
+ * So one class for messing with them!
+ * Nothing in here is public protected.  Only for use by this one java package.
+ * @author Byron Nevins
+ */
+
+final class Strings {
+    private Strings() {
+        // no instances allowed!
+    }
+
+    final static String get(String indexString) {
+        return strings.get(indexString);
+    }
+
+    final static String get(String indexString, Object... objects) {
+        return strings.get(indexString, objects);
+    }
+
+    final private static LocalStringsImpl strings = new LocalStringsImpl(Strings.class);
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/audit/AuditManager.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/audit/AuditManager.java
new file mode 100644
index 0000000..fd42100
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/audit/AuditManager.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.audit;
+
+import org.jvnet.hk2.annotations.Contract;
+
+
+/**
+ * Defines the behavior for audit manager implementations.
+ * 
+ * @author tjquinn
+ */
+@Contract
+public interface AuditManager {
+    /**
+     * Loads all audit modules.
+     */
+    public void loadAuditModules();
+    
+    /**
+     * Reports authentication events to registered audit modules.
+     * 
+     * @param user
+     * @param realm
+     * @param success 
+     */
+    public void authentication(String user, String realm, boolean success);
+    
+    /**
+     * Reports server start-up event to registered audit modules.
+     */
+    public void serverStarted();
+    
+    /**
+     * Reports server shutdown event to registered audit modules.
+     */
+    public void serverShutdown();
+    
+    /**
+     * Returns whether auditing is turned on.
+     * 
+     * @return 
+     */
+    public boolean isAuditOn();
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/audit/BaseAuditManager.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/audit/BaseAuditManager.java
new file mode 100644
index 0000000..4beac3d
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/audit/BaseAuditManager.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * BaseAuditManager.java
+ *
+ * Created on July 28, 2003, 1:56 PM
+ */
+
+package com.sun.enterprise.security.audit;
+
+import com.sun.enterprise.security.BaseAuditModule;
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.config.serverbeans.AuditModule;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+import org.jvnet.hk2.config.types.Property;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+/*V3:Commented
+import com.sun.enterprise.config.serverbeans.ServerBeansFactory;
+import com.sun.enterprise.config.serverbeans.ElementProperty;
+import com.sun.enterprise.config.ConfigContext;
+import com.sun.enterprise.server.ApplicationServer;
+ */
+import org.glassfish.internal.api.ServerContext;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import java.util.List;
+import org.glassfish.api.admin.ServerEnvironment;
+import javax.inject.Inject;
+
+import org.jvnet.hk2.annotations.Service;
+import javax.inject.Singleton;
+
+/**
+ * Basic implementation of audit manager.
+ * <p>
+ * Projects layered on top of nucleus should extend this class, adding platform-specific
+ * methods for auditing platform-specific events.  See AppServerAuditManagerImpl
+ * for an example.  Such implementations should be sure to invoke this class's
+ * setTypeClass method.  Then this class will keep a list of AuditModules of
+ * that specific type in the typedModules field which subclasses can refer
+ * to directly.
+ * <p>
+ * (This implementation was largely refactored from the original 
+ * BaseAuditManager implementation that combined nucleus and app server features.)
+ * 
+ * @author  Harpreet Singh
+ * @author  Shing Wai Chan
+ * @author tjquinn
+ */
+@Service
+@Singleton
+public class BaseAuditManager<T extends BaseAuditModule> implements AuditManager {
+    static final String NAME = "name";
+    static final String CLASSNAME = "classname";
+    
+    // For speed, maintain a separate list of audit modules of the specified
+    // module subtype (if any).  This allows subclasses to have very efficient
+    // access to the specified audit modules which the subclass audit manager
+    // deals with.
+    protected List<T> typedModules = Collections.synchronizedList(new ArrayList<T>());
+    private Class<T> typedModuleClass = null; // typically set by postConstruct of a subclass invoking setTypeClass
+    
+    private static final Logger _logger = 
+             SecurityLoggerInfo.getLogger();
+
+    private static final LocalStringManagerImpl _localStrings =
+	new LocalStringManagerImpl(BaseAuditManager.class);
+
+    private List<BaseAuditModule> instances = Collections.synchronizedList(new ArrayList<BaseAuditModule>());
+    // just a copy of names of the audit classes - helpful for log messages
+    // since we will not have a lot of audit classes, keeping a duplicate copy
+    // seems reasonable.
+    private Map<BaseAuditModule,String> moduleToNameMap = new HashMap<BaseAuditModule,String>();
+    private Map<String,BaseAuditModule> nameToModuleMap = new HashMap<String,BaseAuditModule>();
+    // make this accessible to the containers so that the cost of non-audit case, 
+    // is just a comparision.
+    protected boolean auditOn = false;
+   
+    @Inject
+    private ServerContext serverContext;
+    
+    private static final String AUDIT_MGR_SERVER_STARTUP_KEY = 
+        "auditmgr.serverStartup";
+    private static final String AUDIT_MGR_SERVER_SHUTDOWN_KEY = 
+        "auditmgr.serverShutdown";
+
+    /**
+     * This method initializes BaseAuditManager which load audit modules and
+     * audit enabled flag
+     */
+    @Override
+    public void loadAuditModules() {
+        try {
+            SecurityService securityBean = serverContext.getDefaultServices().getService(SecurityService.class,
+                    ServerEnvironment.DEFAULT_INSTANCE_NAME);
+            
+            assert(securityBean != null);
+            // @todo will be removed to incorporate the new structure.
+            //v3:Commented boolean auditFlag = securityBean.isAuditEnabled();
+            boolean auditFlag = Boolean.parseBoolean(securityBean.getAuditEnabled());
+
+            setAuditOn(auditFlag);
+            /*V3:Commented
+            com.sun.enterprise.config.serverbeans.AuditModule[] am =
+                    securityBean.getAuditModule();*/
+            List<com.sun.enterprise.config.serverbeans.AuditModule> am = securityBean.getAuditModule();
+            for (com.sun.enterprise.config.serverbeans.AuditModule it: am) {
+            //V3:Commented for (int i = 0; i < am.length; i++){
+                try {
+                    //V3:Commented String name = am[i].getName();
+                    //V3:Commented String classname = am[i].getClassname();
+                    String name = it.getName();
+                    String classname = it.getClassname();
+                    Properties p = new Properties();
+                    //XXX should we remove this two extra properties
+                    p.setProperty(NAME, name);
+                    p.setProperty(CLASSNAME, classname);
+                    List<Property> ep = it.getProperty();
+                    /*V3:Commented
+                    ElementProperty[] ep = am[i].getElementProperty();
+                    int epsize = am[i].sizeElementProperty();
+                    for (int j = 0; j < epsize; j++){
+                        String nme = ep[j].getName();
+                        String val = ep[j].getValue();
+                        p.setProperty(nme, val);
+                    }*/
+                    for (Property prop: ep) {
+                        p.setProperty(prop.getName(), prop.getValue());
+                    }
+                    BaseAuditModule auditModule = loadAuditModule(classname, p);
+                    instances.add(auditModule);
+                    moduleToNameMap.put(auditModule, name);
+                    nameToModuleMap.put(name, auditModule);
+                    if (isAuditModuleOfParameterizedType(auditModule)) {
+                        typedModules.add((T)auditModule);
+                    }
+                } catch(Exception ex){
+                     String msg = _localStrings.getLocalString(
+                         "auditmgr.loaderror", 
+                         "Audit: Cannot load AuditModule = {0}",
+                         //V3:Commented new Object[]{ am[i].getName() });
+                         new Object[]{ it.getName() });
+                     _logger.log(Level.WARNING, msg, ex);                    
+                }
+            }
+        } catch (Exception e) {
+            String msg = _localStrings.getLocalString("auditmgr.badinit", 
+                   "Audit: Cannot load Audit Module Initialization information. AuditModules will not be loaded.");
+            _logger.log(Level.WARNING, msg, e);
+        }
+    }
+
+    /**
+     * Add the given audit module to the list of loaded audit module.
+     * Adding the same name twice will override previous one.
+     * @param name of auditModule
+     * @param am an instance of a class extending BaseAuditModule that has been 
+     * successfully loaded into the system.
+     * @exception 
+     */
+    public BaseAuditModule addAuditModule(String name, String classname, Properties props)
+            throws Exception {
+        // make sure only a name corresponding to only one auditModule
+        removeAuditModule(name);
+        BaseAuditModule am = loadAuditModule(classname, props);
+
+        moduleToNameMap.put(am, name);
+        nameToModuleMap.put(name, am);
+        // clone list to resolve multi-thread issues in looping instances
+        instances = copyAndAdd(instances, am);
+        if (isAuditModuleOfParameterizedType(am)) {
+            typedModules = copyAndAdd(typedModules, (T)am);
+        }
+        return am;
+    }
+    
+    private boolean isAuditModuleOfParameterizedType(final BaseAuditModule am) {
+        return (typedModuleClass != null && typedModuleClass.isAssignableFrom(am.getClass()));
+    }
+    
+    private <U extends BaseAuditModule> List<U> copyAndAdd(final List<U> orig, final U am) {
+        final List<U> list = new ArrayList<U>();
+        Collections.copy(orig, list);
+        list.add(am);
+        return list;
+    }
+    
+    private <U extends BaseAuditModule> List<U> copyAndRemove(final List<U> orig, final U am) {
+        final List<U> list = new ArrayList<U>();
+        Collections.copy(orig, list);
+        list.remove(am);
+        return list;
+    }
+    
+    /**
+     * Remove the audit module of given name from the loaded list.
+     * @param name of auditModule
+     */
+    public BaseAuditModule removeAuditModule(String name) {
+        final BaseAuditModule am = nameToModuleMap.get(name);
+        if (am != null) {
+            nameToModuleMap.remove(name);
+            moduleToNameMap.remove(am);
+            // clone list to resolve multi-thread issues in looping instances
+            instances = copyAndRemove(instances, am);
+            if (isAuditModuleOfParameterizedType(am)) {
+                typedModules = copyAndRemove(typedModules, (T)am);
+            }
+        }
+        return am;
+    }
+
+    /**
+     * Get the audit module of given name from the loaded list.
+     * @param name of auditModule
+     */
+    BaseAuditModule getAuditModule(String name) {
+        return nameToModuleMap.get(name);
+    }
+
+    /**
+     * This method return auditModule with given classname and properties.
+     * @param classname
+     * @param props
+     * @exception
+     */
+    private BaseAuditModule loadAuditModule(String classname,
+            Properties props) throws Exception {
+        BaseAuditModule auditModule;
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        Class am = Class.forName(classname, true, loader);
+        Object obj =  am.newInstance();
+        auditModule = (BaseAuditModule) obj;
+        auditModule.init(props);
+        return auditModule;
+    }
+    
+    public LocalStringManagerImpl getLocalStrings() {
+        return _localStrings;
+    }
+    
+    public Logger getLogger() {
+        return _logger;
+    }
+    
+    /**
+     * logs the authentication call for all the loaded modules.
+     * @see com.sun.appserv.security.BaseAuditModule.authentication
+     */
+    public void authentication(final String user, final String realm, final boolean success){
+        if (auditOn) {
+            for (BaseAuditModule am : instances) {
+                try {
+                    am.authentication(user, realm, success);
+                } catch (Exception ex) {
+                    final String name = moduleName(am);
+                    final String msg = 
+                        _localStrings.getLocalString(
+                            "auditmgr.authentication",
+                            " Audit Module {0} threw the following exception during authentication:",
+                            name);
+                    _logger.log(Level.INFO, msg, ex);
+                }
+            }
+        }
+    }
+    
+    public void serverStarted(){
+        if (auditOn) {
+            for (BaseAuditModule am : instances) {
+                try {
+                    am.serverStarted();
+                } catch (Exception ex) {
+                    final String name = moduleName(am);
+                    final String msg = 
+                        _localStrings.getLocalString(
+                            AUDIT_MGR_SERVER_STARTUP_KEY,
+                            " Audit Module {0} threw the following exception during server startup :",
+                            name);
+                    _logger.log(Level.INFO, msg, ex);
+                }
+            }
+        }
+    }
+
+    public void serverShutdown(){
+        if (auditOn) {
+            for (BaseAuditModule am : instances) {
+                try {
+                    am.serverShutdown();
+                } catch (Exception ex) {
+                    final String name = moduleName(am);
+                    final String msg = 
+                        _localStrings.getLocalString(
+                            AUDIT_MGR_SERVER_SHUTDOWN_KEY,
+                            " Audit Module {0} threw the following exception during server shutdown :",
+                            name);
+                    _logger.log(Level.INFO, msg, ex);
+                }
+            }
+        }
+    }
+
+    public void setAuditOn(boolean auditOn) {
+        this.auditOn = auditOn;
+    }
+    
+    public boolean isAuditOn() {
+        return auditOn;
+    }
+    
+    protected String moduleName(final BaseAuditModule am) {
+        return moduleToNameMap.get(am);
+    }
+    
+    protected List<T> instances(final Class<T> c) {
+        final List<T> result = new ArrayList<T>();
+        for (BaseAuditModule am : instances) {
+            if (c.isAssignableFrom(c)) {
+                result.add((T) am);
+            }
+        }
+        return result;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/audit/LocalStrings.properties b/nucleus/security/core/src/main/java/com/sun/enterprise/security/audit/LocalStrings.properties
new file mode 100644
index 0000000..2fc941b
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/audit/LocalStrings.properties
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+auditmgr.admininvocation=Audit: Audit Module {0} threw the following exception during admin invocation :
+auditmgr.authentication=Audit: Audit Module {0} threw the following exception during authentication:
+auditmgr.logout=Audit: Audit Module {0} threw the following exception during logout:
+auditmgr.loaderror=Audit: Cannot load AuditModule = {0}
+auditmgr.badinit=Audit: Cannot load Audit Module Initialization information. AuditModules will not be loaded.
+auditmgr.serverStartup=Audit: Audit Module {0} threw the following exception during server startup :
+auditmgr.serverShutdown=Audit: Audit Module {0} threw the following exception during server shutdown :
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/AuthenticationStatus.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/AuthenticationStatus.java
new file mode 100644
index 0000000..4e7c22c
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/AuthenticationStatus.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth;
+
+/**
+ * This interface stores the status of the authentication.
+ * @author Harish Prabandham
+ */
+
+public interface AuthenticationStatus extends java.io.Serializable {
+    public static final int AUTH_SUCCESS = 0; // Authentication Successful
+    public static final int AUTH_FAILURE = 1; // Authentication Failed
+    public static final int AUTH_CONTINUE = 2; // Continue the Authentication
+    public static final int AUTH_EXPIRED = 3; // Credentials have expired.
+
+    /**
+     * This method returns the status of the authentication
+     * @return An integer value indicating the status of the authentication
+     */
+    public int  getStatus();
+    
+    /**
+     * This is the value returned by the Authenticator when the status
+     * is AUTH_CONTINUE. This data should give an indication to the 
+     * client on what else it should send to the server to complete the
+     * authentication.
+     * 
+     * @return An array of bytes indicating the additional information
+     * needed to complete the authentication.
+     */
+    public byte[] getContinuationData();
+    
+    /**
+     * This is the value returned by the Authenticator when the status
+     * is AUTH_CONTINUE. This data should give an indication to the 
+     * client on specific authentication it needs to adopt to continue
+     * on with the authentication.
+     * 
+     * @return An array of bytes indicating the authentication specific
+     * information needed to complete the authentication.
+     */
+    public byte[] getAuthSpecificData();
+}
+
+
+
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/AuthenticationStatusImpl.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/AuthenticationStatusImpl.java
new file mode 100644
index 0000000..cc3b893
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/AuthenticationStatusImpl.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth;
+
+/**
+ * This class implements an AuthenticationStatus object.
+ * @author Harish Prabandham
+ */
+
+public class AuthenticationStatusImpl implements AuthenticationStatus {
+    private String realmName; // Name of the Realm
+    private String authMethod; // Method used for Authentication.
+    private String principalName; // String form of the Principal.
+    private int status; // Status
+    
+    /**
+     * This constructs a new AuthenticationStatus object.
+     * @param The name of the principal
+     * @param The name of the realm that authenticated the principal
+     * @param The method used for authenticating the principal
+     * @param The status of the authentication
+     */
+    public AuthenticationStatusImpl(String principalName, String authMethod,
+				    String realm,
+				    int status) {
+	this.principalName = principalName;
+	this.authMethod = authMethod;
+	this.status = status;
+	this.realmName = realm;
+    }
+
+    /**
+     * This method returns the status of the authentication
+     * @return An integer value indicating the status of the authentication
+     */
+    public int getStatus() {
+	return status;
+    }
+
+    /** 
+     * This method returns a byte array of zero length, since there's
+     * no continuation data needed for passphrase based authentication.
+     * @return A byte array of zero length.
+     */
+    public byte[] getContinuationData() {
+	return new byte[0];
+    }
+
+    /** 
+     * This method returns a byte array of zero length, since there's
+     * no auth specific data needed for passphrase based authentication.
+     * @return A byte array of zero length.
+     */
+    public byte[] getAuthSpecificData() {
+	return new byte[0];
+    }
+
+    /** 
+     * This method returns the name of realm where the authentication was
+     * performed.
+     * @return A java.lang.String representation of the realm.
+     */
+    public String getRealmName() {
+	return realmName;
+    }
+    
+    /** 
+     * This method returns the "method" used to perform authentication 
+     * @return A java.lang.String representation of the method used. In 
+     * passphrase based authentication it returns the string "password".
+     */
+    public String getAuthMethod() {
+	return authMethod;
+    }
+
+    /** 
+     * This method returns the string representation of the principal
+     * that was authenticated.
+     * @return A java.lang.String representation of the Principal. 
+     */
+    public String getPrincipalName() {
+	return principalName;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/LocalStrings.properties b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/LocalStrings.properties
new file mode 100644
index 0000000..645fe87
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/LocalStrings.properties
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+
+#Sounds like unused file
+realmtool.username=Enter Username:
+realmtool.options= Options:
+realmtool.name=realm-name
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/PrincipalMapper.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/PrincipalMapper.java
new file mode 100644
index 0000000..1b3b705
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/PrincipalMapper.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth;
+
+import java.security.Principal;
+import java.util.Properties;
+
+/**
+ *
+ *  Enables formatting of principal retrieved from message eg: P-Asserted-Identity  values.
+ * eg: "Cullen Jennings" <sip:fluffy@cisco.com> value can be mapped/formatted to
+ *      "CullenJ".
+ * @author k.venugopal@sun.com
+ */
+
+public interface PrincipalMapper {
+
+    public void initialize(Properties props);
+    /**
+     *
+     * converts values in to a format understood by the container/container backend eg: database, ldap etc.
+     *
+     * @param assrtId P-Asserted-Identity values.
+     * @return P-Asserted-Identity values in a format understood by the container.
+     */
+    public Principal[] mapIdentity(Principal[] assrtId);
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/Privilege.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/Privilege.java
new file mode 100644
index 0000000..e2b7295
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/Privilege.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth;
+
+import java.rmi.*;
+
+/**
+ * This remote interface enables the deployment tool to query the
+ * details of the Privilege.
+ * @author Harish Prabandham
+ */
+public interface Privilege extends java.io.Serializable {
+    /**
+     * Returns the name of the name of the Privilege.
+     * @return The name of the name of the Privilege.
+     */
+    public String getName();
+}
+
+
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/PrivilegeImpl.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/PrivilegeImpl.java
new file mode 100644
index 0000000..92ce3b0
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/PrivilegeImpl.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth;
+
+import java.rmi.*;
+
+
+/**
+ * This method provides an implementation a Privilege
+ * @author Harish Prabandham
+ */
+
+public class PrivilegeImpl implements Privilege {
+    private String name;
+    
+    /**
+     * Creates a new Privilege object..
+     *
+     */
+    public PrivilegeImpl(String name) {
+	this.name = name;
+    }
+
+    /**
+     * Returns the hashCode ..
+     */
+    public int hashCode() {
+	return name.hashCode();
+    }
+
+    /**
+     * Returns the name of the name of the Privilege.
+     * @return The name of the name of the Privilege.
+     */
+    public String getName() {
+	return name;
+    }
+
+    /**
+     * Compares equality...
+     */
+    public boolean equals(Object obj) {
+	if(obj instanceof Privilege) {
+	    Privilege priv = (Privilege) obj;
+	    return getName().equals(priv.getName());
+	} else {
+	    return false;
+	}
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/RemoteObject.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/RemoteObject.java
new file mode 100644
index 0000000..f807d83
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/RemoteObject.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth;
+
+import com.sun.enterprise.util.*;
+import javax.rmi.PortableRemoteObject;
+import javax.rmi.CORBA.Tie;
+import org.omg.CORBA.ORB;
+
+/**
+ * Just a Base class to make exporting remote objects a bit easier...
+ * @author Harish Prabandham
+ */
+
+public class RemoteObject {
+    private ORB orb;
+
+    protected RemoteObject() {
+	//TODO:V3 commented, uncomment later orb = ORBManager.getORB();
+    }
+
+    protected void exportObject(java.rmi.Remote remote)
+    throws java.rmi.RemoteException {
+        // create servant and tie
+        PortableRemoteObject.exportObject(remote);
+        Tie servantsTie = javax.rmi.CORBA.Util.getTie(remote);
+
+        // Note: at this point the Tie doesnt have a delegate inside it,
+        // so it is not really "exported".
+        // The following call does orb.connect() which is the real exporting
+        servantsTie.orb(orb);
+    }
+
+    java.rmi.Remote getStub(java.rmi.Remote remote)
+    throws java.rmi.RemoteException {
+	return PortableRemoteObject.toStub(remote);
+    }
+}
+
+
+
+
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/TimestampValidator.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/TimestampValidator.java
new file mode 100644
index 0000000..ff862bc
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/TimestampValidator.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth;
+
+import java.util.Date;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * validate Timestamp received in messages.
+ * @author k.venugopal@sun.com
+ */
+public interface TimestampValidator {
+
+    /**
+     * validate given time against current time.
+     * @param created  created time
+     * @param maxClockSkew   maximum difference allowed between the system clocks of the sender and recipient.
+     * @param freshnessLimit maximum duration of time after which the Timestamp becomes stale
+     * @throws java.util.concurrent.TimeoutException
+     */
+    void validate(Date created,long maxClockSkew,long freshnessLimit)throws TimeoutException;
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/TrustHandler.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/TrustHandler.java
new file mode 100644
index 0000000..d3dbf13
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/TrustHandler.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth;
+
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.Properties;
+
+/**
+ *
+ * Enables developers to provide custom implementation to enable sip containers
+ * to determine if a network entity can be trusted.
+ */
+public interface TrustHandler {
+
+    
+    public void initialize(Properties props);
+    /**
+     * determines if the container can trust the network entity from which we received the message with P-Asserted-Identity
+     * header. This method also validates if the identity that was used to secure(eg: SSL) the message is trusted.
+     *
+     * @param pAssertedValues P-Asserted-Identity header values
+     * @param messageDirection "Incoming" if this method is invoked for a incoming request, "Outgoing" if the message is being sent out.
+     * @param asserterAddress ipaddress/hostname of the network entity from which we received the SIP message
+     * with P-Asserted-Identity header. Inorder to accept/use the values in P-Asserted-Identity
+     * header the network entity should be a trusted.
+     * @param securityid is the asserting security identity, if a secure connection is used then this
+     * would be the java.security.cert.X509Certificate, else null.
+     * @return true if we trust the networtid and the securityid.
+     */
+    public boolean isTrusted(String asserterAddress, String messageDirection,X509Certificate securityid, Principal[] pAssertedValues);
+
+   
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/Constants.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/Constants.java
new file mode 100644
index 0000000..b50da7d
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/Constants.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.digest.api;
+
+/**
+ * 
+ * @author K.Venugopal@sun.com
+ */
+public final class Constants {
+
+    public static final String NONCE = "nonce";
+    public static final String NONCE_COUNT = "nc";
+    public static final String CNONCE = "cnonce";
+    public static final String QOP = "qop";
+    public static final String METHOD = "method";
+    public static final String URI = "uri";
+    public static final String ALGORITHM = "algorithm";
+    public static final String ENTITY_BODY = "entityBody";
+    public static final String RESPONSE = "response";
+    public static final String DATA = "data";
+    public static final String A1 = "A1";
+    public static final String A2 = "A2";
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/DigestAlgorithmParameter.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/DigestAlgorithmParameter.java
new file mode 100644
index 0000000..b69737b
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/DigestAlgorithmParameter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.digest.api;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * Interface to Digest algorithm parameters 
+ * @author K.Venugopal@sun.com
+ */
+public interface DigestAlgorithmParameter extends AlgorithmParameterSpec {
+    /**
+     * @returns the delimiter to be used while performing digest calculation, null otherwise.
+     *
+     */
+     public byte[] getDelimiter(); 
+     /**
+      * 
+      * @returns the parameter value. 
+      */
+     public byte[] getValue() ;
+     /**
+      * @returns the digest algorithm to be used.eg: MD5,MD5-sess etc..
+      *  
+      */
+     public String getAlgorithm();    
+     /**
+      * @returns the name of the parameter, null if no name is present.
+      */
+     public String getName();
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/Key.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/Key.java
new file mode 100644
index 0000000..57c7895
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/Key.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.digest.api;
+
+/**
+ * Represents the Key(username+realmname+passwd) to be used in the Digest calculation.
+ * Password is to be obtained from the store using the Key to complete the digest
+ * calculation.
+ *
+ * @author K.Venugopal@sun.com
+ */
+public interface Key {
+
+    
+    public java.lang.String getRealmName();
+
+    public java.lang.String getUsername();
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/NestedDigestAlgoParam.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/NestedDigestAlgoParam.java
new file mode 100644
index 0000000..2ecc498
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/NestedDigestAlgoParam.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.digest.api;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * Interface representing  nested DigestAlgorithm parameter values
+ * @author K.Venugopal@sun.com
+ */
+public interface NestedDigestAlgoParam extends DigestAlgorithmParameter{
+    /**
+     * @returns array of parameter values. 
+     */
+    public AlgorithmParameterSpec[] getNestedParams();
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/Password.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/Password.java
new file mode 100644
index 0000000..6471014
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/api/Password.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.digest.api;
+
+/**
+ * represents plain text password and pre hashed(username+realmname+password) password.
+ * @author K.Venuopal@sun.com
+ */
+public interface Password {
+    public static final int PLAIN_TEXT= 0;
+    public static final int HASHED = 1;
+    /**
+     * returns PLAIN_TEXT or HASHED.
+     * @returns int
+     */
+    public int getType();
+    /**
+     * returns password.
+     * @returns byte[] 
+     */
+    public byte[] getValue();
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/impl/.gitkeep_empty_dir b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/impl/.gitkeep_empty_dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/digest/impl/.gitkeep_empty_dir
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/AssertedCredentials.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/AssertedCredentials.java
new file mode 100755
index 0000000..81683f2
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/AssertedCredentials.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login;
+
+/**
+ *
+ * @author K.Venugopal@sun.com
+ */
+
+public class AssertedCredentials {
+
+    private String realmName = "";
+    private String userName = "";
+    private Object info = null;
+    
+    public AssertedCredentials(String realmName,String userName) {
+        this.realmName = realmName;
+        this.userName = userName;
+    }
+    
+    public AssertedCredentials(String realmName,String userName,Object info) {
+        this.realmName = realmName;
+        this.userName = userName;
+        this.info = info;
+    }
+    
+    public String getRealmName(){
+        return realmName;
+    }
+    
+    public String getUserName(){
+        return userName;
+    }
+    
+    public Object getInfo(){
+        return info;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/ClientCertificateLoginModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/ClientCertificateLoginModule.java
new file mode 100644
index 0000000..9762ff5
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/ClientCertificateLoginModule.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login;
+
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.security.auth.login.common.X509CertificateCredential;
+import java.util.Map;
+import java.util.Enumeration;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+import javax.security.auth.*;
+import javax.security.auth.callback.*;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+//V3:Commented import com.sun.enterprise.config.clientbeans.Ssl;
+import com.sun.enterprise.security.ssl.SSLUtils;
+import com.sun.enterprise.security.integration.AppClientSSL;
+
+import org.glassfish.security.common.PrincipalImpl;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import java.util.logging.*;
+import com.sun.logging.*;
+import org.glassfish.internal.api.Globals;
+
+
+/**
+ * <p> This LoginModule authenticates users with X509 certificates.
+ * 
+ * <p> If testUser successfully authenticates itself,
+ * a <code>PrincipalImpl</code> with the testUser's username
+ * is added to the Subject.
+ *
+ * <p> This LoginModule recognizes the debug option.
+ * If set to true in the login Configuration,
+ * debug messages will be output to the output stream, System.out.
+ *
+ * @author Harpreet Singh (harpreet.singh@sun.com)
+ */
+
+public class ClientCertificateLoginModule implements LoginModule {
+
+    private static Logger _logger=null;
+    static {
+        _logger=SecurityLoggerInfo.getLogger();
+    }
+
+    private static LocalStringManagerImpl localStrings =
+	new LocalStringManagerImpl(ClientCertificateLoginModule.class);
+
+    private static KeyStore ks = null;
+
+    // initial state
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+    private Map sharedState;
+    private Map options;
+
+    // configurable option
+    private boolean debug = false; // default
+
+    // the authentication status
+    private boolean succeeded = false;
+    private boolean commitSucceeded = false;
+
+    private String alias;
+    private X509Certificate certificate;
+
+    // testUser's PrincipalImpl
+    private PrincipalImpl userPrincipal;
+
+    private AppClientSSL ssl;
+    private SSLUtils sslUtils;
+    
+    /**
+     * Initialize this <code>LoginModule</code>.
+     *
+     * <p>
+     *
+     * @param subject the <code>Subject</code> to be authenticated. <p>
+     *
+     * @param callbackHandler a <code>CallbackHandler</code> for communicating
+     *			with the end user (prompting for usernames and
+     *			passwords, for example). <p>
+     *
+     * @param sharedState shared <code>LoginModule</code> state. <p>
+     *
+     * @param options options specified in the login
+     *			<code>Configuration</code> for this particular
+     *			<code>LoginModule</code>.
+     */
+    public void initialize(Subject subject, CallbackHandler callbackHandler,
+			Map sharedState, Map options) {
+ 
+
+	this.subject = subject;
+	this.callbackHandler = callbackHandler;
+	this.sharedState = sharedState;
+	this.options = options;
+
+	// initialize any configured options
+	debug = "true".equalsIgnoreCase((String)options.get("debug"));
+        sslUtils = Globals.getDefaultHabitat().getService(SSLUtils.class);
+    }
+
+
+    /**
+     * Authenticate the user by prompting for a username and password.
+     *
+     * <p>
+     *
+     * @return true in all cases since this <code>LoginModule</code>
+     *		should not be ignored.
+     *
+     * @exception LoginException if this <code>LoginModule</code>
+     *		is unable to perform the authentication.
+     */
+    public boolean login() throws LoginException {
+
+	// prompt for a username and password
+	if (callbackHandler == null){
+	    throw new LoginException("Error: no CallbackHandler available " +
+			"to garner authentication information from the user");
+        }
+
+	try {
+	    String[] as = new String[ks.size()];
+	    String[] aliasString = new String[ks.size()];
+	    Enumeration aliases = ks.aliases();
+	    for(int i = 0; i < ks.size(); i++) {
+	        aliasString[i] = (String) aliases.nextElement();
+	        as[i] = ((X509Certificate)ks.getCertificate(aliasString[i])).getSubjectDN().getName();
+	    }
+
+	    Callback[] callbacks = new Callback[1];
+	    callbacks[0] = new ChoiceCallback(localStrings.getLocalString("login.certificate", "Choose from list of certificates: "),  as, 0, false);
+ 
+	    callbackHandler.handle(callbacks);
+
+	    int[] idx = ((ChoiceCallback)callbacks[0]).getSelectedIndexes();
+
+	    if (idx == null) {
+		throw new LoginException ("No certificate selected!");
+	    } else if (idx[0] == -1){
+		throw new LoginException ("Incorrect keystore password");
+	    }
+	    // print debugging information
+	    if (debug) {
+                if(_logger.isLoggable(Level.FINE)){
+                    _logger.log(Level.FINE,"\t\t[ClientCertificateLoginModule] " +
+                                "user entered certificate: ");
+                    for (int i = 0; i < idx.length; i++){
+                        _logger.log(Level.FINE,aliasString[idx[i]]);
+                    }
+                }
+	    }
+            
+	    // the authenticate method previously picked out the
+	    // wrong alias.
+	    // since we allow only 1 choice the first element in idx 
+	    // idx[0] should have the selected index.
+	    this.alias  = aliasString[idx[0]];
+	    certificate = (X509Certificate) ks.getCertificate(alias);
+	    // the authenticate should always return a true.
+	    if (debug){
+                if(_logger.isLoggable(Level.FINE)){
+                    _logger.log(Level.FINE,"\t\t[ClientCertificateLoginModule] " +
+                            "authentication succeeded");
+                }
+	    }
+	    succeeded = true;
+	    return true;
+	} catch (java.io.IOException ioe) {
+	    throw new LoginException(ioe.toString());
+	} catch (UnsupportedCallbackException uce) {
+	    throw new LoginException("Error: " + uce.getCallback().toString() +
+		" not available to garner authentication information " +
+		"from the user");
+	} catch (Exception e) {
+	    throw new LoginException(e.toString());
+	}
+    }
+    /**
+     * <p> This method is called if the LoginContext's
+     * overall authentication succeeded
+     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
+     * succeeded).
+     *
+     * <p> If this LoginModule's own authentication attempt
+     * succeeded (checked by retrieving the private state saved by the
+     * <code>login</code> method), then this method associates a
+     * <code>PrincipalImpl</code>
+     * with the <code>Subject</code> located in the
+     * <code>LoginModule</code>.  If this LoginModule's own
+     * authentication attempted failed, then this method removes
+     * any state that was originally saved.
+     *
+     * <p>
+     *
+     * @exception LoginException if the commit fails.
+     *
+     * @return true if this LoginModule's own login and commit
+     *		attempts succeeded, or false otherwise.
+     */
+    public boolean commit() throws LoginException {
+	if (succeeded == false) {
+	    return false;
+	} else {
+	    // add a Principal (authenticated identity)
+	    // to the Subject
+
+	    // assume the user we authenticated is the PrincipalImpl
+	    userPrincipal = new PrincipalImpl(alias);
+	    if (!subject.getPrincipals().contains(userPrincipal)){
+		subject.getPrincipals().add(userPrincipal);
+            }
+
+	    if (debug) {
+                if(_logger.isLoggable(Level.FINE)){
+                    _logger.log(Level.FINE,"\t\t[ClientCertificateLoginModule] " +
+                                "added PrincipalImpl to Subject");
+                }
+	    }
+            
+            ssl = new AppClientSSL();
+            ssl.setCertNickname(this.alias);
+            sslUtils.setAppclientSsl(ssl);
+            
+	    String realm = LoginContextDriver.CERT_REALMNAME;
+	    X509Certificate[] certChain = new X509Certificate[1];
+	    certChain[0] = certificate;
+	    X509CertificateCredential pc = 
+		new X509CertificateCredential(certChain, alias, realm);
+	    if(!subject.getPrivateCredentials().contains(pc)) {
+		subject.getPrivateCredentials().add(pc);
+            }
+
+	    commitSucceeded = true;
+	    return true;
+	}
+    }
+
+    /**
+     * <p> This method is called if the LoginContext's
+     * overall authentication failed.
+     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
+     * did not succeed).
+     *
+     * <p> If this LoginModule's own authentication attempt
+     * succeeded (checked by retrieving the private state saved by the
+     * <code>login</code> and <code>commit</code> methods),
+     * then this method cleans up any state that was originally saved.
+     *
+     * <p>
+     *
+     * @exception LoginException if the abort fails.
+     *
+     * @return false if this LoginModule's own login and/or commit attempts
+     *		failed, and true otherwise.
+     */
+    public boolean abort() throws LoginException {
+	if (succeeded == false) {
+	    return false;
+	} else if (succeeded == true && commitSucceeded == false) {
+	    // login succeeded but overall authentication failed
+	    succeeded = false;
+	    alias = null;
+	    userPrincipal = null;
+	} else {
+	    // overall authentication succeeded and commit succeeded,
+	    // but someone else's commit failed
+	    logout();
+	}
+	return true;
+    }
+
+    /**
+     * Logout the user.
+     *
+     * <p> This method removes the <code>PrincipalImpl</code>
+     * that was added by the <code>commit</code> method.
+     *
+     * <p>
+     *
+     * @exception LoginException if the logout fails.
+     *
+     * @return true in all cases since this <code>LoginModule</code>
+     *          should not be ignored.
+     */
+    public boolean logout() throws LoginException {
+	// unset the alias
+        ssl = null;
+        sslUtils.setAppclientSsl(ssl);
+	subject.getPrincipals().remove(userPrincipal);
+	succeeded = false;
+	commitSucceeded = false;
+	alias = null;
+	userPrincipal = null;
+	return true;
+    }
+
+    public static void setKeyStore(KeyStore keyStore) {
+	ks = keyStore;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/ClientPasswordLoginModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/ClientPasswordLoginModule.java
new file mode 100644
index 0000000..2dee6c8
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/ClientPasswordLoginModule.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login;
+
+import java.util.*;
+import javax.security.auth.*;
+import javax.security.auth.callback.*;
+import javax.security.auth.login.*;
+import javax.security.auth.spi.*;
+import com.sun.enterprise.security.auth.login.common.PasswordCredential;
+import org.glassfish.security.common.PrincipalImpl;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import java.util.logging.*;
+import com.sun.logging.*;
+
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.security.UsernamePasswordStore;
+
+/**
+ * <p> This sample LoginModule authenticates users with a password.
+ * 
+ * <p> If testUser successfully authenticates itself,
+ * a <code>PrincipalImpl</code> with the testUser's username
+ * is added to the Subject.
+ *
+ * @author Harpreet Singh (harpreet.singh@sun.com)
+ */
+
+public class ClientPasswordLoginModule implements LoginModule {
+
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+
+    private static final String DEFAULT_REALMNAME = "default";
+    private static final LocalStringManagerImpl localStrings =
+	new LocalStringManagerImpl(ClientPasswordLoginModule.class);
+    // initial state
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+    private Map sharedState;
+    private Map options;
+
+    // the authentication status
+    private boolean succeeded = false;
+    private boolean commitSucceeded = false;
+
+    // username and password
+    private String username;
+    private char[] password;
+    
+    // testUser's PrincipalImpl
+    private PrincipalImpl userPrincipal;
+    public static final String LOGIN_NAME = "j2eelogin.name";
+    public static final String LOGIN_PASSWORD = "j2eelogin.password";
+
+
+    /**
+     * Initialize this <code>LoginModule</code>.
+     *
+     * <p>
+     *
+     * @param subject the <code>Subject</code> to be authenticated. <p>
+     *
+     * @param callbackHandler a <code>CallbackHandler</code> for communicating
+     *			with the end user (prompting for usernames and
+     *			passwords, for example). <p>
+     *
+     * @param sharedState shared <code>LoginModule</code> state. <p>
+     *
+     * @param options options specified in the login
+     *			<code>Configuration</code> for this particular
+     *			<code>LoginModule</code>.
+     */
+    public void initialize(Subject subject, CallbackHandler callbackHandler,
+			Map sharedState, Map options) {
+ 
+	this.subject = subject;
+	this.callbackHandler = callbackHandler;
+	this.sharedState = sharedState;
+	this.options = options;
+
+    }
+
+    /**
+     * Authenticate the user by prompting for a username and password.
+     *
+     * <p>
+     *
+     * @return true in all cases since this <code>LoginModule</code>
+     *		should not be ignored.
+     *
+     * @exception FailedLoginException if the authentication fails. <p>
+     *
+     * @exception LoginException if this <code>LoginModule</code>
+     *		is unable to perform the authentication.
+     */
+    public boolean login() throws LoginException {
+
+	// prompt for a username and password
+	if (callbackHandler == null){
+	    String failure = localStrings.getLocalString("login.nocallback","Error: no CallbackHandler available to garner authentication information from the user");
+	    throw new LoginException(failure);
+	}
+
+        // Get the username from the exchange mechanism
+        String uname = UsernamePasswordStore.getUsername();
+        char[] pswd = UsernamePasswordStore.getPassword();
+        boolean doSet = false;
+        
+        // bugfix# 6412539
+        if (uname == null) {
+            uname = System.getProperty(LOGIN_NAME);
+            doSet = true;
+        }
+        if (pswd == null) {
+            if(System.getProperty(LOGIN_PASSWORD) != null) {
+                pswd = System.getProperty(LOGIN_PASSWORD).toCharArray();
+            }
+            doSet = true;
+        }
+
+        if (doSet) {
+            UsernamePasswordStore.set(uname, pswd);
+        }
+
+        if (uname != null && pswd != null) {
+            username = uname;
+
+            int length = pswd.length;
+            password = new char[length];
+            System.arraycopy (pswd, 0, password, 0,length);
+	} else{ 
+	    Callback[] callbacks = new Callback[2];
+            NameCallback nameCB = new NameCallback(localStrings.getLocalString("login.username", "ClientPasswordModule username"));
+            String defaultUname = System.getProperty("user.name");
+            if (defaultUname != null) {
+                nameCB = new NameCallback(localStrings.getLocalString("login.username", "ClientPasswordModule username"),defaultUname);
+            }
+            callbacks[0] = nameCB;
+            callbacks[1] = new PasswordCallback(localStrings.getLocalString("login.password", "ClientPasswordModule password: "), false);
+	    
+	    try {
+		callbackHandler.handle(callbacks);
+		username = ((NameCallback)callbacks[0]).getName();
+		if(username == null){
+		    String fail = localStrings.getLocalString("login.nousername", "No user specified");
+		    throw new LoginException(fail);
+		}
+		char[] tmpPassword = ((PasswordCallback)callbacks[1]).getPassword();
+		if (tmpPassword == null) {
+		    // treat a NULL password as an empty password
+		    tmpPassword = new char[0];
+		}
+		password = new char[tmpPassword.length];
+		System.arraycopy(tmpPassword, 0,
+				 password, 0, tmpPassword.length);
+		((PasswordCallback)callbacks[1]).clearPassword();
+		
+	    } catch (java.io.IOException ioe) {
+		throw new LoginException(ioe.toString());
+	    } catch (UnsupportedCallbackException uce) {
+		String nocallback = localStrings.getLocalString("login.callback","Error: Callback not available to garner authentication information from user(CallbackName):" );
+		throw new LoginException(nocallback +
+					 uce.getCallback().toString());
+	    } 
+	}
+
+	// by default -  the client side login module will always say
+	// that the login successful. The actual login will take place 
+	// on the server side.
+
+        _logger.log(Level.FINEST,"\t\t[ClientPasswordLoginModule] " +
+                    "authentication succeeded");
+	succeeded = true;
+	return true;
+    }
+
+    
+    /**
+     * <p> This method is called if the LoginContext's
+     * overall authentication succeeded
+     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
+     * succeeded).
+     *
+     * <p> If this LoginModule's own authentication attempt
+     * succeeded (checked by retrieving the private state saved by the
+     * <code>login</code> method), then this method associates a
+     * <code>PrincipalImpl</code>
+     * with the <code>Subject</code> located in the
+     * <code>LoginModule</code>.  If this LoginModule's own
+     * authentication attempted failed, then this method removes
+     * any state that was originally saved.
+     *
+     * <p>
+     *
+     * @exception LoginException if the commit fails.
+     *
+     * @return true if this LoginModule's own login and commit
+     *		attempts succeeded, or false otherwise.
+     */
+    public boolean commit() throws LoginException {
+	if (succeeded == false) {
+	    return false;
+	} else {
+	    // add a Principal (authenticated identity)
+	    // to the Subject
+
+	    // assume the user we authenticated is the PrincipalImpl
+	    userPrincipal = new PrincipalImpl(username);
+	    if (!subject.getPrincipals().contains(userPrincipal)){
+		subject.getPrincipals().add(userPrincipal);
+            }
+            _logger.log(Level.FINE,"\t\t[ClientPasswordLoginModule] " +
+                        "added PrincipalImpl to Subject");
+            
+	    String realm = DEFAULT_REALMNAME;
+
+	    PasswordCredential pc = 
+		new PasswordCredential(username, password, realm);
+	    if(!subject.getPrivateCredentials().contains(pc)) {
+		subject.getPrivateCredentials().add(pc);
+            }
+	    // in any case, clean out state
+	    username = null;
+	    for (int i = 0; i < password.length; i++){
+		password[i] = ' ';
+            }
+	    password = null;
+	    commitSucceeded = true;
+	    return true;
+	}
+    }
+
+    /**
+     * <p> This method is called if the LoginContext's
+     * overall authentication failed.
+     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
+     * did not succeed).
+     *
+     * <p> If this LoginModule's own authentication attempt
+     * succeeded (checked by retrieving the private state saved by the
+     * <code>login</code> and <code>commit</code> methods),
+     * then this method cleans up any state that was originally saved.
+     *
+     * <p>
+     *
+     * @exception LoginException if the abort fails.
+     *
+     * @return false if this LoginModule's own login and/or commit attempts
+     *		failed, and true otherwise.
+     */
+    public boolean abort() throws LoginException {
+	if (succeeded == false) {
+	    return false;
+	} else if (succeeded == true && commitSucceeded == false) {
+	    // login succeeded but overall authentication failed
+	    succeeded = false;
+	    username = null;
+	    if (password != null) {
+		for (int i = 0; i < password.length; i++){
+		    password[i] = ' ';
+                }
+		password = null;
+	    }
+	    userPrincipal = null;
+	} else {
+	    // overall authentication succeeded and commit succeeded,
+	    // but someone else's commit failed
+	    logout();
+	}
+	return true;
+    }
+
+    /**
+     * Logout the user.
+     *
+     * <p> This method removes the <code>PrincipalImpl</code>
+     * that was added by the <code>commit</code> method.
+     *
+     * <p>
+     *
+     * @exception LoginException if the logout fails.
+     *
+     * @return true in all cases since this <code>LoginModule</code>
+     *          should not be ignored.
+     */
+    public boolean logout() throws LoginException {
+
+	subject.getPrincipals().remove(userPrincipal);
+	succeeded = commitSucceeded;
+	username = null;
+	if (password != null) {
+	    for (int i = 0; i < password.length; i++){
+		password[i] = ' ';
+            }
+	    password = null;
+	}
+	userPrincipal = null;
+	return true;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/DigestCredentials.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/DigestCredentials.java
new file mode 100755
index 0000000..4551e75
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/DigestCredentials.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login;
+import com.sun.enterprise.security.auth.digest.api.DigestAlgorithmParameter;
+
+/**
+ *
+ * @author K.Venugopal@sun.com
+ */
+public class DigestCredentials {
+
+    private String realmName = "";
+    private String username = "";
+    private DigestAlgorithmParameter [] params = null;    
+
+    public DigestCredentials(String realmName, String username,DigestAlgorithmParameter [] params) {
+        this.realmName = realmName;
+        this.username = username;        
+        this.params = params;
+    }
+
+    public String getRealmName() {
+        return this.realmName;
+    }
+
+    public String getUserName() {
+        return this.username;
+    }
+
+    public DigestAlgorithmParameter [] getParameters(){
+        return params;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/DistinguishedPrincipalCredential.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/DistinguishedPrincipalCredential.java
new file mode 100644
index 0000000..90aa80e
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/DistinguishedPrincipalCredential.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login;
+
+import java.security.Principal;
+
+public class DistinguishedPrincipalCredential {
+    private Principal prin = null;
+
+    public DistinguishedPrincipalCredential(Principal prin) {
+        this.prin = prin;
+    }
+
+    public Principal getPrincipal() {
+        return prin;
+    }
+
+    public String toString() {
+        return "DistingushedPrincipal: " + prin;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/FileLoginModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/FileLoginModule.java
new file mode 100644
index 0000000..2fe4fee
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/FileLoginModule.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login;
+
+import java.util.*;
+import java.util.logging.Level;
+import javax.security.auth.*;
+import javax.security.auth.callback.*;
+import javax.security.auth.login.*;
+import javax.security.auth.spi.*;
+import com.sun.enterprise.security.auth.realm.file.FileRealm;
+import javax.security.auth.login.LoginException;
+
+/**
+ * File realm login module.
+ *
+ * <P>Provides a file-based implementation of a password login module.
+ * Processing is delegated to the FileRealm class.
+ *
+ * @see com.sun.enterprise.security.auth.login.PasswordLoginModule
+ * @see com.sun.enterprise.security.auth.realm.file.FileRealm
+ *
+ */
+public class FileLoginModule extends PasswordLoginModule
+{
+
+    /**
+     * Perform file authentication. Delegates to FileRealm.
+     *
+     * @throws LoginException If login fails (JAAS login() behavior).
+     *
+     */
+    protected void authenticate()
+        throws LoginException
+    {
+        if (!(_currentRealm instanceof FileRealm)) {
+            String msg = sm.getString("filelm.badrealm");
+            throw new LoginException(msg);
+        }
+        FileRealm fileRealm = (FileRealm)_currentRealm;
+
+        String[] grpList = fileRealm.authenticate(_username, getPasswordChar());
+
+        if (grpList == null) {  // JAAS behavior
+            String msg = sm.getString("filelm.faillogin", _username);
+            throw new LoginException(msg);
+        }
+
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "File login succeeded for: " + _username);
+        }
+
+        commitAuthentication(_username, getPasswordChar(),
+                             _currentRealm, grpList);
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LDAPLoginModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LDAPLoginModule.java
new file mode 100644
index 0000000..44ffd5d
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LDAPLoginModule.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login;
+
+
+import com.sun.enterprise.security.auth.login.PasswordLoginModule;
+import javax.security.auth.login.*;
+
+import com.sun.enterprise.security.auth.realm.ldap.LDAPRealm;
+
+/**
+ * iAS JAAS LoginModule for an LDAP Realm.
+ *
+ * <P>Refer to the LDAPRealm documentation for necessary and optional
+ * configuration parameters for the iAS LDAP login support.
+ *
+ * <P>There are various ways in which a user can be authenticated using
+ * an LDAP directory. Currently this login module only supports one mode,
+ * 'find and bind'. Other modes may be added as schedules permit.
+ *
+ * <P>Mode: <i>find-bind</i>
+ * <ol>
+ *  <li>An LDAP search is issued on the directory starting at base-dn
+ *      with the given search-filter (having substituted the user name
+ *      in place of %s). If no entries match this search, login fails
+ *      and authentication is over.
+ *  <li>The DN of the entry which matched the search as the DN
+ *      of the user in the directory. If the search-filter
+ *      is properly set there should always be a single match; if there are
+ *      multiple matches, the first one found is used.
+ *  <li>Next an LDAP bind is attempted using the above DN and the provided
+ *      password. If this fails, login is considered to have failed and
+ *      authentication is over.
+ *  <li>Then an LDAP search is issued on the directory starting at
+ *      group-base-dn with the given group-search-filter (having
+ *      substituted %d for the user DN previously found). From the
+ *      matched entry(ies) all the values of group-target are taken
+ *      as group names in which the user has membership. If no entries
+ *      are found, the group membership is empty.
+ * </ol>
+ *
+ *
+ */
+public class LDAPLoginModule extends PasswordLoginModule
+{
+    private LDAPRealm _ldapRealm;
+
+    /**
+     * Performs authentication for the current user.
+     *
+     */
+    protected void authenticate ()
+        throws LoginException
+    {
+        if (!(_currentRealm instanceof LDAPRealm)) {
+            String msg = sm.getString("ldaplm.badrealm");
+            throw new LoginException(msg);
+        }
+        _ldapRealm = (LDAPRealm)_currentRealm;
+        
+                       // enforce that password cannot be empty.
+                       // ldap may grant login on empty password!
+        if (getPasswordChar() == null || getPasswordChar().length == 0) {
+            String msg = sm.getString("ldaplm.emptypassword", _username);
+            throw new LoginException(msg);
+        }
+        
+        String mode = _currentRealm.getProperty(LDAPRealm.PARAM_MODE);
+
+        if (LDAPRealm.MODE_FIND_BIND.equals(mode)) {
+            String[] grpList = _ldapRealm.findAndBind(_username, getPasswordChar());
+            commitAuthentication(_username, getPasswordChar(),
+                    _currentRealm, grpList);
+        } else {
+            String msg = sm.getString("ldaplm.badmode", mode);
+            throw new LoginException(msg);
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LocalStrings.properties b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LocalStrings.properties
new file mode 100644
index 0000000..ecb1868
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LocalStrings.properties
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+login.user=user
+login.username=Enter Username
+login.password=Enter Password:
+login.certificate=Choose from the list of certificates:
+login.nousername=No user specified
+login.nocallback=Error: Callback not available to garner authentication information from user(CallbackName):
+pwdlm.noinfo=Missing Subject information for Login.
+pwdlm.nocreds=No credentials.
+pwdlm.norealm=No realm {0}.
+## No realm available for {requested realm}.
+pwdlm.norealmavail=No realm available for {0}.
+solarislm.badrealm=SolarisLoginModule requires SolarisRealm.
+solarislm.nulluser=Login failed for null user.
+solarislm.loginfail=Failed solaris login for {0}.
+ldaplm.badrealm=LDAPLoginModule requires LDAPRealm.
+ldaplm.badmode=Unsupported mode {0}.
+ldaplm.usernotfound=User {0} not found.
+ldaplm.emptypassword=Access denied on empty password for user {0}.
+filelm.badrealm=FileLoginModule requires FileRealm.
+filelm.faillogin=Failed file login for {0}.
+jdbclm.badrealm=JDBCLoginModule requires JDBCRealm.
+jdbclm.nulluser=Login failed for null user.
+jdbclm.loginfail=Failed jdbc login for {0}.
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LoginCallbackHandler.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LoginCallbackHandler.java
new file mode 100644
index 0000000..cc05717
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LoginCallbackHandler.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login;
+
+import java.io.*;
+import javax.security.auth.callback.*;
+
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.security.TextLoginDialog;
+import com.sun.enterprise.security.GUILoginDialog;
+
+/**
+ * This is the default callback handler provided by the application
+ * client container. The container tries to use the application specified 
+ * callback handler (if provided). If there is no callback handler or if
+ * the handler cannot be instantiated then this default handler is used.
+ *
+ * Note: User-defined Callback Handlers which intend to indicate cancel
+ * status must extend this class and set the ThreadLocal cancelStatus.
+ */
+public class LoginCallbackHandler implements CallbackHandler 
+{
+    private boolean isGUI;
+    private static final LocalStringManagerImpl localStrings =
+    new LocalStringManagerImpl(LoginCallbackHandler.class);
+    protected ThreadLocal<Boolean> cancelStatus = new ThreadLocal<Boolean>();
+
+    /**
+     * Check whether the authentication was cancelled by the user.
+     * @return boolean indicating whether the authentication was cancelled.
+     */
+    public boolean getCancelStatus() {
+        boolean cancelled = cancelStatus.get();
+        cancelStatus.set(false);
+        return cancelled;
+    }
+
+    public LoginCallbackHandler() {
+        this(true);
+    }
+
+    public LoginCallbackHandler(boolean gui) {
+        isGUI = gui;
+        cancelStatus.set(false);
+    }
+
+    /**
+     * This is the callback method called when authentication data is
+     * required. It either pops up a dialog box to request authentication
+     * data or use text input.
+     * @param the callback object instances supported by the login module.
+     */
+    public void handle(Callback[] callbacks) throws IOException,
+					UnsupportedCallbackException
+    {
+        if(isGUI) {
+            String user = localStrings.getLocalString("login.user", "user");
+	    new GUILoginDialog(user, callbacks);
+            for (int i = 0; i < callbacks.length; i++) {
+                if (callbacks[i] instanceof NameCallback) {
+                    cancelStatus.set(((NameCallback) callbacks[i]).getName() == null);
+                    break;
+                }
+            }
+        } else {
+	    new TextLoginDialog(callbacks);
+        }
+    }
+}
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LoginContextDriver.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LoginContextDriver.java
new file mode 100644
index 0000000..2926a94
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LoginContextDriver.java
@@ -0,0 +1,1075 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login;
+
+import org.glassfish.security.common.Group;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.Enumeration;
+import java.security.Principal;
+import java.util.logging.*;
+import java.security.PrivilegedAction;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.x500.X500Principal;
+import sun.security.x509.X500Name;
+import com.sun.logging.*;
+import com.sun.enterprise.common.iiop.security.GSSUPName;
+import com.sun.enterprise.common.iiop.security.AnonCredential;
+import com.sun.enterprise.security.SecurityContext;
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.security.SecurityServicesUtil;
+import com.sun.enterprise.security.audit.AuditManager;
+import com.sun.enterprise.security.common.AppservAccessController;
+//import com.sun.enterprise.security.SecurityContext;
+import com.sun.enterprise.security.auth.login.common.PasswordCredential;
+import com.sun.enterprise.security.auth.login.common.X509CertificateCredential;
+import com.sun.enterprise.security.auth.login.common.ServerLoginCallbackHandler;
+import com.sun.enterprise.security.auth.login.common.LoginException;
+import com.sun.enterprise.security.auth.realm.Realm;
+import com.sun.enterprise.security.auth.realm.certificate.CertificateRealm;
+
+// FIXME: ACC methods need to be moved to ACC-specific class.
+import com.sun.enterprise.security.auth.realm.InvalidOperationException;
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import com.sun.enterprise.security.auth.realm.NoSuchUserException;
+import com.sun.enterprise.security.common.ClientSecurityContext;
+//import com.sun.enterprise.appclient.AppContainer;
+import com.sun.enterprise.security.common.SecurityConstants;
+import org.glassfish.internal.api.Globals;
+
+
+/** 
+ *
+ * This class is invoked implicitly by the server to log in the user
+ * information that was sent on the wire by the client. Clients will 
+ * use the <i>doClientLogin</i> method to simulate authentication to the
+ * server.
+ *
+ * @author Harpreet Singh (hsingh@eng.sun.com)
+ * @author Jyri Virkki
+ *
+ */
+public class LoginContextDriver  {
+
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+
+    private static final ServerLoginCallbackHandler
+        dummyCallback = new ServerLoginCallbackHandler();
+
+    // moved to SecurityConstants.
+//    private static final String CLIENT_JAAS_PASSWORD = "default";
+//    private static final String CLIENT_JAAS_CERTIFICATE = "certificate";
+
+    public static final String CERT_REALMNAME = "certificate";
+  
+    private  static volatile AuditManager AUDIT_MANAGER=null;
+    
+    /** This class cannot be instantiated
+     *
+     */
+    private LoginContextDriver(){
+    }
+
+    private static AuditManager getAuditManager() {
+        if(AUDIT_MANAGER != null) {
+            return AUDIT_MANAGER;
+        }
+        return _getAuditManager();
+    }
+
+    private static synchronized AuditManager _getAuditManager() {
+        if(AUDIT_MANAGER == null) {
+            SecurityServicesUtil secServUtil  = Globals.get(SecurityServicesUtil.class);
+            AUDIT_MANAGER = secServUtil.getAuditManager();
+        }
+        return AUDIT_MANAGER;
+    }
+
+    /**
+     * This method is  just a convenience wrapper for
+     * <i>login(Subject, Class)</i> method. It will construct a
+     * PasswordCredential class.
+     *
+     * @param String username
+     * @param String password
+     * @param String realmName the name of the realm to login into, if realmName
+     * is null, we login into the default realm	 
+     */
+    
+    public static void login(String username, char[] password, String realmName){
+
+        if(realmName == null || !(Realm.isValidRealm(realmName))){    
+            realmName = Realm.getDefaultRealm();
+        }         
+        final Subject fs = new Subject();
+        final PasswordCredential pc =
+            new PasswordCredential(username, password, realmName);
+        
+        AppservAccessController.doPrivileged(new PrivilegedAction(){
+            public java.lang.Object run(){
+                fs.getPrivateCredentials().add(pc);
+                return fs;
+            }
+        });
+
+        LoginContextDriver.login(fs, PasswordCredential.class);
+    }
+
+
+    public static void login(AssertedCredentials asrtCred) throws javax.security.auth.login.LoginException {
+        Subject subject = new Subject();
+        subject.getPrivateCredentials().add(asrtCred);
+        String jaasCtx = null;
+        try {
+            jaasCtx = Realm.getInstance(asrtCred.getRealmName()).getJAASContext();
+        } catch (Exception ex) {
+            if (ex instanceof LoginException) {
+                throw (LoginException) ex;
+            } else {
+                throw (LoginException) new LoginException(ex.toString()).initCause(ex);
+            }
+        }
+
+        try {
+            // A dummyCallback is used to satisfy JAAS but it is never used.
+            // name/pwd info is already contained in Subject's Credential
+            LoginContext lg = new LoginContext(jaasCtx, subject, dummyCallback);
+            lg.login();
+        } catch (Exception e) {
+            if (_logger.isLoggable(Level.INFO)) {
+                _logger.log(Level.INFO, SecurityLoggerInfo.auditAtnRefusedError, asrtCred.getUserName());
+            }
+            if (_logger.isLoggable(Level.FINEST)) {
+                _logger.log(Level.FINEST, "doPasswordLogin fails", e);
+            }
+            if (AUDIT_MANAGER.isAuditOn()) {
+                AUDIT_MANAGER.authentication(asrtCred.getUserName(), asrtCred.getRealmName(), false);
+            }
+            if (e instanceof LoginException) {
+                throw (LoginException) e;
+            } else {
+                throw (LoginException) new LoginException("Login failed: " + e.getMessage()).initCause(e);
+            }
+        }
+
+        setSecurityContext(asrtCred.getUserName(), subject, asrtCred.getRealmName());
+    }
+
+
+    /**
+     * This method performs the login on the server side.
+     *
+     * <P>This method is the main login method for S1AS. It is called
+     * with a Subject and the type (class) of credential which should
+     * be checked. The Subject must contain a credential of the
+     * specified type or login will fail.
+     *
+     * <P>While the implementation has been cleaned up, the login
+     * process still consists of a number of special cases which are
+     * treated separately at the realm level. In the future tighter
+     * JAAS integration could clean some of this up.
+     *
+     * <P>The following credential types are recognized at this time:
+     * <ul>
+     *  <li>PasswordCredential - This is the general case for all login
+     *      methods which rely on the client providing a name and password.
+     *      It can be used with any realms/JAAS login modules which expect
+     *      such data (e.g. file realm, LDAP realm, UNIX realm)
+     *  <LI>X509CertificateCredential - Special case for SSL client auth.
+     *      Here authentication has already been done by the SSL subsystem
+     *      so this login only creates a security context based on the
+     *      certificate data.
+     *  <LI>AnonCredential - Unauthenticated session, set anonymous security
+     *      context.
+     *  <LI>GSSUPName - Retrieve user and realm and set security context.
+     *  <LI>X500Name - Retrieve user and realm and set security context.
+     * </ul>
+     *
+     * @param Subject the subject of the client
+     * @param Class the class of the credential packaged in the subject.
+     *
+     */
+    public static void login(Subject subject, Class cls)
+        throws LoginException
+    {
+        if (_logger.isLoggable(Level.FINEST)) {
+            _logger.log(Level.FINEST,
+                        "Processing login with credentials of type: "+
+                        cls.toString());
+        }
+        
+        if(cls.equals(PasswordCredential.class)) {
+            doPasswordLogin(subject);
+
+        } else if (cls.equals(X509CertificateCredential.class)) {
+            doCertificateLogin(subject);
+            
+        } else if (cls.equals(AnonCredential.class)) {
+            doAnonLogin();
+            
+        } else if (cls.equals(GSSUPName.class)) {
+            doGSSUPLogin(subject);
+            
+        } else if (cls.equals(X500Name.class)) {
+            doX500Login(subject, null);
+            
+        } else {
+            _logger.log(Level.INFO, SecurityLoggerInfo.unknownCredentialError,
+                        cls.toString());
+            throw new
+                LoginException("Unknown credential type, cannot login.");
+        }
+    }
+
+
+    /**
+     * This method is used for logging in a run As principal. It creates
+     * a JAAS subject whose credential is to type GSSUPName.
+     * This is used primarily for runas
+     *
+     */ 
+    public static void loginPrincipal(String username, String realmName)
+        throws LoginException {
+
+        // no realm provided, assuming default
+        if(realmName == null || realmName.length() == 0){
+            realmName = Realm.getDefaultRealm();
+        }
+        
+        final Subject s = new Subject();
+
+        final org.glassfish.security.common.PrincipalImpl p 
+            = new org.glassfish.security.common.PrincipalImpl(username);
+
+        final GSSUPName name = new GSSUPName(username, realmName);
+
+        AppservAccessController.doPrivileged(new PrivilegedAction() {
+            public java.lang.Object run() {
+                s.getPrincipals().add(p);
+                s.getPublicCredentials().add(name);
+                return null;
+            }
+        });
+
+       try {
+            Realm realm = Realm.getInstance(realmName);
+            Enumeration en = realm.getGroupNames(username);
+            Set<Principal> principalSet = s.getPrincipals();
+            while (en.hasMoreElements()) {
+                principalSet.add(new Group((String) en.nextElement()));
+            }
+
+        } catch (InvalidOperationException ex) {
+            _logger.log(Level.WARNING, SecurityLoggerInfo.invalidOperationForRealmError, new Object[] { username, realmName, ex.toString()});
+        } catch (NoSuchUserException ex){
+            _logger.log(Level.WARNING, SecurityLoggerInfo.noSuchUserInRealmError, new Object[] { username, realmName, ex.toString()});
+        } catch (NoSuchRealmException ex) {
+            LoginException lex = new LoginException(ex.toString());
+            lex.initCause(ex);
+            throw lex;
+        }
+        setSecurityContext(username, s, realmName);
+    }
+
+    
+    /**
+     * This method logs out the user by clearing the security context.
+     *
+     */
+    public static void logout() throws LoginException {
+        unsetSecurityContext();
+    }
+
+
+    /**
+     * Log in subject with PasswordCredential. This is a generic login
+     * which applies to all login mechanisms which process PasswordCredential.
+     * In other words, any mechanism which receives an actual username, realm
+     * and password set from the client.
+     *
+     * <P>The realm contained in the credential is checked, and a JAAS
+     * LoginContext is created using a context name obtained from the
+     * appropriate Realm instance. The applicable JAAS LoginModule
+     * is initialized (based on the jaas login configuration) and login()
+     * is invoked on it.
+     *
+     * <P>RI code makes several assumptions which are retained here:
+     * <ul>
+     *  <li>The PasswordCredential is stored as a private credential of
+     *      the subject.
+     *  <li>There is only one such credential present (actually, only
+     *      the first one is relevant if more are present).
+     * </ui>
+     *
+     * @param s Subject to be authenticated.
+     * @throws LoginException Thrown if the login fails.
+     *
+     */
+    private static void doPasswordLogin(Subject subject)
+        throws LoginException
+    {
+        final Subject s = subject;
+        
+        Object obj = getPrivateCredentials(s, PasswordCredential.class);
+        assert obj != null;
+        
+        PasswordCredential p = (PasswordCredential) obj;
+        String user = p.getUser();
+        char[] pwd = p.getPassword();
+        String realm = p.getRealm();
+        String jaasCtx = null;
+        try {
+            jaasCtx = Realm.getInstance(realm).getJAASContext();
+        } catch(Exception ex) {
+            if( ex instanceof LoginException )
+                throw (LoginException)ex;
+            else
+                throw (LoginException)new LoginException(ex.toString()).initCause(ex);
+        }
+
+        assert user != null;
+        assert pwd != null;
+        assert realm != null;
+        assert jaasCtx != null;
+
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.fine("Logging in user [" + user + "] into realm: " +
+                         realm + " using JAAS module: "+jaasCtx);
+        }
+
+        try {
+            // A dummyCallback is used to satisfy JAAS but it is never used.
+            // name/pwd info is already contained in Subject's Credential
+            LoginContext lg = new LoginContext(jaasCtx, s, dummyCallback);
+            lg.login();
+            
+        } catch (Exception e) {
+            if (_logger.isLoggable(Level.FINEST)) {
+                _logger.log(Level.FINEST, "doPasswordLogin fails", e);
+            }
+            if(getAuditManager() != null && getAuditManager().isAuditOn()){
+                getAuditManager().authentication(user, realm, false);
+            }
+            if( e instanceof LoginException )
+                throw (LoginException)e;
+            else
+                throw (LoginException)
+                    new LoginException("Login failed: " + e.getMessage()).initCause(e);
+        }
+        if(getAuditManager() != null && getAuditManager().isAuditOn()){
+            getAuditManager().authentication(user, realm, true);
+        }
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.fine("Password login succeeded for : " + user);
+        }
+
+        setSecurityContext(user, s, realm);
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "Set security context as user: "+user);
+        }
+    }
+
+   /** Performs login for JMAC security. The difference between this
+     * method and others is that it just verifies whether the login will succeed
+     * in the given realm.
+     * It does not set the result of the authentication in the appserver runtime
+     * environment
+     * A silent return from this method means that the given user succeeding in
+     * authenticating with the given password in the given realm
+     * @param subject
+     * @param username
+     * @param password
+     * @param realmName the realm to authenticate under
+     * @returns Subject on successful authentication
+     * @throws LoginException
+     */
+    public static Subject jmacLogin(Subject subject,
+            String username, char[] password, String realmName)
+            throws LoginException {
+
+        if(realmName == null || !(Realm.isValidRealm(realmName))){
+            realmName = Realm.getDefaultRealm();
+        }
+        if (subject == null) {
+            subject = new Subject();
+        }
+        final Subject fs = subject;
+        final PasswordCredential pc =
+            new PasswordCredential(username, password, realmName);
+
+        AppservAccessController.doPrivileged(new PrivilegedAction(){
+            public java.lang.Object run(){
+                fs.getPrivateCredentials().add(pc);
+                return fs;
+            }
+        });
+
+        String jaasCtx = null;
+        try {
+            jaasCtx = Realm.getInstance(realmName).getJAASContext();
+        } catch(Exception ex) {
+            if( ex instanceof LoginException )
+                throw (LoginException)ex;
+            else
+                throw (LoginException)
+                    new LoginException(ex.toString()).initCause(ex);
+        }
+
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.fine("jmac login user [" + username + "] into realm: " +
+                         realmName + " using JAAS module: "+jaasCtx);
+        }
+
+        try{
+            // A dummyCallback is used to satisfy JAAS but it is never used.
+            // name/pwd info is already contained in Subject's Credential
+            LoginContext lg = new LoginContext(jaasCtx, fs, dummyCallback);
+            lg.login();
+        } catch (Exception e) {
+            if (_logger.isLoggable(Level.INFO)) {
+                _logger.log(Level.INFO, SecurityLoggerInfo.auditAtnRefusedError,
+                            username);
+            }
+            if(getAuditManager().isAuditOn()){
+                getAuditManager().authentication(username, realmName, false);
+            }
+
+            if( e instanceof LoginException )
+                throw (LoginException)e;
+            else
+                throw (LoginException)
+                    new LoginException("Login failed: " + e.getMessage()).initCause(e);
+        }
+        if(getAuditManager().isAuditOn()){
+            getAuditManager().authentication(username, realmName, true);
+        }
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.fine("jmac Password login succeeded for : " + username);
+        }
+
+        return subject;
+        // do not set the security Context
+    }
+
+    public static Subject jmacLogin(Subject subject,
+            X500Principal x500Principal) throws LoginException {
+
+        if (subject == null) {
+            subject = new Subject();
+        }
+
+        final Subject fs = subject;
+
+        String userName = "";
+        try {
+            final X500Name x500Name = new X500Name(
+                x500Principal.getName(X500Principal.RFC1779));
+            userName = x500Name.toString();
+
+            AppservAccessController.doPrivileged(new PrivilegedAction(){
+                public java.lang.Object run(){
+                    fs.getPublicCredentials().add(x500Name);
+                    return fs;
+                }
+            });
+
+            Realm realm = Realm.getInstance(CertificateRealm.AUTH_TYPE);
+            CertificateRealm certRealm = (CertificateRealm)realm;
+            String jaasCtx = certRealm.getJAASContext();
+            if (jaasCtx != null) {
+                // The subject has the Cretificate Credential.
+                LoginContext lg = new LoginContext(jaasCtx, fs, dummyCallback);
+                lg.login();
+            }
+            certRealm.authenticate(fs, x500Name);
+        } catch(Exception ex) {
+            if (_logger.isLoggable(Level.INFO)) {
+                _logger.log(Level.INFO, SecurityLoggerInfo.auditAtnRefusedError,
+                            userName);
+            }
+            if (getAuditManager().isAuditOn()){
+                getAuditManager().authentication(userName,
+                    CertificateRealm.AUTH_TYPE, false);
+            }
+            if (ex instanceof LoginException) {
+                throw (LoginException)ex;
+            } else {
+                throw (LoginException)
+                    new LoginException(ex.toString()).initCause(ex);
+            }
+        }
+
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.fine("jmac cert login succeeded for: " + userName);
+        }
+
+        if (getAuditManager().isAuditOn()){
+            getAuditManager().authentication(userName,
+                CertificateRealm.AUTH_TYPE, true);
+        }
+        // do not set the security Context
+
+        return subject;
+    }
+
+    public static Subject jmacLogin(Subject subject, String identityAssertion, String realm) throws LoginException {
+
+        if (subject == null) {
+            subject = new Subject();
+        }
+        final Subject fs = subject;
+        String userName = identityAssertion;
+
+        try {
+            if (realm == null || "".equals(realm)) {
+                realm = Realm.getDefaultRealm();
+            }
+            Realm realmInst = Realm.getInstance(realm);
+            final Enumeration groups = realmInst.getGroupNames(userName);
+            if (groups != null && groups.hasMoreElements()) {
+                AppservAccessController.doPrivileged(new PrivilegedAction() {
+
+                    public java.lang.Object run() {
+                        while (groups.hasMoreElements()) {
+                            String grp = (String) groups.nextElement();
+                            fs.getPrincipals().add(new Group(grp));
+                        }
+                        return fs;
+                    }
+                });
+            }
+        } catch (Exception ex) {
+            if (_logger.isLoggable(Level.FINE)) {
+                _logger.log(Level.FINE, "Exception when trying to populate groups for CallerPrincipal " + identityAssertion, ex);
+            }
+        }
+        return subject;
+    }
+
+    /**
+     * A special case login for handling X509CertificateCredential.
+     * This does not get triggered based on current RI code. See X500Login.
+     *
+     */
+    private static void doCertificateLogin(Subject s)
+        throws LoginException
+    {
+        if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE, "Processing X509 certificate login.");
+        }
+        String realm = CertificateRealm.AUTH_TYPE;
+        String user = null;
+        try{
+            Object obj = getPublicCredentials(s, X509CertificateCredential.class);
+
+            X509CertificateCredential xp = (X509CertificateCredential) obj;
+            user = xp.getAlias();
+            if(_logger.isLoggable(Level.FINE)){
+                _logger.log(Level.FINE,"Set security context as user: "+user);
+            }
+            setSecurityContext(user, s, realm);
+            if(getAuditManager().isAuditOn()){
+                getAuditManager().authentication(user, realm, true);
+            }
+        } catch(LoginException le){
+            if(getAuditManager().isAuditOn()){
+                getAuditManager().authentication(user, realm, false);
+            }
+            throw le;
+        }
+    }
+
+
+    /**
+     * A special case login for anonymous credentials (no login info).
+     *
+     */
+    private static void doAnonLogin()
+        throws LoginException
+    {
+        // instance of anononymous credential login with guest
+        SecurityContext.setUnauthenticatedContext();
+       if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE,"Set anonymous security context.");
+        }  
+    }
+
+
+    /**
+     * A special case login for GSSUPName credentials.
+     *
+     */
+    private static void doGSSUPLogin(Subject s)
+        throws LoginException
+    {
+       if(_logger.isLoggable(Level.FINE)){
+             _logger.fine("Processing GSSUP login.");
+       }
+       String user = null;
+       String realm = Realm.getDefaultRealm();
+       try{
+            Object obj = getPublicCredentials(s, GSSUPName.class);
+
+            user = ((GSSUPName)obj).getUser();
+    
+            setSecurityContext(user, s, realm);
+            if(getAuditManager().isAuditOn()){
+                getAuditManager().authentication(user, realm, true);        
+            }
+            if (_logger.isLoggable(Level.FINE)) {
+                _logger.fine("GSSUP login succeeded for : " + user);
+            }
+       } catch (LoginException le){
+           if(getAuditManager().isAuditOn()){
+               getAuditManager().authentication(user, realm, false);
+           }
+           throw le;
+       }
+    }
+
+
+    /**
+     * A special case login for X500Name credentials.
+     * This is invoked for certificate login because the containers
+     * extract the X.500 name from the X.509 certificate before calling
+     * into this class.
+     *
+     */
+    public static void doX500Login(Subject s, String appModuleID)
+        throws LoginException
+    {
+       if(_logger.isLoggable(Level.FINE)){        
+            _logger.fine("Processing X.500 name login.");
+       }
+       String user = null;
+       String realm_name = null;
+       try{
+            X500Name x500name = (X500Name)getPublicCredentials(s, X500Name.class);
+            user = x500name.getName();
+        
+            // In the RI-inherited implementation this directly creates
+            // some credentials and sets the security context. This means
+            // that the certificate realm does not get an opportunity to
+            // process the request. While the realm will not do any
+            // authentication (already done by this point) it can choose
+            // to adjust the groups or principal name or other variables
+            // of the security context. Of course, bug 4646134 needs to be
+            // kept in mind at all times.
+
+            Realm realm = Realm.getInstance(CertificateRealm.AUTH_TYPE);
+
+            if (realm instanceof CertificateRealm) { // should always be true
+    
+                CertificateRealm certRealm = (CertificateRealm)realm;
+                String jaasCtx = certRealm.getJAASContext();
+                if (jaasCtx != null) {
+                    // The subject has the Cretificate Credential.
+                    LoginContext lg = new LoginContext(jaasCtx, s, new ServerLoginCallbackHandler(user, null, appModuleID));
+                    lg.login();
+                }
+                certRealm.authenticate(s, x500name);
+                realm_name = CertificateRealm.AUTH_TYPE;
+                if(getAuditManager().isAuditOn()){
+                    getAuditManager().authentication(user, realm_name, true);
+                }
+            } else {            
+                _logger.warning(SecurityLoggerInfo.certLoginBadRealmError);            
+                realm_name = realm.getName();
+                setSecurityContext(user, s, realm_name);
+            }
+        
+            if (_logger.isLoggable(Level.FINE)) {
+                _logger.fine("X.500 name login succeeded for : " + user);
+            }
+       } catch (LoginException le){
+           if(getAuditManager().isAuditOn()){
+               getAuditManager().authentication(user, realm_name, false);
+           }
+           throw le;
+       } catch (Exception ex) {
+           throw (LoginException)new LoginException(ex.toString()).initCause(ex);
+       }
+    }
+
+
+    /**
+     * Retrieve a public credential of the given type (java class) from the
+     * subject.
+     *
+     * <P>This method retains the RI assumption that only the first
+     * credential of the given type is used.
+     *
+     */
+    private static Object getPublicCredentials(Subject s, Class<?> cls)
+        throws LoginException
+    {
+        Set credset = s.getPublicCredentials(cls);
+        
+        final Iterator iter = credset.iterator();
+
+        if(!iter.hasNext()) {
+            String credmsg = cls.toString();
+            if(_logger.isLoggable(Level.FINER)){
+                _logger.finer("Expected public credentials of type : " +
+                          credmsg + " but none found.");
+            }
+            throw new LoginException("Expected public credential of type: "+
+                                     credmsg + " but none found.");
+        }
+        
+        Object obj = null;    
+        try{
+            obj = AppservAccessController.doPrivileged(new PrivilegedAction(){
+                public java.lang.Object run(){
+                    return iter.next();
+                }
+            });
+        } catch (Exception e){
+            // should never come here 
+            if( e instanceof LoginException )
+                throw (LoginException)e;
+            else
+                throw (LoginException)
+                    new LoginException("Failed to retrieve public credential: "+
+                                       e.getMessage()).initCause(e);
+        }
+
+        return obj;
+    }
+
+
+    /**
+     * Retrieve a private credential of the given type (java class) from the
+     * subject.
+     *
+     * <P>This method retains the RI assumption that only the first
+     * credential of the given type is used.
+     *
+     */
+    private static Object getPrivateCredentials(Subject subject,
+                                                Class<?> cls)
+        throws LoginException
+    {
+        final Subject s = subject;
+        final Class<?> cl = cls;
+        
+        final Set credset = (Set)
+            AppservAccessController.doPrivileged(new PrivilegedAction() {
+                public java.lang.Object run() {
+                    return
+                        s.getPrivateCredentials(cl);
+                }
+            });
+
+        final Iterator iter = credset.iterator();
+
+        if (!iter.hasNext()) {
+           String credmsg = cls.toString();
+           if(_logger.isLoggable(Level.FINER)){
+                 _logger.finer("Expected private credential of type: "+
+                              credmsg + " but none found.");
+           }
+            throw new LoginException("Expected private credential of type: "+
+                                     credmsg + " but none found.");
+        }
+
+        // retrieve only first credential of give type
+        Object obj = null;
+        try{
+            obj = AppservAccessController.doPrivileged(new PrivilegedAction(){
+                public java.lang.Object run(){
+                    return iter.next();
+                }
+            });
+        } catch (Exception e){
+            // should never come here 
+            if( e instanceof LoginException )
+                throw (LoginException)e;
+            else
+                throw (LoginException)
+                    new LoginException("Failed to retrieve private credential: "+
+                                     e.getMessage()).initCause(e);
+        }
+
+        return obj;
+    }
+
+    
+    /**
+     * This method sets the security context on the current Thread Local 
+     * Storage
+     * @param String username is the user who authenticated
+     * @param Subject is the subject representation of the user
+     * @param Credentials the credentials that the server associated with it
+     */
+private static void setSecurityContext(String userName,
+            Subject subject, String realm) {
+
+        SecurityContext securityContext = new SecurityContext(userName, subject, realm);
+        SecurityContext.setCurrent(securityContext);
+    }
+
+    /**
+     * Set the current security context on the Thread Local Storage to null.
+     *
+     */
+    private static void unsetSecurityContext() {
+        SecurityContext.setCurrent((SecurityContext)null);
+    }
+    /**
+     * Perform login on the client side.
+     * It just simulates the login on the client side.
+     * The method uses the callback handlers and generates correct
+     * credential information that will be later sent to the server
+     * @param int type whether it is <i> username_password</i> or 
+     * <i> certificate </i> based login.
+     * @param CallbackHandler the callback handler to gather user information.
+     * @exception LoginException the exception thrown by the callback handler.
+     */
+    public  static Subject doClientLogin(int type,
+                     javax.security.auth.callback.CallbackHandler jaasHandler)
+        throws LoginException
+    {
+        final javax.security.auth.callback.CallbackHandler handler =
+            jaasHandler;
+        // the subject will actually be filled in with a PasswordCredential
+        // required by the csiv2 layer in the LoginModule.
+        // we create the dummy credential here and call the 
+        // set security context. Thus, we have 2  credentials, one each for
+        // the csiv2 layer and the other for the RI.
+        final Subject subject = new Subject();
+        
+        if (type == SecurityConstants.USERNAME_PASSWORD ){
+            AppservAccessController.doPrivileged(new PrivilegedAction() {
+                public java.lang.Object run() {
+                    try{
+                        LoginContext lg = 
+                            new LoginContext(SecurityConstants.CLIENT_JAAS_PASSWORD, 
+                                             subject, handler);
+                        lg.login();
+                    }catch(javax.security.auth.login.LoginException e){
+                        throw (LoginException)
+                            new LoginException(e.toString()).initCause(e);
+                    }
+                    
+                    return null;
+                }
+            });
+            postClientAuth(subject, PasswordCredential.class);
+            return subject;
+        } else if (type == SecurityConstants.CERTIFICATE){
+            AppservAccessController.doPrivileged(new PrivilegedAction() {
+                public java.lang.Object run() {
+                    try{
+                        LoginContext lg = 
+                            new LoginContext(SecurityConstants.CLIENT_JAAS_CERTIFICATE,
+                                             subject, handler);
+                        lg.login();
+                    }catch(javax.security.auth.login.LoginException e){
+                        throw (LoginException)
+                            new LoginException(e.toString()).initCause(e);
+                    }
+                    
+                    return null;
+                }
+            });
+            postClientAuth(subject, X509CertificateCredential.class);
+            return subject;
+        } else if (type == SecurityConstants.ALL){
+            AppservAccessController.doPrivileged(new PrivilegedAction() {
+                public java.lang.Object run() {
+                    try{
+                        LoginContext lgup =
+                            new LoginContext(SecurityConstants.CLIENT_JAAS_PASSWORD,
+                                             subject, handler);
+                        LoginContext lgc = 
+                            new LoginContext(SecurityConstants.CLIENT_JAAS_CERTIFICATE,
+                                                 subject, handler);
+                        lgup.login();
+                        postClientAuth(subject, PasswordCredential.class);
+                        
+                        lgc.login();
+                        postClientAuth(subject,
+                                       X509CertificateCredential.class);
+                    }catch(javax.security.auth.login.LoginException e){
+                        throw (LoginException)
+                            new LoginException(e.toString()).initCause(e);
+                    }
+                    
+                    return null;
+                }
+            });
+            return subject;
+        } else{ 
+            AppservAccessController.doPrivileged(new PrivilegedAction() {
+                public java.lang.Object run() {
+                    try{
+                        LoginContext lg =
+                            new LoginContext(SecurityConstants.CLIENT_JAAS_PASSWORD, 
+                                             subject, handler);
+                        lg.login();
+                        postClientAuth(subject, PasswordCredential.class);
+                    }catch(javax.security.auth.login.LoginException e){
+                        throw (LoginException)
+                            new LoginException(e.toString()).initCause(e);
+                    }
+                    return null;
+                }
+            });
+            return subject;
+        }
+    }
+
+    /**
+     * Perform logout on the client side.
+     * @exception LoginException
+     */
+    public static void doClientLogout() throws LoginException {
+        unsetClientSecurityContext();
+    }
+     /**
+     * Performs Digest authentication based on RFC 2617. It
+     *
+     * @param digestCred DigestCredentials
+     */
+    public static void login(DigestCredentials digestCred) throws javax.security.auth.login.LoginException {
+        Subject subject = new Subject();
+        subject.getPrivateCredentials().add(digestCred);
+        String jaasCtx = null;
+        try {
+            jaasCtx = Realm.getInstance(digestCred.getRealmName()).getJAASContext();
+        } catch (Exception ex) {
+            if (ex instanceof LoginException) {
+                throw (LoginException) ex;
+            } else {
+                throw (LoginException) new LoginException(ex.toString()).initCause(ex);
+            }
+        }
+
+        try {
+            // A dummyCallback is used to satisfy JAAS but it is never used.
+            // name/pwd info is already contained in Subject's Credential
+            LoginContext lg = new LoginContext(jaasCtx, subject, dummyCallback);
+            lg.login();
+        } catch (Exception e) {
+            if (_logger.isLoggable(Level.INFO)) {
+                _logger.log(Level.INFO, SecurityLoggerInfo.auditAtnRefusedError, digestCred.getUserName());
+            }
+            if (_logger.isLoggable(Level.FINEST)) {
+                _logger.log(Level.FINEST, "doPasswordLogin fails", e);
+            }
+            if (getAuditManager().isAuditOn()) {
+                getAuditManager().authentication(digestCred.getUserName(), digestCred.getRealmName(), false);
+            }
+            if (e instanceof LoginException) {
+                throw (LoginException) e;
+            } else {
+                throw (LoginException) new LoginException("Login failed: " + e.getMessage()).initCause(e);
+            }
+        }
+
+        setSecurityContext(digestCred.getUserName(), subject, digestCred.getRealmName());
+    }
+
+ 
+    /**
+     * Extract the relevant username and realm information from the
+     * subject and sets the correct state in the security context. The
+     * relevant information is set into the Thread Local Storage from
+     * which then is extracted to send over the wire.
+     *
+     * @param Subject the subject returned by the JAAS login.
+     * @param Class the class of the credential object stored in the subject
+     *
+     */
+    private  static void postClientAuth(Subject subject, Class<?> clazz){
+        final Class<?> clas = clazz;
+        final Subject fs = subject;
+        Set credset = 
+            (Set) AppservAccessController.doPrivileged(new PrivilegedAction() {
+                public java.lang.Object run() {
+                if(_logger.isLoggable(Level.FINEST)){
+                    _logger.log(Level.FINEST,"LCD post login subject :" + fs);
+                }
+                    return fs.getPrivateCredentials(clas);
+                }
+            });
+        final Iterator iter = credset.iterator();
+        while(iter.hasNext()) {
+            Object obj = null;    
+            try{
+                obj = AppservAccessController.doPrivileged(new PrivilegedAction(){
+                    public java.lang.Object run(){
+                        return iter.next();
+                    }
+                });
+            } catch (Exception e){
+                // should never come here 
+                _logger.log(Level.SEVERE,
+                            SecurityLoggerInfo.securityAccessControllerActionError,
+                            e);
+            }
+            if(obj instanceof PasswordCredential) {
+                PasswordCredential p = (PasswordCredential) obj;
+                String user = p.getUser();
+                if(_logger.isLoggable(Level.FINEST)){
+                    String realm = p.getRealm();
+                    _logger.log(Level.FINEST,"In LCD user-pass login:" +
+                            user +" realm :" + realm);
+                }
+                setClientSecurityContext(user, fs);
+                return;
+            } else if (obj instanceof X509CertificateCredential){
+                X509CertificateCredential p = (X509CertificateCredential) obj;
+                String user = p.getAlias();
+                if(_logger.isLoggable(Level.FINEST)){
+                    String realm = p.getRealm();
+                    _logger.log(Level.FINEST,"In LCD cert-login::" +
+                                user +" realm :" + realm);
+                }
+                setClientSecurityContext(user, fs);
+                return;
+            }
+        }
+    }
+
+    
+    /**
+     * Sets the security context on the appclient side.
+     * It sets the relevant information into the TLS
+     * @param String username is the user who authenticated
+     * @param Subject is the subject representation of the user
+     * @param Credentials the credentials that the server associated with it
+     */
+    private static void setClientSecurityContext(String username, 
+                                                 Subject subject) {                                       
+        ClientSecurityContext securityContext =
+            new ClientSecurityContext(username, subject);
+        ClientSecurityContext.setCurrent(securityContext);
+    }
+
+    
+    /**
+     * Unsets the current appclient security context on the Thread
+     * Local Storage
+     */
+    private  static void unsetClientSecurityContext() {
+        ClientSecurityContext.setCurrent(null);
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/PasswordLoginModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/PasswordLoginModule.java
new file mode 100644
index 0000000..69fccdc
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/PasswordLoginModule.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login;
+
+import com.sun.enterprise.security.BasePasswordLoginModule;
+import com.sun.enterprise.security.auth.realm.Realm;
+import javax.security.auth.login.LoginException;
+
+/**
+ * Abstract base class for password-based login modules.
+ * This class is provided for
+ * backward compatibility and is a candidate for deprecation.
+ *
+ */
+@Deprecated
+public abstract class PasswordLoginModule extends BasePasswordLoginModule
+{
+
+    /**
+     * Maintain RI compatibility.
+     *
+     * <P>This is a convenience method which can be used by subclasses
+     * to complete the steps required by RI legacy authentication code.
+     * Most of this should go away if a clean JAAS/Subject based
+     * infrastructure is provided. But for now this must be done.
+     *
+     * <P>Note that this method is called after the authentication
+     * has succeeded. If authentication failed do not call this method.
+     * 
+     * <P>A lot of the RI behavior is still present here. Some of the
+     * most notable points to remember:
+     * <ul>
+     *  <li>Global instance field succeeded is set to true by this method.
+     *
+     * @param username Name of authenticated user.
+     * @param password Password of this user.
+     * @param theRealm Current Realm object for this authentication.
+     * @param groups String array of group memberships for user (could be
+     *     empty). 
+     * @returns void
+     *
+     */
+    @Deprecated
+    public final void commitAuthentication(String username,
+                                        String password,
+                                        Realm theRealm,
+                                        String[] groups)
+    {
+        commitUserAuthentication(groups);
+    }
+
+   /**
+     * Since the passwords are to be stored as to have char[]
+     * BT: 6946553.
+     * Retaining the other method for backward compatability
+     *
+     * @param username Name of authenticated user.
+     * @param password Password of this user in char[].
+     * @param theRealm Current Realm object for this authentication.
+     * @param groups String array of group memberships for user (could be
+     *     empty).
+     * @returns void
+     *
+     */
+    public final void commitAuthentication(String username,
+                                        char[] password,
+                                        Realm theRealm,
+                                        String[] groups)
+    {
+        commitUserAuthentication(groups);
+    }
+    /**
+     * Older implementations can implement authenticate. While new implementation
+     * calls authenticateUser
+     * @throws LoginException
+     */
+    protected final void authenticateUser () throws LoginException{
+        authenticate();
+    }
+
+    /**
+     * Perform authentication decision.
+     * Method returns silently on success and returns a LoginException
+     * on failure.
+     * To be implmented by sub-classes
+     * @return void authenticate returns silently on successful authentication.
+     * @throws com.sun.enterprise.security.LoginException on authentication failure.
+     *
+     */
+    abstract protected void authenticate()
+        throws LoginException;
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/SolarisLoginModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/SolarisLoginModule.java
new file mode 100644
index 0000000..1ef9cc6
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/SolarisLoginModule.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login;
+
+import java.util.*;
+
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+import javax.security.auth.*;
+import javax.security.auth.callback.*;
+import javax.security.auth.login.*;
+import javax.security.auth.spi.*;
+
+import com.sun.enterprise.security.auth.realm.solaris.SolarisRealm;
+
+// limit RI imports
+import com.sun.enterprise.security.auth.Privilege;
+import com.sun.enterprise.security.auth.PrivilegeImpl;
+
+import com.sun.enterprise.security.auth.realm.Realm;
+import com.sun.enterprise.security.auth.login.common.PasswordCredential;
+import javax.security.auth.login.LoginException;
+
+/**
+ * Solaris realm login module.
+ *
+ * <P>Processing is delegated to the SolarisRealm class which accesses
+ * the native methods.
+ *
+ * @see com.sun.enterprise.security.auth.login.PasswordLoginModule
+ * @see com.sun.enterprise.security.auth.realm.solaris.SolarisRealm
+ *
+ */
+public class SolarisLoginModule extends PasswordLoginModule
+{
+
+    /**
+     * Perform solaris authentication. Delegates to SolarisRealm.
+     *
+     * @throws LoginException If login fails (JAAS login() behavior).
+     *
+     */
+    protected void authenticate()
+        throws LoginException
+    {
+        if (!(_currentRealm instanceof SolarisRealm)) {
+            String msg = sm.getString("solarislm.badrealm");
+            throw new LoginException(msg);
+        }
+        
+        SolarisRealm solarisRealm = (SolarisRealm)_currentRealm;
+
+        // A solaris user must have a name not null so check here.
+        if ( (_username == null) || (_username.length() == 0) ) {
+            String msg = sm.getString("solarislm.nulluser");
+            throw new LoginException(msg);
+        }
+        
+        String[] grpList = solarisRealm.authenticate(_username, getPasswordChar());
+
+        if (grpList == null) {  // JAAS behavior
+            String msg = sm.getString("solarislm.loginfail", _username);
+            throw new LoginException(msg);
+        }
+
+        if (_logger.isLoggable(Level.FINEST)) {
+            _logger.finest("Solaris login succeeded for: " + _username);
+        }
+
+        commitAuthentication(_username, getPasswordChar(),
+                             _currentRealm, grpList);
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/LocalStrings.properties b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/LocalStrings.properties
new file mode 100644
index 0000000..5bcf3a2
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/LocalStrings.properties
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+
+enterprise.security.login_failed=Login Failed.
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/LoginException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/LoginException.java
new file mode 100644
index 0000000..23dd42e
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/LoginException.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login.common;
+
+import com.sun.enterprise.util.LocalStringManagerImpl;
+/**
+ * LoginException is thrown by the LoginContext class whenever
+ * the following happens: <UL>
+ * <LI> If the client is unable to authenticate successfully with the 
+ * </UL>
+ * @see com.sun.enterprise.security.auth.AuthenticationStatus
+ * @author Harish Prabandham
+ * @author Harpreet Singh
+ */
+
+public class LoginException extends SecurityException {
+
+    private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(LoginException.class);
+
+    private boolean status = false;
+
+
+    /**
+     * Create a new LoginException object with the given message
+     * @param The message indicating why authentication failed.
+     */
+    public LoginException(String message) {
+	super(message);
+    }
+
+    
+    /**
+     * Create a new LoginException object with the given authentication
+     * value.
+     * @param The AuthenticationStatus object
+     */
+    public LoginException(boolean as){
+	super(localStrings.getLocalString("enterprise.security.login_failed", 
+					   "Login Failed."));
+	status = as;
+    }
+
+    
+    /**
+     * Returns the status of the Authentication.
+     */
+    public boolean getStatus(){
+	return status;
+    }
+    
+}
+
+
+
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/PasswordCredential.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/PasswordCredential.java
new file mode 100644
index 0000000..d220a37
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/PasswordCredential.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login.common;
+
+import java.util.Arrays;
+
+/**
+ * This class holds the user password for the shared password realm and the
+ * realm name. This credential is added as a private credential to the
+ * JAAS subject.
+ */
+
+public class PasswordCredential {
+    private String username;
+ //   private String password;
+    private char[] password;
+    private String realm;
+    private boolean readOnly = false;
+    // target_name is filled in by the SecSecurityServer interceptor
+    // only when a CSIv2 GSSUP authenticator is received.
+
+    private byte[] target_name = {};
+
+    /**
+     * Construct a credential with the specified password and realm name.
+     * @param the password.
+     * @param the realm name. The only value supported for now is "default".
+     */
+    public PasswordCredential(String user, char[] password, String realm)
+    {
+	this.username = user;
+        //Copy the password to another reference before storing it to the
+        //instance field.
+        char[] passwordCopy = (password == null) ? null : Arrays.copyOf(password, password.length);
+	this.password = passwordCopy;
+	this.realm = realm;
+
+        if (this.username == null ) { this.username = ""; }
+        if (this.password == null ) { this.password = new char[]{}; }
+        if (this.realm == null ) { this.realm = ""; }
+    }
+
+    
+    /**
+     * called by SecServerRequestInterceptor 
+     * The object if created on the server side is readonly
+     */
+    public PasswordCredential(String user, char[] password,
+                              String realm, byte[] target_name)
+    {
+        this(user, password, realm);
+	this.target_name = target_name;
+        readOnly = true;
+    }
+
+    
+    /**
+     * Return the realm name.
+     * @return the realm name. Only value supported for now is "default".
+     */
+    public String getRealm() {
+	return realm;
+    }
+
+    
+    /**
+     * Return the username.
+     * @return the user name.
+     */
+    public String getUser() {
+	return username;
+    }
+
+    public void setRealm(String realm){
+        if(!readOnly){
+            this.realm = realm;
+        }
+    }
+    
+    /**
+     * Return the password.
+     * @return the password.
+     */
+    public char[] getPassword() {
+       //Copy the password to another reference before returning it
+        char[] passwordCopy = (password == null) ? null : Arrays.copyOf(password, password.length);
+	return passwordCopy;
+    }
+
+    
+    /**
+     * Return the target_name
+     * @return the target_name
+     */
+    public byte[] getTargetName() {
+	return this.target_name;
+    }
+
+    /**
+     * Compare two instances of the credential and return true if they are
+     * the same and false otherwise.
+     * @param the object that this instance is being compared to.
+     * @return true if the instances are equal, false otherwise
+     */
+    public boolean equals(Object o) {
+	if(o instanceof PasswordCredential) {
+	    PasswordCredential pc = (PasswordCredential) o;
+	    if(pc.getUser().equals(username) && 
+		Arrays.equals(pc.getPassword(),password) &&
+		pc.getRealm().equals(realm)) {
+		return true;
+	    }
+	}
+	return false;
+    }
+
+    
+    /**
+     * Return the hashCode computed from the password and realm name.
+     * @return the hash code.
+     */
+    public int hashCode() {
+	return username.hashCode() + Arrays.hashCode(password) + realm.hashCode();
+    }
+
+    
+    /**
+     * The string representation of the credential.
+     */
+    public String toString() {
+	String s = "Realm=" + realm;
+	s = s + " Username=" + username;
+	s = s + " Password=" + "########";
+	s = s + " TargetName = " + new String(target_name);
+	return s;
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/ServerLoginCallbackHandler.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/ServerLoginCallbackHandler.java
new file mode 100644
index 0000000..524cee9
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/ServerLoginCallbackHandler.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login.common;
+
+import com.sun.enterprise.security.auth.realm.certificate.CertificateRealm;
+import java.io.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import javax.security.auth.callback.*;
+
+
+/**
+ * This is the default callback handler provided by the application
+ * client container. The container tries to use the application specified 
+ * callback handler (if provided). If there is no callback handler or if
+ * the handler cannot be instantiated then this default handler is used.
+ */
+public class ServerLoginCallbackHandler implements CallbackHandler 
+{
+    private static final String GP_CB="javax.security.auth.message.callback.GroupPrincipalCallback";
+    private static final String GPCBH_UTIL = "com.sun.enterprise.security.jmac.callback.ServerLoginCBHUtil";
+    private static final String GPCBH_UTIL_METHOD="processGroupPrincipal";
+    private String username = null;
+    private char[] password = null;
+    private String moduleID = null;
+
+    public ServerLoginCallbackHandler(String username, char[] password) {
+	this.username = username;
+	this.password = password;
+    }
+
+    public ServerLoginCallbackHandler(String username, char[] password, String moduleID) {
+	this.username = username;
+	this.password = password;
+        this.moduleID = moduleID;
+    }
+    
+    public ServerLoginCallbackHandler(){
+    }
+    
+    public void setUsername(String user){
+	username = user;
+    }
+    
+    public void setPassword(char[] pass){
+	password = pass;
+    }
+
+    public void setModuleID(String moduleID) {
+        this.moduleID = moduleID;
+    }
+
+    
+    /**
+     * This is the callback method called when authentication data is
+     * required. It either pops up a dialog box to request authentication
+     * data or use text input.
+     * @param the callback object instances supported by the login module.
+     */
+    public void handle(Callback[] callbacks) throws IOException,
+					UnsupportedCallbackException
+    {
+	for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof NameCallback){
+		NameCallback nme = (NameCallback)callbacks[i];
+		nme.setName(username);
+	    } else if (callbacks[i] instanceof PasswordCallback){
+		PasswordCallback pswd = (PasswordCallback)callbacks[i];
+		pswd.setPassword(password);
+	    } else if (callbacks[i] instanceof CertificateRealm.AppContextCallback){
+                ((CertificateRealm.AppContextCallback) callbacks[i]).setModuleID(moduleID);
+            } else if (GP_CB.equals(callbacks[i].getClass().getName())){
+                processGroupPrincipal(callbacks[i]);
+            } else {
+                throw new UnsupportedCallbackException(callbacks[i]);
+            }
+	}
+    }
+
+    private static void processGroupPrincipal(Callback callback) throws UnsupportedCallbackException {
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        try {
+            Class clazz = loader.loadClass(GPCBH_UTIL);
+            Method meth = clazz.getMethod(GPCBH_UTIL_METHOD, Callback.class);
+            meth.invoke(null, callback);
+        } catch (IllegalAccessException ex) {
+            throw new UnsupportedCallbackException(callback);
+        } catch (IllegalArgumentException ex) {
+            throw new UnsupportedCallbackException(callback);
+        } catch (InvocationTargetException ex) {
+            throw new UnsupportedCallbackException(callback);
+        } catch (NoSuchMethodException ex) {
+            throw new UnsupportedCallbackException(callback);
+        } catch (SecurityException ex) {
+            throw new UnsupportedCallbackException(callback);
+        } catch (ClassNotFoundException ex) {
+             throw new UnsupportedCallbackException(callback);
+        }
+
+    }
+
+    
+}
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/X509CertificateCredential.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/X509CertificateCredential.java
new file mode 100644
index 0000000..5bdc209
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/X509CertificateCredential.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.login.common;
+
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+
+/**
+ * This class holds the user certificate for the certificate realm and the
+ * realm name. This credential is added as a public credential to the
+ * JAAS subject.
+ */
+
+public class X509CertificateCredential {
+    private X509Certificate[] certChain;
+    private String realm;
+    private String alias;
+
+    /**
+     * Construct a credential with the specified X509Certificate certificate
+     * chain, realm name and alias.
+     * @param the X509Certificate.
+     * @param the alias for the certificate
+     * @param the realm name. The only value supported for now is "certificate".
+     */
+
+    public X509CertificateCredential(X509Certificate[] certChain, 
+				    String alias, String realm)
+    {
+	this.certChain = certChain;
+	this.alias = alias;
+	this.realm = realm;
+    }
+
+    /**
+     * Return the alias for the certificate.
+     * @return the alias. 
+     */
+    public String getAlias() {
+	return alias;
+    }
+
+    /**
+     * Return the realm name.
+     * @return the realm name. Only value supported for now is "certificate".
+     */
+    public String getRealm() {
+	return realm;
+    }
+
+    /**
+     * Return the chain of certificates.
+     * @return the chain of X509Certificates.
+     */
+    public X509Certificate[] getX509CertificateChain() {
+	return certChain;
+    }
+
+    /**
+     * Compare two instances of the credential and return true if they are
+     * the same and false otherwise.
+     * @return true if the instances are equal, false otherwise.
+     */
+    public boolean equals(Object o) {
+	if(o instanceof X509CertificateCredential) {
+	    X509CertificateCredential pc = (X509CertificateCredential) o;
+	    if(pc.getRealm().equals(realm) && pc.getAlias().equals(alias)) {
+		X509Certificate[] certs = pc.getX509CertificateChain();
+		for(int i = 0; i < certs.length; i++) {
+		    if(!certs[i].equals(certChain[i])) {
+			return false;
+		    }
+		}
+		return true;
+	    }
+	}
+	return false;
+    }
+
+    /**
+     * Return the hashCode computed from the certificate, realm and alias.
+     * @return the hash code.
+     */
+    public int hashCode() {
+	return Arrays.hashCode(certChain) + realm.hashCode() + ((alias != null)?alias.hashCode():0);
+    }
+
+    /**
+     * String representation of the credential.
+     */
+    public String toString() {
+	String s = "Realm=" + realm;
+	s = s + " alias=" + alias;
+        StringBuffer certChainStr = new StringBuffer("");
+        for (int i=0; i < certChain.length; i++) {
+            certChainStr.append(certChain[i].toString());
+            certChainStr.append("\n");
+        }
+	s = s + " X509Certificate=" + certChainStr.toString();
+	return s;
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/nonce/.gitkeep_empty_dir b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/nonce/.gitkeep_empty_dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/nonce/.gitkeep_empty_dir
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AuthenticationHandler.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AuthenticationHandler.java
new file mode 100644
index 0000000..bf3513a
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AuthenticationHandler.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+import java.security.Principal;
+import com.sun.enterprise.security.auth.*;
+
+/**
+ * This interface is used by the Authentication Service to have the 
+ * Principal authenticated by the realm. A realm provides an 
+ * implementation of this interface.
+ * @author Harish Prabandham
+ * @author Harpreet Singh
+ */
+public interface AuthenticationHandler {
+    /**
+     * Returns the Realm that this Authentication Handler is authenticating
+     * in.
+     * @return The Realm object in which this handler is authenticating in.
+     */
+    public Realm getRealm();
+
+    /**
+     * This method authenticates the given principal using the specified 
+     * authentication data and the Principal's Credentials. The result of
+     * the authentication is returned back.
+     * @param The principal (user) being authenticated.
+     * @param The data needed for authentication.
+     * @return boolean denoting true for success and false for failure
+     * authentication.
+     */
+    public boolean doAuthentication(String principalName,
+				    byte[] authData);
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BadRealmException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BadRealmException.java
new file mode 100644
index 0000000..cf68d5d
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BadRealmException.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+
+/**
+ * Exception thrown when a Realm is found to be corrupted for some reason.
+ * This usually reflects some sort of problem with data structures such
+ * as those holding information about users, groups, or ACLs.
+ *
+ * @author Harish Prabandham
+ */
+public class BadRealmException extends Exception
+{
+    /**
+     * Constructs the exception, with descriptive information.
+     *
+     * @param info describes the problem with the realm
+     */
+    public BadRealmException (String info) { super (info); }
+    
+    public BadRealmException() {
+        super();
+    }
+    
+    public BadRealmException(Throwable cause) {
+        super(cause);
+    }
+    
+    public BadRealmException(String info, Throwable cause) {
+        super(info, cause);
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BadUserException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BadUserException.java
new file mode 100644
index 0000000..5f2c55d
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BadUserException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+
+/**
+ * Exception thrown when a User is found to be corrupted for some reason.
+ * This is a special case of a realm data structure being corrupted.
+ *
+ * @author Harish Prabandham
+ */
+public class BadUserException extends BadRealmException
+{
+    /**
+     * Constructs the exception, with descriptive information.
+     *
+     * @param info describes the problem with the user
+     */
+    public BadUserException (String info) { super (info); }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupMapper.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupMapper.java
new file mode 100644
index 0000000..3961bf0
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupMapper.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ *
+ * @author Kumar
+ */
+public class GroupMapper {
+
+    private Map<String, ArrayList<String>> groupMappingTable = new HashMap<String, ArrayList<String>>();
+    
+    public void parse(String mappingStr) {
+        StringTokenizer tokenizer = new StringTokenizer(mappingStr, ";");
+        while(tokenizer.hasMoreElements()) {
+            String mapping = tokenizer.nextToken();
+            String[] mappingGroups = mapping.split(",");
+            String mappedGroup = null;
+            int indexOfArrow = mapping.indexOf("->");
+            if (indexOfArrow > 0 && mappingGroups != null && (mappingGroups.length > 0)) {
+                String tmpGroup = mapping.substring(indexOfArrow + 2);
+                mappedGroup = tmpGroup.trim();
+            }
+            validate(mappedGroup, mappingGroups);
+            for (String grp : mappingGroups) {
+                int aIndex = grp.indexOf("->");
+                String theGroup = null;
+                if (aIndex > 0) {
+                    String tGrp = grp.substring(0, aIndex);
+                    theGroup = tGrp.trim();
+                } else {
+                    theGroup = grp.trim();
+                }
+                ArrayList<String> mappedGroupList = groupMappingTable.get(theGroup);
+                if (mappedGroupList == null) {
+                    mappedGroupList = new ArrayList<String>();
+                }
+                mappedGroupList.add(mappedGroup);
+                groupMappingTable.put(theGroup, mappedGroupList);
+            }
+        }
+    }
+    
+    public void getMappedGroups(String group, ArrayList<String> result) {
+        if (result == null) {
+            throw new RuntimeException("result argument cannot be NULL");
+        }
+        ArrayList<String> mappedGrps = groupMappingTable.get(group);
+        if (mappedGrps == null || mappedGrps.isEmpty()) {
+            return;
+        }
+        addUnique(result,mappedGrps);
+        //look for transitive closure
+        ArrayList<String> result1 = new ArrayList<String>();
+        for (String str : mappedGrps) {
+            getMappedGroups(group, str,result1);
+        }
+        addUnique(result, result1);
+    }
+    
+    private void addUnique(ArrayList<String> dest, ArrayList<String> src) {
+        for (String str : src) {
+            if (!dest.contains(str)) {
+                dest.add(str);
+            }
+        }
+    }
+    /*
+    public void traverse() {
+        Iterator<String> it = groupMappingTable.keySet().iterator();
+        while(it.hasNext()) {
+            String key = it.next();
+            System.out.println();
+            System.out.print( key + "<<<Is Mapped to>>>");
+            ArrayList<String> list = new ArrayList<String>();
+            getMappedGroups(key, list);
+            if (list != null) {
+                for (String str : list) {
+                    System.out.print(str + ", ");
+                }
+            }
+            System.out.println();
+        }
+    }*/
+    /**
+     * @param args the command line arguments
+     
+    public static void main(String[] args) {
+        // TODO code application logic here
+        GroupMapper mapper = new GroupMapper();
+        mapper.parse(mappingStr);
+        mapper.traverse();
+    }*/
+
+    private void getMappedGroups(String group, String str, ArrayList<String> result) {
+       
+        ArrayList<String> mappedGrps = groupMappingTable.get(str);
+        if (mappedGrps == null || mappedGrps.isEmpty()) {
+            return;
+        }
+        if (mappedGrps.contains(group)) {
+            throw new RuntimeException("Illegal Mapping: cycle detected with group'" + group);
+        }
+        addUnique(result,mappedGrps);
+        for (String str1 : mappedGrps) {
+            getMappedGroups(group, str1,result);
+        }
+    }
+
+    private void validate(String mappedGroup, String[] mappingGroups) {
+        for (String str : mappingGroups) {
+            int aIndex = str.indexOf("->");
+            String theGroup = null;
+            if (aIndex > 0) {
+                theGroup = str.substring(0, aIndex);
+            } else {
+                theGroup = str;        
+            }
+            if (theGroup.equals(mappedGroup)) {
+                throw new RuntimeException("Illegal Mapping: Identity Mapping of group '" + theGroup + "' to '" + theGroup + "'");
+            }
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupNotEmptyException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupNotEmptyException.java
new file mode 100644
index 0000000..689863b
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupNotEmptyException.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+
+/**
+ * Exception thrown when an operation is requested to remove a group that has 
+ * a list of users.
+ *
+ * @author Harpreet Singh
+ */
+public class GroupNotEmptyException extends Exception
+{
+    /**
+     * Constructs the exception, with descriptive information.
+     *
+     * @param info describes the user which does not exist
+     */
+    public GroupNotEmptyException (String info) { super (info); }
+}
+
+
+
+
+
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/IASRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/IASRealm.java
new file mode 100644
index 0000000..c5e5133
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/IASRealm.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+import com.sun.enterprise.security.BaseRealm;
+
+
+/**
+ * Parent class for iAS Realm classes.
+ *
+ *  This class no longer implements the methods of Realm, instead it extends
+ *  from BaseRealm and now is only a place holder for migration and is a
+ *  candidate for deprecation.
+ *
+ */
+public abstract class IASRealm extends BaseRealm
+{
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/InvalidOperationException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/InvalidOperationException.java
new file mode 100644
index 0000000..d3749b9
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/InvalidOperationException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+
+/**
+ * Exception thrown when an operation is invoked on a realm that does not
+ * support it. 
+ * e.g. Invoking getGroups (username) is not supported by a certificate realm.
+ * @author Harpreet Singh
+ */
+public class InvalidOperationException extends Exception
+{
+    /**
+     * Constructs the exception, with descriptive information.
+     *
+     * @param info describes the problem with the realm
+     */
+    public InvalidOperationException (String info) { super (info); }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/LocalStrings.properties b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/LocalStrings.properties
new file mode 100644
index 0000000..4a8d207
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/LocalStrings.properties
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+realm.already_exists=This Realm already exists.
+realm.no_such_realm=Realm {0} does not exists.
+## Missing required property {0} for {JDBCRealm}.  
+realm.missingprop=Missing required property {0} for {1}.
+iasrealm.notsupported=Operation not supported.
+filerealm.nofile=Incomplete configuration in file realm: file not specified.
+filerealm.nomodule=Incomplete configuration in file realm: login module not specified.
+filerealm.nouser=No such user [{0}].
+filerealm.noaccess=Unable to create keyfile: {0}
+ldaprealm.badconfig=Incomplete configuration of ldap realm: url: {0} baseDN: {1} login module: {2}
+ldaprealm.badmode=Unsupported mode {0}.
+ldaprealm.usernotfound=User {0} not found.
+ldaprealm.bindfailed=LDAP bind failed for {0}.
+
+solarisrealm.nojaas=Solaris realm jaas-context not set.
+jdbcrealm.cantconnect=Unable to connect to datasource {0} for database user {1}.
+jdbcrealm.nodigestalg=Digest algorithm {0} is not supported.
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchRealmException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchRealmException.java
new file mode 100644
index 0000000..7498383
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchRealmException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+
+/**
+ * Exception thrown when an operation is requested on a realm which
+ * does not exist.
+ *
+ * @author Harish Prabandham
+ */
+public class NoSuchRealmException extends Exception
+{
+    /**
+     * Constructs the exception, with descriptive information.
+     *
+     * @param info describes the realm which does not exist
+     */
+    public NoSuchRealmException (String info) { super (info); }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchUserException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchUserException.java
new file mode 100644
index 0000000..7ddfcab
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchUserException.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+
+/**
+ * Exception thrown when an operation is requested on a user which
+ * does not exist.
+ *
+ * @author Harish Prabandham
+ */
+public class NoSuchUserException extends Exception
+{
+    /**
+     * Constructs the exception, with descriptive information.
+     *
+     * @param info describes the user which does not exist
+     */
+    public NoSuchUserException (String info) { super (info); }
+}
+
+
+
+
+
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java
new file mode 100644
index 0000000..a3446aa
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java
@@ -0,0 +1,876 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.security.util.IASSecurityException;
+import java.io.*;
+import java.util.*;
+import com.sun.enterprise.util.*;
+import java.lang.ref.WeakReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.glassfish.external.probe.provider.PluginPoint;
+import org.glassfish.external.probe.provider.StatsProviderManager;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.internal.api.ClassLoaderHierarchy;
+import org.glassfish.internal.api.Globals;
+import org.jvnet.hk2.annotations.Contract;
+
+/**
+ * javadoc
+ *
+ * @see java.security.Principal
+ *
+ * @author Harish Prabandham
+ * @author Harpreet Singh
+ * @author Jyri Virkki
+ * @author Shing Wai Chan
+ *
+ */
+@Contract
+public abstract class Realm implements Comparable {
+
+    private static LocalStringManagerImpl localStrings =
+	new LocalStringManagerImpl(Realm.class);
+
+//    private static Hashtable loadedRealms = new Hashtable();
+    private String myName;
+
+    // Keep track of name of default realm. This is updated during startup
+    // using value from server.xml
+//    private static String defaultRealmName="default";
+    
+    // Keep a mapping from "default" to default realm (if no such named
+    // realm is present) for the sake of all the hardcoded accesses to it.
+    // This needs to be removed as part of RI security service cleanup.
+    final static String RI_DEFAULT="default";
+
+    // All realms have a set of properties from config file, consolidate.
+    private Properties ctxProps;
+
+    // for assign-groups
+    private static final String PARAM_GROUPS = "assign-groups";
+    private static final String GROUPS_SEP = ",";
+    private List<String> assignGroups = null;
+    public static final String PARAM_GROUP_MAPPING="group-mapping";
+    protected GroupMapper groupMapper = null;
+    private static RealmStatsProvider realmStatsProvier = null;
+    private static final String DEFAULT_DIGEST_ALGORITHM = "default-digest-algorithm";
+    private static final String DEFAULT_DEF_DIG_ALGO_VAL = "SHA-256";
+
+    private static WeakReference<RealmsManager> realmsManager = new WeakReference<RealmsManager>(null);
+    private String defaultDigestAlgorithm = null;
+
+    protected static final Logger _logger = SecurityLoggerInfo.getLogger();
+
+    
+    /**
+     * Returns the name of this realm.
+     *
+     * @return realm name.
+     */
+    public final String	getName() { 
+	return myName; 
+    }
+
+    protected String getDefaultDigestAlgorithm() {
+        return defaultDigestAlgorithm;
+    }
+
+    
+    /**
+     * Assigns the name of this realm, and stores it in the cache
+     * of realms.  Used when initializing a newly created in-memory
+     * realm object; if the realm already has a name, there is no
+     * effect.
+     *
+     * @param name name to be assigned to this realm.
+     */
+    protected final void setName(String name) {
+	if (myName != null) {
+	    return;
+	}
+	myName = name;
+    }
+
+    
+    /**
+     * Returns the name of this realm.
+     *
+     * @return name of realm.
+     */
+    @Override
+    public String  toString() { 
+	return myName; 
+    }
+
+    
+    /**
+     * Compares a realm to another.  The comparison first considers the
+     * authentication type, so that realms supporting the same kind of
+     * user authentication are grouped together.  Then it compares realm
+     * realm names.  Realms compare "before" other kinds of objects (i.e.
+     * there's only a partial order defined, in the case that those other
+     * objects compare themselves "before" a realm object).
+     */
+    public int compareTo (Object realm) {
+	if (!(realm instanceof Realm)) {
+	    return 1;
+	}
+	
+	Realm 	r = (Realm) realm;
+	String	str = r.getAuthType ();
+	int	temp;
+	
+	if ((temp = getAuthType ().compareTo (str)) != 0) {
+	    return temp;
+	}
+
+	str = r.getName ();
+	return getName ().compareTo (str);
+    }
+
+
+    /**
+     * Instantiate a Realm with the given name and properties using the
+     * Class name given. This method is used by iAS and not RI.
+     *
+     * @param name Name of the new realm.
+     * @param className Java Class name of the realm to create.
+     * @param props Properties containing values of the Property element
+     *     from server.xml
+     * @returns Reference to the new Realm. The Realm class keeps an internal
+     *     list of all instantiated realms.
+     * @throws BadRealmException If the requested realm cannot be instantiated.
+     *
+     */
+    public static synchronized Realm instantiate(String name, String className,
+                                    Properties props)
+        throws BadRealmException
+    {
+        //Register the realm provider
+        registerRealmStatsProvier();
+        
+        Realm realmClass = _getInstance(name);
+        if(realmClass == null) {
+            realmClass = doInstantiate(name, className, props);
+            RealmsManager mgr = getRealmsManager();
+            mgr.putIntoLoadedRealms(name, realmClass);
+        }
+        return realmClass;
+    }
+
+    /**
+     * Instantiate a Realm with the given name and properties using the
+     * Class name given. This method is used by iAS and not RI.
+     *
+     * @param name Name of the new realm.
+     * @param className Java Class name of the realm to create.
+     * @param props Properties containing values of the Property element
+     *     from server.xml
+     * @param configName the config to which this realm belongs
+     * @returns Reference to the new Realm. The Realm class keeps an internal
+     *     list of all instantiated realms.
+     * @throws BadRealmException If the requested realm cannot be instantiated.
+     *
+     */
+    public static synchronized Realm instantiate(String name, String className,
+                                    Properties props, String configName)
+        throws BadRealmException
+    {
+        //Register the realm provider
+        registerRealmStatsProvier();
+
+        Realm realmClass = _getInstance(configName, name);
+        if(realmClass == null) {
+            realmClass = doInstantiate(name, className, props);
+            RealmsManager mgr = getRealmsManager();
+            mgr.putIntoLoadedRealms(configName, name, realmClass);
+        }
+        return realmClass;
+
+    }
+
+    private static void registerRealmStatsProvier() {
+        if (realmStatsProvier == null) {
+            getRealmStatsProvier();
+            StatsProviderManager.register("security", PluginPoint.SERVER, "security/realm", realmStatsProvier);
+        }
+    }
+
+    public static synchronized void getRealmStatsProvier(){
+        if(realmStatsProvier == null){
+            realmStatsProvier = new RealmStatsProvider();
+        }
+    }
+
+    /**
+     * Instantiate a Realm with the given name, loading properties from
+     * the given file. This method is only used by RI and is not called
+     * anywhere in iAS.
+     * Note : this method stands unused in V3.1 but keeping it since it is a 
+     * public method.
+     * @deprecated
+     * @param realmName Name of the new realm.
+     * @param f File containing Properties for the new realm.
+     */
+    public static synchronized Realm instantiate(String realmName, File f)
+    throws NoSuchRealmException, BadRealmException, FileNotFoundException
+    {
+
+
+        if (!f.exists() || !f.isFile()) {
+            throw new FileNotFoundException ();
+        }
+        
+        if(_getInstance(realmName) != null) {
+            throw new BadRealmException(
+                localStrings.getLocalString("realm.already_exists", 
+                                            "This Realm already exists."));
+        } 
+        
+        //
+        // First load the description from properties.
+        //
+        InputStream in = null;
+        Properties  props = new Properties();
+        
+        try{    
+            in = new FileInputStream(f);
+            props.load(in);
+            //
+            // Then instantiate and initialize, using the single mandatory
+            // property ("classname").
+            //
+            String classname = props.getProperty("classname");
+            assert (classname != null);
+
+            return doInstantiate(realmName, classname, props);
+        } catch (IOException e) {
+            throw new BadRealmException(e.toString());
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch(Exception ex) {
+                }
+            }
+        }
+    }
+
+    
+    /**
+     * Instantiates a Realm class of the given type and invokes its init()
+     *
+     */
+    private static synchronized Realm doInstantiate(String name, String className,
+                                       Properties props)
+        throws BadRealmException
+    {
+        
+        ServiceLocator habitat = Globals.getDefaultHabitat();
+        RealmsManager mgr = null;
+        try {
+            mgr = getRealmsManager();
+            Class realmClass = null;
+            //try a HK2 route first
+            Realm r = habitat.getService(Realm.class, name);
+            if (r == null) {
+                try {
+                    //TODO: workaround here. Once fixed in V3 we should be able to use
+                    //Context ClassLoader instead.
+                    ClassLoaderHierarchy hierarchy =
+                            habitat.getService(ClassLoaderHierarchy.class);
+                    realmClass = hierarchy.getCommonClassLoader().loadClass(className);
+                    Object obj = realmClass.newInstance();
+                    r = (Realm) obj;
+                } catch (ClassNotFoundException ex) {
+                    realmClass = Class.forName(className);
+                    Object obj = realmClass.newInstance();
+                    r = (Realm) obj;
+                }
+            }
+
+            r.setName(name);
+            r.init(props);
+            if (mgr == null) {
+                throw new BadRealmException("Unable to locate RealmsManager Service");
+            }
+            _logger.log(Level.INFO, SecurityLoggerInfo.realmCreated ,new Object[]{name, className});
+            return r;
+
+
+        } catch (NoSuchRealmException ex) {
+            throw new BadRealmException(ex);
+        } catch (InstantiationException ex) {
+            throw new BadRealmException(ex);
+        } catch (IllegalAccessException ex) {
+            throw new BadRealmException(ex);
+        } catch (ClassNotFoundException ex) {
+            throw new BadRealmException(ex);
+        }
+    }
+
+
+    /**
+     * Replace a Realm instance. Can be used by a Realm subclass to
+     * replace a previously initialized instance of itself. Future
+     * getInstance requests will then obtain the new instance.
+     *
+     * <P>Minimal error checking is done. The realm being replaced must
+     * already exist (instantiate() was previously called), the new
+     * instance must be fully initialized properly and it must of course
+     * be of the same class as the previous instance.
+     *
+     * @param realm The new realm instance.
+     * @param name The (previously instantiated) name for this realm.
+     *
+     */
+    protected static synchronized void updateInstance(Realm realm, String name)
+    {
+        RealmsManager mgr = getRealmsManager();
+        if (mgr == null) {
+             throw new RuntimeException("Unable to locate RealmsManager Service");
+        }
+        
+        Realm oldRealm = mgr.getFromLoadedRealms(name);
+        if (!oldRealm.getClass().equals(realm.getClass())) {
+            // would never happen unless bug in realm subclass
+            throw new Error("Incompatible class "+realm.getClass()+
+                            " in replacement realm "+name);
+        }
+        realm.setName(oldRealm.getName());
+        mgr.putIntoLoadedRealms(name, realm);
+        _logger.log(Level.INFO, SecurityLoggerInfo.realmUpdated, new Object[]{realm.getName()});
+    }
+
+    /**
+     * Replace a Realm instance. Can be used by a Realm subclass to
+     * replace a previously initialized instance of itself. Future
+     * getInstance requests will then obtain the new instance.
+     *
+     * <P>Minimal error checking is done. The realm being replaced must
+     * already exist (instantiate() was previously called), the new
+     * instance must be fully initialized properly and it must of course
+     * be of the same class as the previous instance.
+     *
+     * @param realm The new realm instance.
+     * @param name The (previously instantiated) name for this realm.
+     *
+     */
+    protected static synchronized void updateInstance(String configName, Realm realm, String name) {
+        RealmsManager mgr = getRealmsManager();
+        if (mgr == null) {
+            throw new RuntimeException("Unable to locate RealmsManager Service");
+        }
+
+        Realm oldRealm = mgr.getFromLoadedRealms(configName, name);
+        if (!oldRealm.getClass().equals(realm.getClass())) {
+            // would never happen unless bug in realm subclass
+            throw new Error("Incompatible class " + realm.getClass()
+                    + " in replacement realm " + name);
+        }
+        realm.setName(oldRealm.getName());
+        mgr.putIntoLoadedRealms(configName, name, realm);
+        _logger.log(Level.INFO, SecurityLoggerInfo.realmUpdated, new Object[]{realm.getName()});
+    }
+
+    
+    /**
+     * Convenience method which returns the Realm object representing
+     * the current default realm. Equivalent to
+     * getInstance(getDefaultRealm()).
+     * 
+     * @return Realm representing default realm.
+     * @exception NoSuchRealmException if default realm does not exist
+     */
+    public static synchronized Realm getDefaultInstance() throws NoSuchRealmException
+    {
+        return getInstance(getDefaultRealm());
+    }
+
+    
+    /**
+     * Returns the name of the default realm.
+     *
+     * @return Default realm name.
+     *
+     */
+    public static synchronized String getDefaultRealm() {
+        RealmsManager mgr = getRealmsManager();
+        if (mgr != null) {
+            return mgr.getDefaultRealmName();
+        } else {
+            throw new RuntimeException("Unable to locate RealmsManager Service");
+        }
+    }
+
+    
+    /**
+     * Sets the name of the default realm.
+     *
+     * @param realmName Name of realm to set as default.
+     *
+     */
+    public static synchronized void setDefaultRealm(String realmName) {
+        //defaultRealmName = realmName;
+        RealmsManager mgr = getRealmsManager();
+        if (mgr != null) {
+             mgr.setDefaultRealmName(realmName);
+        } else  {
+           throw new RuntimeException("Unable to locate RealmsManager Service");
+        }
+    }
+
+    /**
+     * Remove realm with given name from cache.
+     * @param realmName
+     * @exception NoSuchRealmException
+     */
+    public static synchronized void unloadInstance(String realmName) throws NoSuchRealmException {
+        //make sure instance exist
+        getInstance(realmName);
+        RealmsManager mgr = getRealmsManager();
+        if (mgr != null) {
+             mgr.removeFromLoadedRealms(realmName);
+        } else {
+           throw new RuntimeException("Unable to locate RealmsManager Service");
+        }
+        _logger.log(Level.INFO, SecurityLoggerInfo.realmDeleted, realmName);
+    }
+
+     /**
+     * Remove realm with given name from cache.
+     * @param realmName
+     * @exception NoSuchRealmException
+     */
+    public static synchronized void unloadInstance(String configName, String realmName) throws NoSuchRealmException {
+        //make sure instance exist
+        //getInstance(configName, realmName);
+        RealmsManager mgr = getRealmsManager();
+        if (mgr != null) {
+             mgr.removeFromLoadedRealms(configName, realmName);
+        } else {
+           throw new RuntimeException("Unable to locate RealmsManager Service");
+        }
+        _logger.log(Level.INFO, SecurityLoggerInfo.realmDeleted, realmName);
+    }
+
+
+
+    /**
+     * Set a realm property.
+     *
+     * @param name property name.
+     * @param value property value.
+     *
+     */
+    public synchronized void setProperty(String name, String value)
+    {
+        ctxProps.setProperty(name, value);
+    }
+
+
+    /**
+     * Get a realm property.
+     *
+     * @param name property name.
+     * @returns value.
+     *
+     */
+    public synchronized String getProperty(String name)
+    {
+        return ctxProps.getProperty(name);
+    }
+
+    /**
+     * Return properties of the realm.
+     */
+    protected synchronized Properties getProperties() {
+        return ctxProps;
+    }
+
+
+    /**
+     * Returns name of JAAS context used by this realm.
+     *
+     * <P>The JAAS context is defined in server.xml auth-realm element
+     * associated with this realm. 
+     *
+     * @return String containing JAAS context name.
+     *
+     */
+    public synchronized String getJAASContext()
+    {
+        return ctxProps.getProperty(IASRealm.JAAS_CONTEXT_PARAM);
+    }
+    
+    
+    /**
+     * Returns the realm identified by the name which is passed
+     * as a parameter.  This function knows about all the realms
+     * which exist; it is not possible to store (or create) one
+     * which is not accessible through this routine.
+     *
+     * @param name identifies the realm
+     * @return the requested realm
+     * @exception NoSuchRealmException if the realm is invalid
+     * @exception BadRealmException if realm data structures are bad
+     */
+    public static synchronized Realm	getInstance(String name) throws NoSuchRealmException
+    {
+	Realm retval = _getInstance(name);
+
+        if (retval == null) {
+            throw new NoSuchRealmException(
+                localStrings.getLocalString("realm.no_such_realm", 
+                name + " realm does not exist.",
+                new Object[] { name }));
+        }
+     
+	return retval;
+    }
+
+    /**
+     * Returns the realm identified by the name which is passed
+     * as a parameter.  This function knows about all the realms
+     * which exist; it is not possible to store (or create) one
+     * which is not accessible through this routine.
+     *
+     * @param name identifies the realm
+     * @return the requested realm
+     * @exception NoSuchRealmException if the realm is invalid
+     * @exception BadRealmException if realm data structures are bad
+     */
+    public static synchronized Realm getInstance(String configName, String name) throws NoSuchRealmException
+    {
+	Realm retval = _getInstance(configName, name);
+
+        if (retval == null) {
+            throw new NoSuchRealmException(
+                localStrings.getLocalString("realm.no_such_realm",
+                name + " realm does not exist.",
+                new Object[] { name }));
+        }
+
+	return retval;
+    }
+    
+    /**
+     * This is a private method for getting realm instance.
+     * If realm does not exist, then it will not return null rather than 
+     * throw exception.
+     * @param name identifies the realm
+     * @return the requested realm
+     */
+    private static synchronized Realm _getInstance(String name) {
+        RealmsManager mgr = getRealmsManager();
+        if (mgr != null) {
+            return mgr._getInstance(name);
+        } else  {
+           throw new RuntimeException("Unable to locate RealmsManager Service");
+        }
+    }
+
+    /**
+     * This is a private method for getting realm instance.
+     * If realm does not exist, then it will not return null rather than
+     * throw exception.
+     * @param name identifies the realm
+     * @return the requested realm
+     */
+    private static synchronized Realm _getInstance(String configName, String name) {
+        RealmsManager mgr = getRealmsManager();
+        if (mgr != null) {
+            return mgr._getInstance(configName, name);
+        } else  {
+           throw new RuntimeException("Unable to locate RealmsManager Service");
+        }
+    }
+    
+
+    /**
+     * Returns the names of accessible realms.
+     * @return set of realm names
+     */
+    public static synchronized Enumeration	getRealmNames() {
+        RealmsManager mgr = getRealmsManager();
+        if (mgr != null) {
+            return mgr.getRealmNames();
+        }
+        throw new RuntimeException("Unable to locate RealmsManager Service");
+    }
+
+
+    /**
+     * The default constructor creates a realm which will later
+     * be initialized, either from properties or by deserializing.
+     */
+    protected Realm() {
+        ctxProps = new Properties();
+    }
+
+
+    /**
+     * Initialize a realm with some properties.  This can be used
+     * when instantiating realms from their descriptions.  This
+     * method may only be called a single time.  
+     *
+     * @param props initialization parameters used by this realm.
+     * @exception BadRealmException if the configuration parameters
+     *	identify a corrupt realm
+     * @exception NoSuchRealmException if the configuration parameters
+     *	specify a realm which doesn't exist
+     */
+    protected void init(Properties props)
+            throws BadRealmException, NoSuchRealmException {
+        String groupList = props.getProperty(PARAM_GROUPS);
+        if (groupList != null && groupList.length() > 0) {
+            this.setProperty(PARAM_GROUPS, groupList);
+            assignGroups = new ArrayList<String>();
+            StringTokenizer st = new StringTokenizer(groupList, GROUPS_SEP);
+            while (st.hasMoreTokens()) {
+                String grp = (String)st.nextToken();
+                if (!assignGroups.contains(grp)) {
+                    assignGroups.add(grp);
+                }
+            }
+        }
+        String groupMapping = props.getProperty(PARAM_GROUP_MAPPING);
+        if (groupMapping != null) {
+            groupMapper = new GroupMapper();
+            groupMapper.parse(groupMapping);
+        }
+        String defaultDigestAlgo = null;
+        if(_getRealmsManager() != null) {
+            defaultDigestAlgo = _getRealmsManager().getDefaultDigestAlgorithm();
+        }       
+       this.defaultDigestAlgorithm = (defaultDigestAlgo == null)?DEFAULT_DEF_DIG_ALGO_VAL:defaultDigestAlgo;       
+    }
+
+    private static synchronized  RealmsManager _getRealmsManager() {
+        if (realmsManager.get() == null) {
+            if(Globals.getDefaultHabitat() != null) {
+                realmsManager = new WeakReference<RealmsManager>(Globals.get(RealmsManager.class));
+            }
+            else {
+                return null;
+            }
+        }
+        return realmsManager.get();
+    }
+
+    private static RealmsManager getRealmsManager() {
+        if (realmsManager.get() != null) {
+            return realmsManager.get();
+        }
+        return _getRealmsManager();
+     }
+    /**
+     * Checks if the given realm name is loaded/valid.
+     * @param String name of the realm to check.
+     * @return true if realm present, false otherwise.
+     */
+    public static boolean isValidRealm(String name) {
+        RealmsManager mgr = getRealmsManager();
+        if (mgr != null) {
+            return mgr.isValidRealm(name);
+        }
+        throw new RuntimeException("Unable to locate RealmsManager Service");
+    }
+
+    /**
+     * Checks if the given realm name is loaded/valid.
+     * @param String name of the realm to check.
+     * @return true if realm present, false otherwise.
+     */
+    public static boolean isValidRealm(String configName, String name) {
+        RealmsManager mgr = getRealmsManager();
+        if (mgr != null) {
+            return mgr.isValidRealm(configName, name);
+        }
+        throw new RuntimeException("Unable to locate RealmsManager Service");
+    }
+
+    /**
+     * Add assign groups to given Vector of groups.
+     * To be used by getGroupNames.
+     * @param grps
+     */
+    protected String[] addAssignGroups(String[] grps) {
+        String[] resultGroups = grps;
+        if (assignGroups != null && assignGroups.size() > 0) {
+            List<String> groupList = new ArrayList<String>();
+            if (grps != null &&  grps.length > 0) {
+                for (String grp : grps) {
+                    groupList.add(grp);
+                }
+            }
+            
+            for (String agrp : assignGroups) {
+                if (!groupList.contains(agrp)) {
+                    groupList.add(agrp);
+                }
+            }
+            resultGroups = groupList.toArray(new String[groupList.size()]);
+        }
+        return resultGroups;
+    }
+    
+    protected ArrayList<String> getMappedGroupNames(String group) {
+        if (groupMapper != null) {
+            ArrayList<String> result = new ArrayList<String>();
+            groupMapper.getMappedGroups(group, result);
+            return result;
+        }
+        return null;
+    }
+    
+    //---[ Abstract methods ]------------------------------------------------
+
+    
+    /**
+     * Returns a short (preferably less than fifteen characters) description
+     * of the kind of authentication which is supported by this realm.
+     *
+     * @return description of the kind of authentication that is directly
+     *	supported by this realm.
+     */
+    public abstract String getAuthType ();
+
+    /**
+     * Returns an AuthenticationHandler object which can be used to 
+     * authenticate within this realm.
+     *
+     * @return An AuthenticationHandler object for this realm.
+     */
+    public abstract AuthenticationHandler getAuthenticationHandler ();
+
+    /**
+     * Returns names of all the users in this particular realm.
+     *
+     * @return enumeration of user names (strings)
+     * @exception BadRealmException if realm data structures are bad
+     */
+    public abstract Enumeration	getUserNames() throws BadRealmException;
+
+    /**
+     * Returns the information recorded about a particular named user.
+     *
+     * @param name name of the user whose information is desired
+     * @return the user object
+     * @exception NoSuchUserException if the user doesn't exist
+     * @exception BadRealmException if realm data structures are bad
+     */
+    public abstract User getUser(String name)
+	throws NoSuchUserException, BadRealmException;
+
+    /**
+     * Returns names of all the groups in this particular realm.
+     *
+     * @return enumeration of group names (strings)
+     * @exception BadRealmException if realm data structures are bad
+     */
+    public abstract Enumeration	getGroupNames()
+	throws BadRealmException;
+
+    /**
+     * Returns the name of all the groups that this user belongs to
+     * @param username name of the user in this realm whose group listing
+     * is needed.
+     * @return enumeration of group names (strings)
+     * @exception InvalidOperationException thrown if the realm does not
+     * support this operation - e.g. Certificate realm does not support this
+     * operation
+     */
+    public abstract Enumeration getGroupNames (String username)
+	throws InvalidOperationException, NoSuchUserException;
+    
+    /**
+     * Refreshes the realm data so that new users/groups are visible.
+     *
+     * @exception BadRealmException if realm data structures are bad
+     */
+    public abstract void  refresh() throws BadRealmException;
+
+    /**
+     * Refreshes the realm data so that new users/groups are visible.
+     *
+     * @exception BadRealmException if realm data structures are bad
+     */
+    public void refresh(String configName) throws BadRealmException {
+        //do nothing
+    }
+    
+    /**
+     * Adds new user to file realm. User cannot exist already.
+     *
+     * @param name User name.
+     * @param password Cleartext password for the user.
+     * @param groupList List of groups to which user belongs.
+     * @throws BadRealmException If there are problems adding user.
+     *
+     */
+    public abstract void addUser(String name, char[] password, String[] groupList)
+        throws BadRealmException, IASSecurityException;
+    
+    /**
+     * Remove user from file realm. User must exist.
+     *
+     * @param name User name.
+     * @throws NoSuchUserException If user does not exist.
+     *
+     */
+     public abstract void removeUser(String name)
+        throws NoSuchUserException, BadRealmException;
+     
+     /**
+     * Update data for an existing user. User must exist.
+     *
+     * @param name Current name of the user to update.
+     * @param newName New name to give this user. It can be the same as
+     *     the original name. Otherwise it must be a new user name which
+     *     does not already exist as a user.
+     * @param password Cleartext password for the user. If non-null the user
+     *     password is changed to this value. If null, the original password
+     *     is retained.
+     * @param groupList List of groups to which user belongs.
+     * @throws BadRealmException If there are problems adding user.
+     * @throws NoSuchUserException If user does not exist.
+     *
+     */
+    public abstract void updateUser(String name, String newName, char[] password,
+                           String[] groups)
+        throws NoSuchUserException, BadRealmException,
+                               IASSecurityException;
+    /**
+     * @return true if the realm implementation support User Management (add,remove,update user)
+     */
+    public abstract boolean supportsUserManagement();
+    
+   /**
+    * Persist the realm data to permanent storage
+    * @throws com.sun.enterprise.security.auth.realm.BadRealmException
+    */
+    public abstract void persist() throws BadRealmException;
+}
+
+
+
+
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmConfig.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmConfig.java
new file mode 100644
index 0000000..f4f3269
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmConfig.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.security.SecurityLoggerInfo;
+
+import org.jvnet.hk2.config.types.Property;
+import java.util.List;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * RealmConfig usable by standalone : Admin CLI for creating Realms
+ * It has a subset of functionality defined in com.sun.enterprise.security.RealmConfig
+ */
+public class RealmConfig {
+
+    private static Logger logger =
+            SecurityLoggerInfo.getLogger();
+
+    public static void createRealms(String defaultRealm, List<AuthRealm> realms) {
+        createRealms(defaultRealm, realms, null);
+    }
+    public static void createRealms(String defaultRealm, List<AuthRealm> realms, String configName) {
+        assert(realms != null);
+
+        String goodRealm = null; // need at least one good realm
+
+        for (AuthRealm aRealm : realms) {
+            String realmName = aRealm.getName();
+            String realmClass = aRealm.getClassname();
+            assert (realmName != null);
+            assert (realmClass != null);
+
+            try {
+                List<Property> realmProps = aRealm.getProperty();
+                /*V3 Commented ElementProperty[] realmProps =
+                    aRealm.getElementProperty();*/
+                Properties props = new Properties();
+                for (Property realmProp : realmProps) {
+                    props.setProperty(realmProp.getName(), realmProp.getValue());
+                }
+                Realm.instantiate(realmName, realmClass, props, configName);
+                if (logger.isLoggable(Level.FINE)) {
+                    logger.fine("Configured realm: " + realmName);
+                }
+
+                if (goodRealm == null) {
+                    goodRealm = realmName;
+                }
+            } catch (Exception e) {
+                logger.log(Level.WARNING,
+                           SecurityLoggerInfo.realmConfigDisabledError, realmName);
+                logger.log(Level.WARNING, SecurityLoggerInfo.securityExceptionError, e);
+            }
+        }
+
+        // done loading all realms, check that there is at least one
+        // in place and that default is installed, or change default
+        // to the first one loaded (arbitrarily).
+
+        if (goodRealm == null) {
+            logger.severe(SecurityLoggerInfo.noRealmsError);
+
+        } else {
+            try {
+                Realm.getInstance(defaultRealm);
+            } catch (Exception e) {
+                defaultRealm = goodRealm;
+            }
+            Realm.setDefaultRealm(defaultRealm);
+            if (logger.isLoggable(Level.FINE)) {
+                logger.fine("Default realm is set to: " + defaultRealm);
+            }
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmStatsProvider.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmStatsProvider.java
new file mode 100644
index 0000000..75e1220
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmStatsProvider.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+import org.glassfish.external.statistics.CountStatistic;
+import org.glassfish.external.statistics.impl.CountStatisticImpl;
+import org.glassfish.external.probe.provider.annotations.ProbeListener;
+import org.glassfish.external.probe.provider.annotations.ProbeParam;
+
+
+import org.glassfish.gmbal.*;
+/**
+ *
+ * @author nithyasubramanian
+ */
+@AMXMetadata(type="security-realm-mon", group="monitoring", isSingleton=false)
+@ManagedObject
+@Description( "Security Realm Statistics" )
+public class RealmStatsProvider {
+
+    private CountStatisticImpl realmCount;
+    
+    
+    public RealmStatsProvider() {
+        realmCount = new CountStatisticImpl("RealmCount", "realm","No of Realms");
+    }
+
+    @ManagedAttribute
+    @Description( "Security Realm Count" )
+    public CountStatistic getRealmCount() {
+        return realmCount;
+    }
+    
+    @ProbeListener("glassfish:security:realm:realmAddedEvent")
+    public void realmAddedEvent(@ProbeParam("realmName")String realmName){
+       realmCount.increment();
+    }
+    
+   @ProbeListener("glassfish:security:realm:realmRemovedEvent")
+    public void realmRemovedEvent(@ProbeParam("realmName")String realmName){
+       realmCount.decrement();
+    }
+   
+    
+    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmsManager.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmsManager.java
new file mode 100644
index 0000000..4fef3a4
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmsManager.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.hk2.api.ActiveDescriptor;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.hk2.utilities.BuilderHelper;
+import org.glassfish.internal.api.Globals;
+import org.jvnet.hk2.annotations.Service;
+import org.jvnet.hk2.config.types.Property;
+
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.security.SecurityLoggerInfo;
+
+/**
+ *
+ * @author kumar.jayanti
+ */
+@Service
+@Singleton
+public class RealmsManager {
+    //per domain list of loaded Realms
+    //Wanted to get rid of Hashtable but the API exporting  Enumeration<String> is preventing
+    // it for now.
+    private final Map<String, Hashtable<String, Realm>> loadedRealms = 
+            Collections.synchronizedMap(new HashMap<String, Hashtable<String, Realm>>());
+
+    // Keep track of name of default realm for this domain. This is updated during startup
+    // using value from server.xml
+    private volatile String defaultRealmName="default";
+    private final RealmsProbeProvider probeProvider = new RealmsProbeProvider();
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+    
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    private String defaultDigestAlgorithm = null;
+
+    private static final String DEFAULT_DIGEST_ALGORITHM = "default-digest-algorithm";
+
+
+    public RealmsManager() {
+        
+    }
+    /**
+     * Checks if the given realm name is loaded/valid.
+     * @param name of the realm to check.
+     * @return true if realm present, false otherwise.
+     */
+    public  boolean isValidRealm(String name){
+        if(name == null){
+            return false;
+        } else {
+            return configContainsRealm(name, config.getName());
+        }
+    }
+
+    /**
+     * Checks if the given realm name is loaded/valid.
+     * @param name of the realm to check.
+     * @return true if realm present, false otherwise.
+     */
+    public  boolean isValidRealm(String configName, String name){
+        if(name == null){
+            return false;
+        } else {
+            return configContainsRealm(name, configName);
+        }
+    }
+    
+    /**
+     * Returns the names of accessible realms.
+     * @return set of realm names
+     */
+    public  Enumeration<String>	getRealmNames() {
+	return getRealmNames(config.getName());
+    }
+
+    Realm _getInstance(String configName, String name) {
+	Realm retval = null;
+	retval = configGetRealmInstance(configName, name);
+
+        // Some tools as well as numerous other locations assume that
+        // getInstance("default") always works; keep them from breaking
+        // until code can be properly cleaned up. 4628429
+
+        // Also note that for example the appcontainer will actually create
+        // a Subject always containing realm='default' so this notion
+        // needs to be fixed/handled.
+        if ( (retval == null) && (Realm.RI_DEFAULT.equals(name)) ) {
+            retval = configGetRealmInstance(configName,getDefaultRealmName());
+        }
+
+        return retval;
+    }
+
+    Realm _getInstance(String name) {
+        return _getInstance(config.getName(), name);
+    }
+
+    public void removeFromLoadedRealms(String realmName) {
+        Realm r = removeFromLoadedRealms(config.getName(), realmName);
+        if (r != null) {
+            probeProvider.realmRemovedEvent(realmName);
+        }
+    }
+
+    void putIntoLoadedRealms(String realmName, Realm realm) {
+        putIntoLoadedRealms(config.getName(), realmName, realm);
+        probeProvider.realmAddedEvent(realmName);
+    }
+    
+    public Realm getFromLoadedRealms(String realmName) {
+        return configGetRealmInstance(config.getName(),realmName);
+    }
+
+    public Realm getFromLoadedRealms(String configName, String realmName) {
+        return configGetRealmInstance(configName,realmName);
+    }
+
+    public synchronized String getDefaultRealmName() {
+        return defaultRealmName;
+    }
+
+    public synchronized void setDefaultRealmName(String defaultRealmName) {
+        this.defaultRealmName = defaultRealmName;
+    }
+    
+   /**
+    * Returns names of predefined AuthRealms' classes supported by security service.
+    * @returns array of predefind AuthRealms' classes
+    *
+    */
+   public  List<String> getPredefinedAuthRealmClassNames()
+   {
+       //!!!!!!!!!!!! (hardcoded for now until ss will implement backemnd support)
+      /* return new String[]{
+               "com.sun.enterprise.security.auth.realm.file.FileRealm",
+               "com.sun.enterprise.security.auth.realm.certificate.CertificateRealm",
+               "com.sun.enterprise.security.auth.realm.ldap.LDAPRealm",
+               "com.sun.enterprise.security.ee.auth.realm.jdbc.JDBCRealm",
+               "com.sun.enterprise.security.auth.realm.solaris.SolarisRealm"};*/
+       ServiceLocator habitat = Globals.getDefaultHabitat();
+       List<ActiveDescriptor<?>> collection = habitat.getDescriptors(
+               BuilderHelper.createContractFilter(Realm.class.getName()));
+       List<String> arr = new ArrayList<String>();
+       for (ActiveDescriptor<?> it : collection) {
+           arr.add(it.getImplementation());
+       }
+      
+       return arr;   
+   }
+
+   public void createRealms() {
+       createRealms(config.getSecurityService(), config);
+   }
+
+   public void createRealms(Config cfg) {
+       if (cfg == null) {
+           return;
+       }
+       createRealms(cfg.getSecurityService(), cfg);
+   }
+
+   private void setDefaultDigestAlgorithm() {
+       SecurityService service = config.getSecurityService();
+       if(service == null) {
+           return;
+       }
+       List<Property> props = service.getProperty();
+       if(props == null) {
+           return;
+       }  
+       Iterator<Property> propsIterator = props.iterator();
+       while(propsIterator != null && propsIterator.hasNext()) {
+           Property prop = propsIterator.next();
+           if(prop != null && DEFAULT_DIGEST_ALGORITHM.equals(prop.getName())) {
+               this.defaultDigestAlgorithm = prop.getValue();
+               break;
+           }
+       }     
+   }
+
+   public String getDefaultDigestAlgorithm() {
+       return defaultDigestAlgorithm;
+   }
+
+   /**
+     * Load all configured realms from server.xml and initialize each
+     * one.  Initialization is done by calling Realm.initialize() with
+     * its name, class and properties.  The name of the default realm
+     * is also saved in the Realm class for reference during server
+     * operation.
+     *
+     * <P>This method superceeds the RI RealmManager.createRealms() method.
+     *
+     * */
+    private void createRealms(SecurityService securityBean, Config cfg) {
+        //check if realms are already loaded by admin GUI ?
+        if (realmsAlreadyLoaded(cfg.getName())) {
+            return;
+        }
+
+        setDefaultDigestAlgorithm();
+        try {
+            if (_logger.isLoggable(Level.FINE)) {
+                _logger.fine("Initializing configured realms from SecurityService in Domain.xml....");
+            }
+
+            if (securityBean == null) {
+                securityBean = cfg.getSecurityService();
+                assert (securityBean != null);
+            }
+
+            // grab default realm name
+            String defaultRealm = securityBean.getDefaultRealm();
+
+            // get set of auth-realms and process each
+            List<AuthRealm> realms = securityBean.getAuthRealm();
+            assert (realms != null);
+
+            RealmConfig.createRealms(defaultRealm, realms, cfg.getName());
+
+        } catch (Exception e) {
+            _logger.log(Level.SEVERE, SecurityLoggerInfo.noRealmsError, e);
+        }
+    }
+
+    private boolean realmsAlreadyLoaded(String cfgName) {
+        Enumeration<String> en = getRealmNames(cfgName);
+        return (en != null && en.hasMoreElements()) ? true : false;
+    }
+
+    private boolean configContainsRealm(String name, String configName) {
+        Hashtable<String, Realm> containedRealms = loadedRealms.get(configName);
+        return (containedRealms != null) ? containedRealms.containsKey(name) : false;
+    }
+
+    private Enumeration<String> getRealmNames(String configName) {
+        Hashtable<String, Realm> containedRealms = loadedRealms.get(configName);
+        return (containedRealms != null) ? containedRealms.keys() : null;
+    }
+
+    private Realm configGetRealmInstance(String configName, String realm) {
+        Hashtable<String, Realm> containedRealms = loadedRealms.get(configName);
+	return  (containedRealms != null) ? (Realm) containedRealms.get(realm) : null;
+    }
+
+    public Realm removeFromLoadedRealms (String configName, String realmName) {
+         Hashtable<String, Realm> containedRealms = loadedRealms.get(configName);
+         return (containedRealms != null) ?(Realm)containedRealms.remove(realmName) : null;
+    }
+
+    public void putIntoLoadedRealms (String configName, String realmName, Realm realm) {
+         Hashtable<String, Realm> containedRealms = loadedRealms.get(configName);
+         if (containedRealms == null) {
+             containedRealms = new Hashtable<String, Realm>();
+             if (configName == null) {
+                 configName = config.getName();
+             }
+             loadedRealms.put(configName, containedRealms);
+         }
+         containedRealms.put(realmName, realm);
+    }
+    
+    public void refreshRealm(String configName, String realmName) {
+        if (realmName != null && realmName.length() > 0) {
+            try {
+                Realm realm = Realm.getInstance(configName, realmName);
+
+                if (realm != null) {
+                    realm.refresh(configName);
+                }
+            } catch (com.sun.enterprise.security.auth.realm.NoSuchRealmException nre) {
+                //	    _logger.fine("Realm: "+realmName+" is not configured");
+            } catch (com.sun.enterprise.security.auth.realm.BadRealmException bre) {
+                //	    _logger.fine("Realm: "+realmName+" is not configured");
+            }
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmsProbeProvider.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmsProbeProvider.java
new file mode 100644
index 0000000..8a60005
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmsProbeProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+import org.glassfish.external.probe.provider.annotations.ProbeProvider;
+import org.glassfish.external.probe.provider.annotations.Probe;
+import org.glassfish.external.probe.provider.annotations.ProbeParam;
+
+/**
+ *
+ * @author nithyasubramanian
+ */
+@ProbeProvider(moduleProviderName="glassfish",moduleName="security",probeProviderName="realm")
+public class RealmsProbeProvider {
+    
+    @Probe(name="realmAddedEvent")
+    public void realmAddedEvent(
+            @ProbeParam("realmName") String realmName
+            )
+    {}
+    
+    @Probe(name="realmRemovedEvent")
+    public void realmRemovedEvent(
+            @ProbeParam("realmName") String realmName
+            )
+    {}
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/User.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/User.java
new file mode 100644
index 0000000..7be8e82
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/User.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm;
+
+import java.security.Principal;
+
+import java.util.Enumeration;
+
+
+/**
+ * All users are principals ... perhaps in the native OS, perhaps
+ * not.
+ *
+ * <P> Users always have authentication information, which is used
+ * to validate a user's proferred credentials.  Different kinds of
+ * realms use different kinds of authentication information.  For
+ * example, realms could use X.509 public key certificates, shared
+ * passphrases, encrypted passwords, smart cards, or biometric data
+ * to figure out if the user's credentials are valid.
+ * 
+ * <P> Users typically have attributes that identify privileges 
+ * granted/possesed by the user.
+ *
+ * @author Harish Prabandham
+ */
+
+public interface User extends Principal {
+    /**
+     * Returns the realm with which this user is associated.
+     */
+    Realm getRealm () throws NoSuchRealmException;
+
+
+    /**
+     * Returns the single requested attribute for the user.
+     *
+     * @param name string identifying the attribute.
+     * @return value of that attribute, or null if no value
+     *	has been defined
+     */
+    Object getAttribute (String name);
+
+
+    /**
+     * Returns an enumeration of the keys for the attributes
+     * supported for this user.
+     */
+    Enumeration	getAttributeNames ();
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/certificate/CertificateRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/certificate/CertificateRealm.java
new file mode 100644
index 0000000..7870bb2
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/certificate/CertificateRealm.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm.certificate;
+
+import com.sun.enterprise.security.SecurityContext;
+import com.sun.enterprise.security.auth.login.DistinguishedPrincipalCredential;
+import java.util.*;
+import java.util.logging.Level;
+
+import javax.security.auth.Subject;
+
+import org.glassfish.security.common.Group;
+//import com.sun.enterprise.security.SecurityContext;
+import com.sun.enterprise.security.auth.realm.BadRealmException;
+import com.sun.enterprise.security.auth.realm.NoSuchUserException;
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import com.sun.enterprise.security.auth.realm.InvalidOperationException;
+
+import com.sun.enterprise.security.auth.realm.IASRealm;
+import java.security.Principal;
+import javax.security.auth.callback.Callback;
+
+
+import org.jvnet.hk2.annotations.Service;
+import sun.security.x509.X500Name;
+
+
+/**
+ * Realm wrapper for supporting certificate authentication.
+ *
+ * <P>The certificate realm provides the security-service functionality
+ * needed to process a client-cert authentication. Since the SSL processing,
+ * and client certificate verification is done by NSS, no authentication
+ * is actually done by this realm. It only serves the purpose of being
+ * registered as the certificate handler realm and to service group
+ * membership requests during web container role checks.
+ *
+ * <P>There is no JAAS LoginModule corresponding to the certificate realm,
+ * therefore this realm does not require the jaas-context configuration
+ * parameter to be set. The purpose of a JAAS LoginModule is to implement
+ * the actual authentication processing, which for the case of this
+ * certificate realm is already done by the time execution gets to Java.
+ *
+ * <P>The certificate realm needs the following properties in its
+ * configuration: None.
+ *
+ * <P>The following optional attributes can also be specified:
+ * <ul>
+ *   <li>assign-groups - A comma-separated list of group names which
+ *       will be assigned to all users who present a cryptographically
+ *       valid certificate. Since groups are otherwise not supported
+ *       by the cert realm, this allows grouping cert users
+ *       for convenience.
+ * </ul>
+ *
+ */
+
+@Service
+public final class CertificateRealm extends IASRealm
+{
+    // Descriptive string of the authentication type of this realm.
+    public static final String AUTH_TYPE = "certificate";
+    private Vector<String> defaultGroups = new Vector<String>();
+
+    // Optional link to a realm to verify group (possibly user, later)
+    // public static final String PARAM_USEREALM = "use-realm";
+
+    // Optional ordered list of possible elements to use as user name
+    // from X.500 name.
+    //    public static final String PARAM_NAMEFIELD = "name-field";
+    //    private String[] nameFields = null;
+    //    private static final String LINK_SEP = ",";
+
+    /**
+     * Initialize a realm with some properties.  This can be used
+     * when instantiating realms from their descriptions.  This
+     * method is invoked from Realm during initialization.
+     *
+     * @param props Initialization parameters used by this realm.
+     * @exception BadRealmException If the configuration parameters
+     *     identify a corrupt realm.
+     * @exception NoSuchRealmException If the configuration parameters
+     *     specify a realm which doesn't exist.
+     *
+     */
+    protected void init(Properties props)
+        throws BadRealmException, NoSuchRealmException
+    {
+        super.init(props);
+        String[] groups = addAssignGroups(null);
+        if (groups != null && groups.length > 0) {
+            for (String gp : groups) {
+                defaultGroups.add(gp);
+            }
+        }
+
+        String jaasCtx = props.getProperty(IASRealm.JAAS_CONTEXT_PARAM);
+        if (jaasCtx != null) {
+            this.setProperty(IASRealm.JAAS_CONTEXT_PARAM, jaasCtx);
+        }
+
+
+        /* future enhacement; allow using subset of DN as name field;
+           requires RI fixes to handle subject & principal names
+           consistently
+        String nameLink = props.getProperty(PARAM_NAMEFIELD);
+        if (nameLink == null) {
+            Util.debug(log, "CertificateRealm: No "+PARAM_NAMEFIELD+
+                       " provided, will use X.500 name.");
+        } else {
+
+            StringTokenizer st = new StringTokenizer(nameLink, LINK_SEP);
+            int n = st.countTokens();
+            nameFields = new String[n];
+
+            for (int i=0; i<n; i++) {
+                nameFields[i] = (String)st.nextToken();
+            }
+        }
+        */
+
+        /* future enhancement; allow linking to other realm such that
+           user presence verification and group membership can be
+           defined/shared; requires RI fixes to consistently check role
+           memberships and RI fixes to allow multiple active realms.
+        String link = props.getProperty(PARAM_USEREALM);
+        if (link != null) {
+            this.setProperty(PARAM_USEREALM, link);
+            Util.debug(log, "CertificateRealm : "+PARAM_USEREALM+"="+link);
+        }
+        */
+    }
+
+
+    /**
+     * Returns a short (preferably less than fifteen characters) description
+     * of the kind of authentication which is supported by this realm.
+     *
+     * @return Description of the kind of authentication that is directly
+     *     supported by this realm.
+     */
+    public String getAuthType()
+    {
+        return AUTH_TYPE;
+    }
+    
+
+    /**
+     * Returns the name of all the groups that this user belongs to.
+     *
+     * @param username Name of the user in this realm whose group listing
+     *     is needed.
+     * @return Enumeration of group names (strings).
+     * @exception InvalidOperationException thrown if the realm does not
+     *     support this operation - e.g. Certificate realm does not support
+     *     this operation.
+     *
+     */
+    public Enumeration getGroupNames(String username)
+        throws NoSuchUserException, InvalidOperationException
+    {
+        // This is called during web container role check, not during
+        // EJB container role cheks... fix RI for consistency.
+
+        // Groups for cert users is empty by default unless some assign-groups
+        // property has been specified (see init()).
+        return defaultGroups.elements();
+    }
+    
+
+    /**
+     * Returns name of JAAS context used by this realm. Overrides default
+     * Realm behavior of this method. The certificate realm does not
+     * require (or support) a LoginModule. This method should never get
+     * called unless there is a configuration error, so this overloading
+     * is provided to log an error message.  See class documentation.
+     *
+     * @return null
+     *
+     */
+    /*public String getJAASContext()
+    {
+    _logger.warning("certrealm.nojaas");
+    return null;
+    }*/
+
+    /**
+     * Complete authentication of certificate user.
+     *
+     * <P>As noted, the certificate realm does not do the actual
+     * authentication (signature and cert chain validation) for
+     * the user certificate, this is done earlier in NSS. This method
+     * simply sets up the security context for the user in order to
+     * properly complete the authentication processing.
+     *
+     * <P>If any groups have been assigned to cert-authenticated users
+     * through the assign-groups property these groups are added to
+     * the security context for the current user.
+     *
+     * @param subject The Subject object for the authentication request.
+     * @param x500name The X500Name object from the user certificate.
+     *
+     
+    public void authenticate(Subject subject, X500Name x500name)
+    {
+        // It is important to use x500name.getName() in order to be
+        // consistent with web containers view of the name - see bug
+        // 4646134 for reasons why this matters.
+        
+        String name = x500name.getName();
+
+        if (_logger.isLoggable(Level.FINEST)) {
+            _logger.finest(
+                "Certificate realm setting up security context for: "+ name);
+        }
+
+        if (defaultGroups != null) {
+	    Set principalSet = subject.getPrincipals();
+	    Enumeration e = defaultGroups.elements();
+	    while (e.hasMoreElements()) {
+		principalSet.add(new Group((String) e.nextElement()));
+	    }
+	}
+        
+        SecurityContext securityContext =
+	    new SecurityContext(name, subject);
+        
+	SecurityContext.setCurrent(securityContext);
+    }*/
+
+    /**
+     * Complete authentication of certificate user.
+     *
+     * <P>As noted, the certificate realm does not do the actual
+     * authentication (signature and cert chain validation) for
+     * the user certificate, this is done earlier in NSS. This method
+     * simply sets up the security context for the user in order to
+     * properly complete the authentication processing.
+     *
+     * <P>If any groups have been assigned to cert-authenticated users
+     * through the assign-groups property these groups are added to
+     * the security context for the current user.
+     *
+     * @param subject The Subject object for the authentication request.
+     * @param x500name The X500Name object from the user certificate.
+     *
+     */
+    public void authenticate(Subject subject, X500Name x500name)
+    {
+        // It is important to use x500name.getName() in order to be
+        // consistent with web containers view of the name - see bug
+        // 4646134 for reasons why this matters.
+        
+        String name = x500name.getName();
+
+        if (_logger.isLoggable(Level.FINEST)) {
+            _logger.finest(
+                "Certificate realm setting up security context for: "+ name);
+        }
+
+        if (defaultGroups != null) {
+	    Set<Principal> principalSet = subject.getPrincipals();
+	    Enumeration<String> e = defaultGroups.elements();
+	    while (e.hasMoreElements()) {
+		principalSet.add(new Group(e.nextElement()));
+	    }
+	}
+        if (!subject.getPrincipals().isEmpty()) {
+            DistinguishedPrincipalCredential dpc = new DistinguishedPrincipalCredential(x500name);
+            subject.getPublicCredentials().add(dpc);
+        }
+        
+        SecurityContext securityContext =
+	    new SecurityContext(name, subject);
+
+	SecurityContext.setCurrent(securityContext);
+        /*AppServSecurityContext secContext = Util.getDefaultHabitat().getByContract(AppServSecurityContext.class);
+        AppServSecurityContext securityContext = secContext.newInstance(name, subject);
+        securityContext.setCurrentSecurityContext(securityContext);*/
+        
+    }
+
+    /**
+     * <p> A <code>LoginModule</code> for <code>CertificateRealm</code>
+     * can instantiate and pass a <code>AppContextCallback</code>
+     * to <code>handle</code> method of the passed
+     * <code>CallbackHandler</code> to retrieve the application
+     * name information.
+     */
+    public final static class AppContextCallback implements Callback {
+        private String moduleID;
+
+        /**
+         * Get the fully qualified module name. The module name consists
+         * of the application name (if not a singleton) followed by a '#'
+         * and the name of the module.
+         *
+         * <p>
+         *
+         * @return the application name.
+         */
+        public String getModuleID() {
+            return moduleID;
+        }
+
+        /**
+         * Set the fully qualified module name. The module name consists
+         * of the application name (if not a singleton) followed by a '#'
+         * and the name of the module.
+         * 
+         */
+        public void setModuleID(String moduleID) {
+            this.moduleID = moduleID;
+        }
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealm.java
new file mode 100644
index 0000000..ab4943c
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealm.java
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm.file;
+
+import java.util.*;
+import java.util.logging.Level;
+import java.io.*;
+import com.sun.enterprise.security.auth.realm.User;
+import com.sun.enterprise.security.auth.realm.Realm;
+import com.sun.enterprise.security.auth.realm.BadRealmException;
+import com.sun.enterprise.security.auth.realm.NoSuchUserException;
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import com.sun.enterprise.security.auth.realm.IASRealm;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.security.common.Util;
+import com.sun.enterprise.security.util.IASSecurityException;
+import org.glassfish.internal.api.RelativePathResolver;
+import org.glassfish.security.common.FileRealmHelper;
+import org.jvnet.hk2.annotations.Service;
+
+
+/**
+ * Realm wrapper for supporting file password authentication.
+ *
+ * <P>In addition to the basic realm functionality, this class provides
+ * administration methods for the file realm.
+ *
+ * <P>Format of the keyfile used by this class is one line per user
+ * containing <code>username;password;groups</code> where:
+ * <ul>
+ *   <li>username - Name string.
+ *   <li>password - A salted SHA hash (SSHA) of the user password.
+ *   <li>groups - A comma separated list of group memberships.
+ * </ul>
+ *
+ * <P>The file realm needs the following properties in its configuration:
+ * <ul>
+ *   <li>file - Full path to the keyfile to load
+ *   <li>jaas-ctx - JAAS context name used to access LoginModule for
+ *       authentication.
+ * </ul>
+ *
+ * @author Harry Singh
+ * @author Jyri Virkki
+ * @author Shing Wai Chan
+ */
+@Service
+public final class FileRealm extends IASRealm
+{
+    // Descriptive string of the authentication type of this realm.
+    public static final String AUTH_TYPE = "filepassword";
+
+    // These are property names which should be in auth-realm in server.xml
+    public static final String PARAM_KEYFILE="file";
+
+    FileRealmHelper helper;
+    
+    /**
+     * Constructor.
+     *
+     * <P>The created FileRealm instance is not registered in the
+     * Realm registry. This constructor can be used by admin tools
+     * to create a FileRealm instance which can be edited by adding or
+     * removing users and then saved to disk, without affecting the
+     * installed realm instance.
+     *
+     * <P>The file provided should always exist. A default (empty) keyfile
+     * is installed with the server so this should always be the case
+     * unless the user has manually deleted this file.  If this file
+     * path provided does not point to an existing file this constructor
+     * will first attempt to create it. If this succeeds the constructor
+     * returns normally and an empty keyfile will have been created; otherwise
+     * an exception is thrown.
+     *
+     * @param keyfile Full path to the keyfile to read for user data.
+     * @exception BadRealmException If the configuration parameters
+     *     identify a corrupt realm.
+     * @exception NoSuchRealmException If the configuration parameters
+     *     specify a realm which doesn't exist.
+     *
+     */
+    public FileRealm(String keyfile)
+         throws BadRealmException, NoSuchRealmException
+    {
+        Properties p = new Properties();
+        // The original keyfile is stored here for use in the init and refresh methods
+        p.setProperty(PARAM_KEYFILE, keyfile);
+        p.setProperty(IASRealm.JAAS_CONTEXT_PARAM, "ignore");
+        this.init(p);
+    }
+
+    /* 
+     * No arg constructor used by the Realm class when creating realms. 
+     * This is followed by a call to the init() method. 
+     */
+    public FileRealm()
+    {
+    }
+    
+    /**
+     * Return a list of the file names used by all file realms
+     * defined for the specified config.
+     *
+     * @param   config  the config object
+     * @return          a list of the file names for all files realms in the
+     *                  config
+     */
+    public static List<String> getRealmFileNames(Config config) {
+        List<String> files = new ArrayList<String>();
+        SecurityService securityService = config.getSecurityService();
+        for (AuthRealm authRealm : securityService.getAuthRealm()) {
+            String fileRealmClassName = authRealm.getClassname();
+            // skip it if it's not a file realm
+            if (fileRealmClassName == null ||
+                    !fileRealmClassName.equals(FileRealm.class.getName()))
+                continue;
+            String file = authRealm.getPropertyValue("file");
+            if (file == null)           // skip if no "file" property
+                continue;
+            if (file.contains("$")) {
+                file = RelativePathResolver.resolvePath(file);
+            }
+            files.add(file);
+        }
+        return files;
+    }
+
+    
+    /**
+     * Initialize a realm with some properties.  This can be used
+     * when instantiating realms from their descriptions.  This
+     * method is invoked from Realm during initialization.
+     *
+     * @param props Initialization parameters used by this realm.
+     * @exception BadRealmException If the configuration parameters
+     *     identify a corrupt realm.
+     * @exception NoSuchRealmException If the configuration parameters
+     *     specify a realm which doesn't exist.
+     *
+     */
+    @Override
+    protected void init(Properties props)
+        throws BadRealmException, NoSuchRealmException
+    {
+        super.init(props);
+        String file = props.getProperty(PARAM_KEYFILE);
+        if (file == null) {
+            String msg = sm.getString("filerealm.nofile");
+            throw new BadRealmException(msg);
+        }
+        if (file.contains("$")) {
+                file = RelativePathResolver.resolvePath(file);
+        }
+        
+        this.setProperty(PARAM_KEYFILE, file);
+        
+        String jaasCtx = props.getProperty(IASRealm.JAAS_CONTEXT_PARAM);
+        if (jaasCtx == null) {
+            String msg = sm.getString("filerealm.nomodule");
+            throw new BadRealmException(msg);
+        }
+        this.setProperty(IASRealm.JAAS_CONTEXT_PARAM, jaasCtx);
+
+        _logger.log(Level.FINE, "FileRealm : "+ PARAM_KEYFILE + "={0}", file);
+        _logger.log(Level.FINE, "FileRealm : "+ IASRealm.JAAS_CONTEXT_PARAM + "={0}", jaasCtx);
+       try {
+            if (Util.isEmbeddedServer()) {
+                String embeddedFilePath = Util.writeConfigFileToTempDir(file).getAbsolutePath();
+                file = embeddedFilePath;
+            }
+            helper = new FileRealmHelper(file);
+        } catch (IOException ioe) {
+            String msg = sm.getString("filerealm.noaccess", ioe.toString());
+            throw new BadRealmException(msg);
+        }
+    }
+
+
+    /**
+     * Returns a short (preferably less than fifteen characters) description
+     * of the kind of authentication which is supported by this realm.
+     *
+     * @return Description of the kind of authentication that is directly
+     *     supported by this realm.
+     */
+    @Override
+    public String getAuthType()
+    {
+        return AUTH_TYPE;
+    }
+    
+
+    /**
+     * Returns names of all the users in this particular realm.
+     *
+     * @return enumeration of user names (strings)
+     * @exception BadRealmException if realm data structures are bad
+     */
+    @Override
+    public Enumeration<String> getUserNames()
+         throws BadRealmException
+    {
+        return Collections.enumeration(helper.getUserNames());
+    }
+
+
+    /**
+     * Returns the information recorded about a particular named user.
+     *
+     * @param name Name of the user whose information is desired.
+     * @return The user object.
+     * @exception NoSuchUserException if the user doesn't exist.
+     * @exception BadRealmException if realm data structures are bad.
+     */
+    @Override
+    public User getUser(String name)
+        throws NoSuchUserException
+    {
+        
+        FileRealmHelper.User u = helper.getUser(name);
+        if (u == null) {
+            String msg = sm.getString("filerealm.nouser", name);
+            throw new NoSuchUserException(msg);
+        }
+        return new FileRealmUser(u, null);
+    }
+    
+
+    /**
+     * Returns names of all the groups in this particular realm.
+     * Note that this will not return assign-groups.
+     *
+     * @return enumeration of group names (strings)
+     * @exception BadRealmException if realm data structures are bad
+     */
+    @Override
+    public Enumeration getGroupNames()
+        throws BadRealmException
+    {
+        return Collections.enumeration(helper.getGroupNames());
+    }
+
+    
+    /**
+     * Returns the name of all the groups that this user belongs to.
+     * @param username Name of the user in this realm whose group listing
+     *     is needed.
+     * @return Enumeration of group names (strings).
+     * @exception InvalidOperationException thrown if the realm does not
+     *     support this operation - e.g. Certificate realm does not support
+     *     this operation.
+     */
+    @Override
+    public Enumeration getGroupNames(String username)
+        throws NoSuchUserException
+    {
+        String groups[] = helper.getGroupNames(username);
+        if ( groups == null ) {
+          groups = new String[]{};
+        }
+        groups = addAssignGroups(groups);
+        return Collections.enumeration(Arrays.asList(groups));
+    }
+
+    /**
+     * Refreshes the realm data so that new users/groups are visible.
+     *
+     * <P>A new FileRealm instance is created and initialized from the
+     * keyfile on disk. The new instance is installed in the Realm registry
+     * so future Realm.getInstance() calls will obtain the new data. Any
+     * existing references to this instance (e.g. in active LoginModule
+     * sessions) are unaffected.
+     *
+     * @exception BadRealmException if realm data structures are bad
+     *
+     */
+    @Override
+    public void refresh()
+         throws BadRealmException
+    {
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.fine("Reloading file realm data.");
+        }
+
+        try {
+            FileRealm newRealm = new FileRealm(getProperty(PARAM_KEYFILE));
+            newRealm.init(getProperties());
+            Realm.updateInstance(newRealm, this.getName());
+        } catch (Exception e) {
+            throw new BadRealmException(e.toString());
+        }
+    }
+
+    /**
+     * Refreshes the realm data so that new users/groups are visible.
+     *
+     * <P>A new FileRealm instance is created and initialized from the
+     * keyfile on disk. The new instance is installed in the Realm registry
+     * so future Realm.getInstance() calls will obtain the new data. Any
+     * existing references to this instance (e.g. in active LoginModule
+     * sessions) are unaffected.
+     * @param config
+     * @exception BadRealmException if realm data structures are bad
+     *
+     */
+    @Override
+    public void refresh(String configName)
+            throws BadRealmException {
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.fine("Reloading file realm data.");
+        }
+        
+        try {
+            FileRealm newRealm = new FileRealm(getProperty(PARAM_KEYFILE));
+            newRealm.init(getProperties());
+            Realm.updateInstance(configName, newRealm, this.getName());
+        } catch (Exception e) {
+            throw new BadRealmException(e.toString());
+        }
+    }
+
+     /**
+     * Adds new user to file realm. User cannot exist already.
+     *
+     * @param name User name.
+     * @param password Cleartext password for the user.
+     * @param groupList List of groups to which user belongs.
+     * @throws BadRealmException If there are problems adding user.
+     *
+     */
+    @Override
+    public  void addUser(String name, char[] password, String[] groupList)
+        throws BadRealmException, IASSecurityException  {
+        helper.addUser(name, password, groupList);
+    }
+
+    /**
+     * Remove user from file realm. User must exist.
+     *
+     * @param name User name.
+     * @throws NoSuchUserException If user does not exist.
+     *
+     */
+    @Override
+     public void removeUser(String name)
+        throws NoSuchUserException, BadRealmException {
+        helper.removeUser(name);
+     }
+
+   /**
+     * Update data for an existing user. User must exist.
+     *
+     * @param name Current name of the user to update.
+     * @param newName New name to give this user. It can be the same as
+     *     the original name. Otherwise it must be a new user name which
+     *     does not already exist as a user.
+     * @param password Cleartext password for the user. If non-null the user
+     *     password is changed to this value. If null, the original password
+     *     is retained.
+     * @param groupList List of groups to which user belongs.
+     * @throws BadRealmException If there are problems adding user.
+     * @throws NoSuchUserException If user does not exist.
+     *
+     */
+    @Override
+    public void updateUser(String name, String newName, char[] password,
+                           String[] groups)
+        throws NoSuchUserException, BadRealmException,
+                               IASSecurityException {
+        helper.updateUser(name, newName, password, groups);
+    }
+
+
+    /**
+     * Authenticates a user.
+     *
+     * <P>This method is invoked by the FileLoginModule in order to
+     * authenticate a user in the file realm. The authentication decision
+     * is kept within the realm class implementation in order to keep
+     * the password cache in a single location with no public accessors,
+     * to simplify future improvements.
+     *
+     * @param user Name of user to authenticate.
+     * @param password Password provided by client.
+     * @returns Array of group names the user belongs to, or null if
+     *      authentication fails.
+     * @throws LoginException If there are errors during authentication.
+     *
+     */
+    public String[] authenticate(String user, char[] password)
+    {
+        String groups[] = helper.authenticate(user, password);
+        if (groups != null) {
+            groups = addAssignGroups(groups);
+        }
+        return groups;
+    }
+
+    /*
+     * Test whether their is a user in the FileRealm that has a password that 
+     * has been set, i.e., something other than the resetKey.
+     */
+    public boolean hasAuthenticatableUser() 
+    {
+        return helper.hasAuthenticatableUser();
+    }
+      
+    /**
+     * @return true if the realm implementation support User Management (add,remove,update user)
+     */
+    @Override
+    public boolean supportsUserManagement() {
+        //File Realm supports UserManagement
+        return true;
+    }
+    
+    /**
+     * Persist the realm data to permanent storage
+     * @throws com.sun.enterprise.security.auth.realm.BadRealmException
+     */
+    @Override
+    public void persist() throws BadRealmException {      
+        try {
+           helper.persist();
+        } catch (IOException ex) {
+            throw new BadRealmException(ex);
+        }
+    }    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealmUser.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealmUser.java
new file mode 100644
index 0000000..c367e41
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealmUser.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm.file;
+
+import java.util.*;
+
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import com.sun.enterprise.security.auth.realm.Realm;
+import com.sun.enterprise.security.auth.realm.User;
+import org.glassfish.security.common.FileRealmHelper;
+
+
+/**
+ * Represents a FileRealm user.
+ *
+ *
+ */
+public class FileRealmUser implements User
+{    
+    FileRealmHelper.User user;
+    Hashtable attributes = new Hashtable();
+    String realm;
+    /**
+     * Constructor.
+     *
+     */
+    public FileRealmUser(FileRealmHelper.User user, String realm)
+    {
+        this.user = user;
+        this.realm = realm;
+    }
+    
+    public String[] getGroups() {
+        return user.getGroups();
+    }
+    
+    /**
+     * Returns the realm with which this user is associated
+     *
+     * @return Realm name.
+     * @exception NoSuchRealmException if the realm associated this user
+     *            no longer exist
+     *
+     */
+    @Override
+    public Realm getRealm() throws NoSuchRealmException
+    {
+	return Realm.getInstance(realm);
+    }
+
+    /**
+     * Return the requested attribute for the user.
+     * <P>Not really needed.
+     *
+     * @param key string identifies the attribute.
+     */
+    @Override
+    public Object getAttribute (String key)
+    {
+        return attributes.get(key);
+    }
+
+    /**
+     * Return the names of the supported attributes for this user.
+     * <P>Not really needed.
+     */
+    @Override
+    public Enumeration getAttributeNames () {
+	return attributes.keys();
+    }
+
+    @Override
+    public String getName() {
+        return user.getName();
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/jdbc/.gitkeep_empty_dir b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/jdbc/.gitkeep_empty_dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/jdbc/.gitkeep_empty_dir
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/ldap/CustomSocketFactory.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/ldap/CustomSocketFactory.java
new file mode 100644
index 0000000..04c4a43
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/ldap/CustomSocketFactory.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm.ldap;
+
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.security.SecurityServicesUtil;
+import com.sun.enterprise.security.ssl.SSLUtils;
+import com.sun.enterprise.util.i18n.StringManager;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Comparator;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import java.net.InetAddress;
+
+import org.glassfish.internal.api.Globals;
+import org.glassfish.internal.api.SharedSecureRandom;
+/**
+ * Custom socket factory for ldaps (SSL).
+ *
+ * The comparator only works in JDK 1.6 onwards. Due to a bug in JDK 1.6
+ * compare method invocation fails with a classcast exception. The caller is 
+ * trying to pass java.lang.String when it should have passed 
+ * javax.net.SocketFactory
+ * 
+ * @see com.sun.enterprise.security.auth.realm.ldap.LDAPRealm
+ *
+ */
+public class CustomSocketFactory extends SocketFactory implements Comparator<SocketFactory> {
+    private SocketFactory socketFactory;
+
+    public static final String SSL = "SSL";
+    protected static final Logger _logger =
+        SecurityLoggerInfo.getLogger();
+    protected static final StringManager sm =
+        StringManager.getManager(CustomSocketFactory.class);
+    private static final  CustomSocketFactory customSocketFactory = new CustomSocketFactory();
+
+    public  CustomSocketFactory() {
+        SSLUtils sslUtils = Globals.getDefaultHabitat().getService(SSLUtils.class);
+        SSLContext sc = null;
+        try {
+            sc = SSLContext.getInstance(SSL);
+            sc.init(sslUtils.getKeyManagers(), sslUtils.getTrustManagers(), SharedSecureRandom.get());
+            socketFactory = sc.getSocketFactory();
+        } catch (Exception ex) {
+            _logger.log(Level.WARNING, SecurityLoggerInfo.securityExceptionError, ex);
+        }        
+    }
+    
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.lang.String, int)
+     */
+    public Socket createSocket(String arg0, int arg1) throws IOException,
+            UnknownHostException {
+        return socketFactory.createSocket(arg0, arg1);
+    }
+    
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.net.InetAddress, int)
+     */
+    public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
+        return socketFactory.createSocket(arg0, arg1);
+    }
+    
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.lang.String, int,
+     *      java.net.InetAddress, int)
+     */
+    public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3)
+    throws IOException, UnknownHostException {
+        return socketFactory.createSocket(arg0, arg1, arg2, arg3);
+    }
+    
+    /**
+     * @see javax.net.SocketFactory#createSocket(java.net.InetAddress, int,
+     *      java.net.InetAddress, int)
+     */
+    public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2,
+            int arg3) throws IOException {
+        return socketFactory.createSocket(arg0, arg1, arg2, arg3);
+    }
+
+    public int compare(SocketFactory s1, SocketFactory s2) {
+        return s1.getClass().toString().compareTo(s2.getClass().toString());
+    }
+
+    public static SocketFactory getDefault() {
+        return customSocketFactory;
+    }
+    
+    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/ldap/LDAPRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/ldap/LDAPRealm.java
new file mode 100644
index 0000000..d49eef9
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/ldap/LDAPRealm.java
@@ -0,0 +1,769 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm.ldap;
+
+import java.util.*;
+import java.io.IOException;
+import java.util.logging.Level;
+import javax.naming.CompositeName;
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.security.auth.login.LoginException;
+import java.security.Principal;
+// imported from the ldap booster pack
+import com.sun.jndi.ldap.obj.GroupOfURLs;
+import javax.security.auth.x500.X500Principal;
+import com.sun.enterprise.security.auth.realm.BadRealmException;
+import com.sun.enterprise.security.auth.realm.NoSuchUserException;
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import com.sun.enterprise.security.auth.realm.InvalidOperationException;
+
+import com.sun.enterprise.security.auth.realm.IASRealm;
+import java.lang.StringBuffer;
+import java.util.regex.Matcher;
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+import org.glassfish.internal.api.RelativePathResolver;
+import org.jvnet.hk2.annotations.Service;
+import sun.security.x509.X500Name;
+
+
+/**
+ * Realm wrapper for supporting LDAP authentication.
+ *
+ * <P>See LDAPLoginModule documentation for more details on the operation
+ * of the LDAP realm and login module.
+ *
+ * <P>The ldap realm needs the following properties in its configuration:
+ * <ul>
+ *   <li>directory - URL of LDAP directory to use
+ *   <li>base-dn - The base DN to use for user searches.
+ *   <li>jaas-ctx - JAAS context name used to access LoginModule for
+ *       authentication.
+ * </ul>
+ *
+ * <P>Besides JDK Context properties start with java.naming, javax.security,
+ *  one can also set connection pool related properties starting with
+ *  com.sun.jndi.ldap.connect.pool.
+ *  See http://java.sun.com/products/jndi/tutorial/ldap/connect/config.html
+ *  for details.
+ *  Also, the following optional attributes can also be specified:
+ * <ul>
+ *   <li>search-filter - LDAP filter to use for searching for the user
+ *       entry based on username given to iAS. The default value is
+ *       <code>uid=%s</code> where %s is expanded to the username.
+ *   <li>group-base-dn - The base DN to use for group searches. By default
+ *       its value is the same as base-dn.
+ *   <li>group-search-filter - The LDAP filter to use for searching group
+ *       membership of a given user. The default value is <code>
+ *       uniquemember=%d</code> where %d is expanded to the DN of the
+ *       user found by the user search.
+ *   <li>group-target - The attribute which value(s) are interpreted as
+ *       group membership names of the user. Default value is <code>cn</code>.
+ *   <li>search-bind-dn - The dn of ldap user. optional and no default value.
+ *   <li>search-bind-password - The password of search-bind-dn.optional and 
+ *       no default value.
+ *   <li>pool-size - The JNDI ldap connection pool size.
+ * </ul>
+ * 
+ * @see com.sun.enterprise.security.auth.login.LDAPLoginModule
+ *
+ */
+@Service
+public final class LDAPRealm extends IASRealm
+{
+    // Descriptive string of the authentication type of this realm.
+    public static final String AUTH_TYPE = "ldap";
+
+    // These are property names which should be in auth-realm in server.xml
+    public static final String PARAM_DIRURL="directory";
+    public static final String PARAM_USERDN="base-dn";
+   
+    // These are optional, defaults are provided
+    // %s = subject name
+    // %d = DN of user search result
+    public static final String PARAM_SEARCH_FILTER="search-filter";
+    public static final String PARAM_GRPDN="group-base-dn";
+    public static final String PARAM_GRP_SEARCH_FILTER="group-search-filter";
+    public static final String PARAM_GRP_TARGET="group-target";
+    public static final String PARAM_DYNAMIC_GRP_FILTER="dynamic-group-search-filter";
+    public static final String PARAM_DYNAMIC_GRP_TARGET="dynamic-group-target";
+    public static final String PARAM_MODE="mode";
+    public static final String PARAM_JNDICF="jndiCtxFactory";
+    public static final String PARAM_POOLSIZE="pool-size";
+    
+    // These are optional, no default values are provided
+    public static final String PARAM_BINDDN="search-bind-dn";
+    public static final String PARAM_BINDPWD="search-bind-password";
+
+    // Only find-bind mode is supported so mode attribute is not exposed yet
+    public static final String MODE_FIND_BIND="find-bind";
+
+    // Expansion strings
+    public static final String SUBST_SUBJECT_NAME="%s";
+    public static final String SUBST_SUBJECT_DN="%d";
+
+    // Defaults
+    private static final String SEARCH_FILTER_DEFAULT=
+                                     "uid="+SUBST_SUBJECT_NAME;
+    private static final String GRP_SEARCH_FILTER_DEFAULT=
+                                     "uniquemember="+SUBST_SUBJECT_DN;
+    private static final String GRP_TARGET_DEFAULT="cn";
+    private static final String DYNAMIC_GRP_TARGET_DEFAULT="ismemberof";//"memberOf";
+    private static final String MODE_DEFAULT=MODE_FIND_BIND;
+    private static final String JNDICF_DEFAULT=
+                                     "com.sun.jndi.ldap.LdapCtxFactory";
+    private static final int POOLSIZE_DEFAULT=5;
+
+    private final String[] _dnOnly = {"dn"};
+    
+    private static final String SUN_JNDI_POOL = "com.sun.jndi.ldap.connect.pool";
+    private static final String SUN_JNDI_POOL_ = "com.sun.jndi.ldap.connect.pool.";
+    private static final String SUN_JNDI_POOL_PROTOCOL = "com.sun.jndi.ldap.connect.pool.protocol";
+    private static final String SUN_JNDI_POOL_MAXSIZE = "com.sun.jndi.ldap.connect.pool.maxsize";
+    // dynamic group related properties.
+    private static final String DYNAMIC_GROUP_OBJECT_FACTORY =
+                                        "com.sun.jndi.ldap.obj.LdapGroupFactory";
+    public static final String DYNAMIC_GROUP_FACTORY_OBJECT_PROPERTY =
+                                        "java.naming.factory.object";
+    private static final String DYNAMIC_GROUP_STATE_FACTORY = 
+                                        "com.sun.jndi.ldap.obj.LdapGroupFactory";
+    public static final String DYNAMIC_GROUP_STATE_FACTORY_PROPERTY =
+                                        "java.naming.factory.state";
+    public static final String LDAP_SOCKET_FACTORY = "java.naming.ldap.factory.socket";
+    public static final String DEFAULT_SSL_LDAP_SOCKET_FACTORY = "com.sun.enterprise.security.auth.realm.ldap.CustomSocketFactory";
+    public static final String LDAPS_URL = "ldaps://";
+    public static final String DEFAULT_POOL_PROTOCOL = "plain ssl";
+    
+    public static final String DYNAMIC_GROUP_FILTER = 
+                "(&(objectclass=groupofuniquenames)(objectclass=*groupofurls*))";
+    
+    public static final String SSL = "SSL";
+    
+    private HashMap groupCache;
+    private Vector emptyVector;
+    private Properties ldapBindProps = new Properties();
+
+    /**
+     * Initialize a realm with some properties.  This can be used
+     * when instantiating realms from their descriptions.  This
+     * method may only be called a single time.  
+     *
+     * @param props Initialization parameters used by this realm.
+     * @exception BadRealmException If the configuration parameters
+     *     identify a corrupt realm.
+     * @exception NoSuchRealmException If the configuration parameters
+     *     specify a realm which doesn't exist.
+     *
+     */
+    public synchronized void init(Properties props)
+        throws BadRealmException, NoSuchRealmException
+    {
+        super.init(props);
+        String url = props.getProperty(PARAM_DIRURL);
+        String dn = props.getProperty(PARAM_USERDN);
+        String jaasCtx = props.getProperty(IASRealm.JAAS_CONTEXT_PARAM);
+       
+        if (url==null || dn==null || jaasCtx==null) {
+            String msg = sm.getString("ldaprealm.badconfig", url, dn, jaasCtx);
+            throw new BadRealmException(msg);
+        }
+        this.setProperty(PARAM_DIRURL, url);
+        ldapBindProps.setProperty(Context.PROVIDER_URL, url);
+        this.setProperty(PARAM_USERDN, dn);
+        this.setProperty(IASRealm.JAAS_CONTEXT_PARAM, jaasCtx);
+        
+        String mode = props.getProperty(PARAM_MODE, MODE_DEFAULT);
+        if (!MODE_DEFAULT.equals(mode)) {
+            String msg = sm.getString("ldaprealm.badmode", mode);
+            throw new BadRealmException(msg);
+        }
+        this.setProperty(PARAM_MODE, mode);
+
+        String ctxF = props.getProperty(PARAM_JNDICF, JNDICF_DEFAULT);
+        this.setProperty(PARAM_JNDICF, ctxF);
+        ldapBindProps.setProperty(Context.INITIAL_CONTEXT_FACTORY, ctxF);
+
+        String searchFilter = props.getProperty(
+                PARAM_SEARCH_FILTER, SEARCH_FILTER_DEFAULT);
+        this.setProperty(PARAM_SEARCH_FILTER,searchFilter);
+
+        String grpDN = props.getProperty(PARAM_GRPDN, dn);
+        this.setProperty(PARAM_GRPDN, grpDN);
+
+        String grpSearchFilter = props.getProperty(
+                PARAM_GRP_SEARCH_FILTER, GRP_SEARCH_FILTER_DEFAULT);
+        this.setProperty(PARAM_GRP_SEARCH_FILTER, grpSearchFilter);
+
+        String dynGrpSearchFilter = props.getProperty(
+                PARAM_DYNAMIC_GRP_FILTER, SEARCH_FILTER_DEFAULT);
+        this.setProperty(PARAM_DYNAMIC_GRP_FILTER, dynGrpSearchFilter);
+
+        String grpTarget = props.getProperty(
+                PARAM_GRP_TARGET, GRP_TARGET_DEFAULT);
+        this.setProperty(PARAM_GRP_TARGET, grpTarget);
+
+        String dynGrpTarget = props.getProperty(
+                PARAM_DYNAMIC_GRP_TARGET, DYNAMIC_GRP_TARGET_DEFAULT);
+        this.setProperty(PARAM_DYNAMIC_GRP_TARGET, dynGrpTarget);
+
+        String objectFactory = props.getProperty(
+                DYNAMIC_GROUP_FACTORY_OBJECT_PROPERTY, DYNAMIC_GROUP_OBJECT_FACTORY);
+        this.setProperty(DYNAMIC_GROUP_FACTORY_OBJECT_PROPERTY, objectFactory);
+        ldapBindProps.setProperty(DYNAMIC_GROUP_FACTORY_OBJECT_PROPERTY, objectFactory);
+
+        String stateFactory = props.getProperty(
+                DYNAMIC_GROUP_STATE_FACTORY_PROPERTY, DYNAMIC_GROUP_STATE_FACTORY);
+        this.setProperty(DYNAMIC_GROUP_STATE_FACTORY_PROPERTY, stateFactory);
+        ldapBindProps.setProperty(DYNAMIC_GROUP_STATE_FACTORY_PROPERTY, stateFactory);
+
+        String bindDN = props.getProperty(PARAM_BINDDN);
+        if (bindDN != null) {
+            this.setProperty(PARAM_BINDDN, bindDN);
+            ldapBindProps.setProperty(Context.SECURITY_PRINCIPAL, bindDN);
+        } 
+        String bindPWD = props.getProperty(PARAM_BINDPWD);
+        if (bindPWD != null) {
+            //If the passwors is aliased, de-alias it
+            try {
+                bindPWD = RelativePathResolver.getRealPasswordFromAlias(bindPWD);
+            }catch(Exception ex) {
+                 _logger.log(Level.WARNING, "ldaprealm.pwd.dealiasing.failed",ex);
+            }
+            this.setProperty(PARAM_BINDPWD, bindPWD);
+            ldapBindProps.setProperty(Context.SECURITY_CREDENTIALS, bindPWD);
+        }
+
+        Enumeration penum = props.propertyNames();
+        while (penum.hasMoreElements()) {
+            String propName = (String)penum.nextElement();
+            if (propName.startsWith("java.naming.") ||
+                    propName.startsWith("javax.security.") ||
+                    propName.startsWith("com.sun.jndi.ldap.")) {
+                ldapBindProps.setProperty(propName, props.getProperty(propName));
+            } else if (propName.startsWith(SUN_JNDI_POOL_) &&
+                    !SUN_JNDI_POOL_MAXSIZE.equals(propName)) {
+                if (System.getProperty(propName) == null) {
+                    System.setProperty(propName, props.getProperty(propName));
+                }
+            }
+        }
+
+        String poolSize =
+            Integer.getInteger(PARAM_POOLSIZE,POOLSIZE_DEFAULT).toString();
+        String sunPoolSizeStr = props.getProperty(SUN_JNDI_POOL_MAXSIZE,
+            poolSize);
+        //Precedence rule: SUN_JNDI_POOL_MAXSIZE > PARAM_POOLSIZE > POOLSIZE_DEFAULT
+        try {
+            sunPoolSizeStr = Integer.valueOf(sunPoolSizeStr).toString();
+        } catch(Exception ex) {
+            sunPoolSizeStr = poolSize;
+        }
+        if (System.getProperty(SUN_JNDI_POOL_MAXSIZE) == null) {       
+            System.setProperty(SUN_JNDI_POOL_MAXSIZE, sunPoolSizeStr);
+        }
+        this.setProperty(PARAM_POOLSIZE, sunPoolSizeStr);
+
+        String usePool = props.getProperty(SUN_JNDI_POOL, "true");
+        ldapBindProps.setProperty(SUN_JNDI_POOL, usePool);
+        
+        if( url.startsWith(LDAPS_URL)) {
+            ldapBindProps.setProperty(LDAP_SOCKET_FACTORY,
+                    DEFAULT_SSL_LDAP_SOCKET_FACTORY);
+            if (System.getProperty(SUN_JNDI_POOL_PROTOCOL) == null) {
+                System.setProperty(SUN_JNDI_POOL_PROTOCOL,DEFAULT_POOL_PROTOCOL);
+            }
+            if (_logger.isLoggable(Level.FINE)) {
+                _logger.log(Level.FINE, "LDAPRealm : Using custom socket factory for SSL with pooling");
+            }
+        }
+        
+        if (_logger.isLoggable(Level.FINE)) {
+            Properties tempProps = (Properties)ldapBindProps.clone();
+            tempProps.remove(Context.SECURITY_CREDENTIALS);
+            _logger.log(Level.FINE, "LDAPRealm : " + tempProps);
+        }
+
+        groupCache = new HashMap();
+        emptyVector = new Vector();
+    }
+
+
+    /**
+     * Returns a short (preferably less than fifteen characters) description
+     * of the kind of authentication which is supported by this realm.
+     *
+     * @return Description of the kind of authentication that is directly
+     *     supported by this realm.
+     */
+    public String getAuthType()
+    {
+        return AUTH_TYPE;
+    }
+
+    private String[] addMappedGroupNames(String[] grpList) {
+
+        if (groupMapper == null) {
+            return grpList;
+        }
+        ArrayList<String> finalresult = new ArrayList<String>();
+        for (String grp : grpList) {
+            ArrayList<String> result = new ArrayList<String>();
+            groupMapper.getMappedGroups(grp, result);
+            finalresult.add(grp);
+            if (!result.isEmpty()) {
+                finalresult.addAll(result);
+            }
+        }
+        return finalresult.toArray(new String[finalresult.size()]);
+    }
+    
+    /**
+     * Get binding properties defined in server.xml for LDAP server.
+     *
+     */
+    private Properties getLdapBindProps()
+    {
+        return (Properties)ldapBindProps.clone();
+    }
+
+
+    private List<String> getGroups(String userDN) {
+        //no authentication has happened through the realm.
+        DirContext ctx = null;
+        String srcFilter = null;
+
+        String dynFilter = null;
+        String dynMember = getProperty(PARAM_DYNAMIC_GRP_TARGET);
+        try {
+            ctx = new InitialDirContext(getLdapBindProps());
+
+            String _username = userDN;
+            try {
+                X500Name name = new X500Name(userDN);
+                _username = name.getCommonName();
+            } catch (IOException e) {
+                //Ignoring the exception to suppot simple group names as userDN
+                //Issue GLASSFISH-19595
+            }
+            if (_username == null && userDN != null && userDN.startsWith("uid")) {
+                //handle uid=XXX here where cn is not present
+                //TODO :maybe there is a better way to handle this??
+                int first = userDN.indexOf("uid=");
+                int last = userDN.indexOf(",");
+                if (first != -1 && last != -1) {
+                    _username = userDN.substring(first + 4, last);
+                }
+
+            }
+            StringBuffer sb = new StringBuffer(getProperty(PARAM_GRP_SEARCH_FILTER));
+            StringBuffer dynSb = new StringBuffer(getProperty(PARAM_DYNAMIC_GRP_FILTER));
+            substitute(sb, SUBST_SUBJECT_NAME, _username);
+            substitute(sb, SUBST_SUBJECT_DN, userDN);
+            substitute(dynSb, SUBST_SUBJECT_NAME, _username);
+            substitute(dynSb, SUBST_SUBJECT_DN, userDN);
+
+            srcFilter = sb.toString();
+            dynFilter = dynSb.toString();
+            List<String> groupsList = new ArrayList<String>();
+            groupsList.addAll(groupSearch(ctx, getProperty(PARAM_GRPDN), srcFilter, getProperty(PARAM_GRP_TARGET)));
+            // search filter is constructed internally as
+            // as a groupofURLS
+            groupsList.addAll(dynamicGroupSearch(ctx, getProperty(PARAM_GRPDN), dynMember, 
+                    dynFilter, getProperty(PARAM_GRP_TARGET)));
+            return groupsList;
+        } catch (Exception e) {
+             _logger.log(Level.WARNING, "ldaprealm.groupsearcherror",e);
+        } finally {
+            if (ctx != null) {
+                try {
+                    ctx.close();
+                } catch (NamingException e) {
+                    _logger.log(Level.WARNING, "ldaprealm.exception", e);
+                }
+            }
+        }
+        return null;
+    }
+    /**
+     * Returns the name of all the groups that this user belongs to.
+     * Note that this information is only known after the user has
+     * logged in. This is called from web path role verification, though
+     * it should not be.
+     *
+     * @param username Name of the user in this realm whose group listing
+     *     is needed.
+     * @return Enumeration of group names (strings).
+     * @exception InvalidOperationException thrown if the realm does not
+     *     support this operation - e.g. Certificate realm does not support
+     *     this operation.
+     */
+    public Enumeration getGroupNames (String username)
+        throws InvalidOperationException, NoSuchUserException
+    {
+        Vector v = (Vector)groupCache.get(username);
+        if (v == null) {
+            //Note : assuming the username is a userDN here
+            List<String> searchedGrps = getGroups(username);
+            if (searchedGrps != null) {
+                return Collections.enumeration(searchedGrps);
+            }
+            if (_logger.isLoggable(Level.FINE)) {
+                _logger.log(Level.FINE, "No groups available for: "+username);
+            }
+            // we don't load group here as we need to bind ctx to user with
+            // password before doing that and password is not available here
+            return emptyVector.elements();
+        } else {
+            if (groupMapper != null) {
+                Vector ret = new Vector();
+                ret.addAll(v);
+                ArrayList<String> result = new ArrayList<String>();
+                for (Object o : v) {
+                    String grp = (String)o;
+                    ArrayList<String> tmp =this.getMappedGroupNames(grp);
+                    result.addAll(tmp);
+                }
+                ret.addAll(result);
+                return ret.elements();
+            } else {
+                return v.elements();
+            }
+        }
+    }
+
+
+    /**
+     * Set group membership info for a user.
+     *
+     * <P>See bugs 4646133,4646270 on why this is here.
+     *
+     */
+    private void setGroupNames(String username, String[] groups)
+    {
+        Vector v = new Vector(groups.length);
+        for (int i=0; i<groups.length; i++) {
+            v.add(groups[i]);
+        }
+        groupCache.put(username, v);
+    }
+
+    /**
+     * Supports mode=find-bind. See class documentation.
+     *
+     */
+    public String[] findAndBind(String _username, char[] _password)
+        throws LoginException
+    {
+        // do search for user, substituting %s for username
+	_username = RFC2254Encode(_username);
+        StringBuffer sb = new StringBuffer(getProperty(PARAM_SEARCH_FILTER));
+        substitute(sb, SUBST_SUBJECT_NAME, _username);
+        String userid = sb.toString();
+
+        // attempt to bind as the user
+        DirContext ctx = null;
+        String srcFilter = null;
+        String[] grpList = null;
+
+        String dynFilter = null;
+        String dynMember = getProperty(PARAM_DYNAMIC_GRP_TARGET);
+        try {
+            ctx = new InitialDirContext(getLdapBindProps());
+            String realUserDN = userSearch(ctx, getProperty(PARAM_USERDN), userid);
+            if (realUserDN == null) {
+                String msg = sm.getString("ldaprealm.usernotfound", _username);
+                throw new LoginException(msg);
+            }
+
+            boolean bindSuccessful = bindAsUser(realUserDN, _password);
+            if (bindSuccessful == false) {
+                String msg = sm.getString("ldaprealm.bindfailed", realUserDN);
+                throw new LoginException(msg);
+            }
+
+            // search groups using above connection, substituting %d (and %s)
+            sb = new StringBuffer(getProperty(PARAM_GRP_SEARCH_FILTER));
+            StringBuffer dynSb = new StringBuffer(getProperty(PARAM_DYNAMIC_GRP_FILTER));
+
+            substitute(sb, SUBST_SUBJECT_NAME, _username);
+            substitute(sb, SUBST_SUBJECT_DN, realUserDN);
+            substitute(dynSb, SUBST_SUBJECT_NAME, _username);
+            substitute(dynSb, SUBST_SUBJECT_DN, realUserDN);
+
+            srcFilter = sb.toString();
+            dynFilter = dynSb.toString();
+            ArrayList groupsList = new ArrayList();
+            groupsList.addAll(groupSearch(ctx, getProperty(PARAM_GRPDN), srcFilter, getProperty(PARAM_GRP_TARGET)));
+            // search filter is constructed internally as
+            // as a groupofURLS
+            groupsList.addAll(dynamicGroupSearch(ctx, getProperty(PARAM_GRPDN), dynMember,
+                dynFilter, getProperty(PARAM_GRP_TARGET)));          
+            grpList = new String[groupsList.size()];
+            groupsList.toArray(grpList);
+        } catch (Exception e) {
+            LoginException le=new LoginException(e.toString());
+            le.initCause(e);
+            _logger.log(Level.SEVERE, "ldaprealm.exception", le);
+            throw le;
+        } finally {
+            if (ctx != null) {
+                try {
+                    ctx.close();
+                } catch (NamingException e) {}
+            }
+        }
+
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.log(Level.FINE, "LDAP:Group search filter: " + srcFilter);
+            StringBuffer gb = new StringBuffer();
+            gb.append("Group memberships found: ");
+            if (grpList.length > 0) {
+                for (int i=0; i<grpList.length; i++) {
+                    gb.append(" "+grpList[i]);
+                }
+            } else {
+                gb.append("(null)");
+            }
+            if (_logger.isLoggable(Level.FINE)) {
+                _logger.log(Level.FINE, "LDAP: "+ gb.toString());
+            }
+        }
+        grpList = addAssignGroups(grpList);
+        grpList = this.addMappedGroupNames(grpList);
+        setGroupNames(_username, grpList);
+
+        if(_logger.isLoggable(Level.FINE)){
+             _logger.log(Level.FINE, "LDAP: login succeeded for: " + _username);
+        }
+
+        return grpList;
+    }
+
+    /**
+     * Do anonymous search for the user. Should be unique if exists.
+     *
+     */
+    private String userSearch(DirContext ctx, String baseDN, String filter)
+    {
+        if (_logger.isLoggable(Level.FINEST)) {
+            _logger.log(Level.FINE, "search: baseDN: "+ baseDN +
+                           "  filter: " + filter);
+        }
+            
+        String foundDN = null;
+        NamingEnumeration namingEnum = null;
+
+        SearchControls ctls = new SearchControls();
+        ctls.setReturningAttributes(_dnOnly);
+        ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+        ctls.setCountLimit(1);
+
+        try {
+            namingEnum = ctx.search(baseDN, filter, ctls);
+            if (namingEnum.hasMore()) {
+                SearchResult res = (SearchResult)namingEnum.next();
+
+                StringBuffer sb = new StringBuffer();
+                //for dn name with '/'
+                CompositeName compDN = new CompositeName(res.getName());
+                String ldapDN = compDN.get(0);
+                sb.append(ldapDN);
+                
+                if (res.isRelative()) {
+                    sb.append(",");
+                    sb.append(baseDN);
+                }
+                foundDN = sb.toString();
+                if (_logger.isLoggable(Level.FINEST)) {
+                    _logger.log(Level.FINE, "Found user DN: " + foundDN);
+                }
+            }
+        } catch (Exception e) {
+            _logger.log(Level.WARNING, "ldaprealm.searcherror", filter);
+            _logger.log(Level.WARNING, "security.exception", e);
+        } finally {
+            if (namingEnum != null) {
+                try {
+                    namingEnum.close();
+                } catch(Exception ex) {
+                }
+            }
+        }
+
+        return foundDN;
+    }
+
+    /**
+     * Attempt to bind as a specific DN.
+     *
+     */
+    private boolean bindAsUser(String bindDN, char[] password)
+    {
+        boolean bindSuccessful=false;
+
+        Properties p = getLdapBindProps();
+        
+        p.put(Context.SECURITY_PRINCIPAL, bindDN);
+        p.put(Context.SECURITY_CREDENTIALS, new String(password));
+        
+        DirContext ctx = null;
+        try {
+            ctx = new InitialDirContext(p);
+            bindSuccessful = true;
+        } catch (Exception e) {
+            if (_logger.isLoggable(Level.FINEST)) {
+                _logger.finest("Error binding to directory as: " + bindDN);
+                _logger.finest("Exception from JNDI: " + e.toString());
+            }
+        } finally {
+            if (ctx != null) {
+                try {
+                    ctx.close();
+                } catch (NamingException e) {}
+            }
+        }
+        return bindSuccessful;
+    }
+
+    /**
+     * Search for group membership using the given connection.
+     *
+     */
+    private List dynamicGroupSearch(DirContext ctx, String baseDN, 
+            String memberOfAttr, String filter, String target) throws NamingException
+    {        
+        List groupList = new ArrayList();
+        
+        String[] targets = new String[] { memberOfAttr };
+        
+        try {
+            SearchControls ctls = new SearchControls();
+            ctls.setReturningAttributes(targets);
+            ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+            //Set this to false to avoid objects and hence exposing ldap object
+            //injection.
+            ctls.setReturningObjFlag(false);
+            
+            NamingEnumeration e = ctx.search(baseDN, filter, ctls);
+            
+            while(e.hasMore()) {
+                SearchResult res = (SearchResult)e.next();
+                Attribute isMemberOf = res.getAttributes().get(memberOfAttr);
+                if (isMemberOf != null) {
+                    for (Enumeration values = isMemberOf.getAll();
+                            values.hasMoreElements();) {
+                        String groupDN = (String) values.nextElement();
+                        LdapName dn = new LdapName(groupDN);
+                        for(Rdn rdn : dn.getRdns()) {
+                            if(rdn.getType().equalsIgnoreCase(target)) {
+                                groupList.add(rdn.getValue());
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            _logger.log(Level.WARNING, "ldaprealm.searcherror", filter);
+            _logger.log(Level.WARNING, "security.exception", e);
+        }
+        return groupList;
+    }
+
+    /**
+     * Search for group membership using the given connection.
+     *
+     */
+    private List groupSearch(DirContext ctx, String baseDN,
+                                 String filter, String target)
+    {        
+        List groupList = new ArrayList();
+        
+        try {
+            String[] targets = new String[1];
+            targets[0] = target;
+            
+            SearchControls ctls = new SearchControls();
+            ctls.setReturningAttributes(targets);
+            ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+            
+            NamingEnumeration e = ctx.search(baseDN,
+                    filter.replaceAll(Matcher.quoteReplacement("\\"), Matcher.quoteReplacement("\\\\")), ctls);
+            
+            while(e.hasMore()) {
+                SearchResult res = (SearchResult)e.next();
+                Attribute grpAttr = res.getAttributes().get(target);
+                int sz = grpAttr.size();
+                for (int i=0; i<sz; i++) {
+                    String s = (String)grpAttr.get(i);
+                    groupList.add(s);
+                }
+            }
+                
+        } catch (Exception e) {
+            _logger.log(Level.WARNING, "ldaprealm.searcherror", filter);
+            _logger.log(Level.WARNING, "security.exception", e);
+        }
+
+        return groupList;
+    }
+
+    /**
+     * Do string substitution. target is replaced by value for all
+     * occurences.
+     *
+     */
+    private static void substitute(StringBuffer sb,
+                                   String target, String value)
+    {
+        int i = sb.indexOf(target);
+        while (i >= 0) {
+            sb.replace(i, i+target.length(), value);
+            i = sb.indexOf(target);
+        }
+    }
+    /**
+     * Escape special chars in search filter, according to RFC2254
+     * @param inName
+     * @return
+     */
+    private String RFC2254Encode(String inName) {
+
+        int len = inName.length();
+        StringBuffer buf = new StringBuffer(len);
+        for (int i = 0; i < len; i++) {
+            char ch = inName.charAt(i);
+            switch (ch) {
+            case '*' : buf.append("\\2a"); break;
+            case '(' : buf.append("\\28"); break;
+            case ')' : buf.append("\\29"); break;
+            case '\\' : buf.append("\\5c"); break;
+            case 0 : buf.append("\\00"); break;
+            default : buf.append(ch);
+            }
+        }
+        return buf.toString();
+    } 
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/solaris/SolarisRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/solaris/SolarisRealm.java
new file mode 100644
index 0000000..5c7c2a5
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/solaris/SolarisRealm.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.auth.realm.solaris;
+
+import java.util.*;
+
+import java.util.logging.Level;
+
+import com.sun.enterprise.security.auth.realm.IASRealm;
+import com.sun.enterprise.security.auth.realm.BadRealmException;
+import com.sun.enterprise.security.auth.realm.NoSuchUserException;
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import com.sun.enterprise.security.auth.realm.InvalidOperationException;
+import org.jvnet.hk2.annotations.Service;
+
+
+/**
+ * Realm wrapper for supporting Solaris authentication.
+ *
+ * <P>The Solaris realm needs the following properties in its configuration:
+ * <ul>
+ *   <li>jaas-ctx - JAAS context name used to access LoginModule for
+ *       authentication.
+ * </ul>
+ *
+ * @see com.sun.enterprise.security.auth.login.SolarisLoginModule
+ *
+ */
+@Service
+public final class SolarisRealm extends IASRealm
+{
+    // Descriptive string of the authentication type of this realm.
+    public static final String AUTH_TYPE = "solaris";
+    public static final String OS_ARCH = "os.arch";
+    public static final String SOL_SPARC_OS_ARCH = "sparc";
+    public static final String SOL_X86_OS_ARCH = "x86";
+
+    private HashMap groupCache;
+    private Vector emptyVector;
+    private static String osArchType = null;
+
+
+    // Library for native methods
+    static {
+        osArchType = System.getProperty(OS_ARCH);
+        if(SOL_SPARC_OS_ARCH.equals(osArchType)) {
+            System.loadLibrary("solsparcauth");
+        }
+        else if (SOL_X86_OS_ARCH.equals(osArchType)) {
+            System.loadLibrary("solx86auth");
+        }
+    }
+
+    
+    /**
+     * Initialize a realm with some properties.  This can be used
+     * when instantiating realms from their descriptions.  This
+     * method may only be called a single time.  
+     *
+     * @param props Initialization parameters used by this realm.
+     * @exception BadRealmException If the configuration parameters
+     *     identify a corrupt realm.
+     * @exception NoSuchRealmException If the configuration parameters
+     *     specify a realm which doesn't exist.
+     *
+     */
+    public synchronized void init(Properties props)
+        throws BadRealmException, NoSuchRealmException
+    {
+        super.init(props);
+        String jaasCtx = props.getProperty(IASRealm.JAAS_CONTEXT_PARAM);
+        if (jaasCtx == null) {
+            if (_logger.isLoggable(Level.WARNING)) {
+                _logger.warning("realmconfig.noctx");
+            }
+            String msg = sm.getString("solarisrealm.nojaas");
+            throw new BadRealmException(msg);
+        }
+
+        this.setProperty(IASRealm.JAAS_CONTEXT_PARAM, jaasCtx);
+
+        if (_logger.isLoggable(Level.FINE)) {
+            _logger.fine("SolarisRealm : "+IASRealm.JAAS_CONTEXT_PARAM+
+                       "="+jaasCtx);
+        }
+
+        groupCache = new HashMap();
+        emptyVector = new Vector();
+    }
+
+
+    /**
+     * Returns a short (preferably less than fifteen characters) description
+     * of the kind of authentication which is supported by this realm.
+     *
+     * @return Description of the kind of authentication that is directly
+     *     supported by this realm.
+     */
+    public String getAuthType()
+    {
+        return AUTH_TYPE;
+    }
+    
+
+    /**
+     * Returns the name of all the groups that this user belongs to.
+     * This is called from web path role verification, though
+     * it should not be.
+     *
+     * @param username Name of the user in this realm whose group listing
+     *     is needed.
+     * @return Enumeration of group names (strings).
+     * @exception InvalidOperationException thrown if the realm does not
+     *     support this operation - e.g. Certificate realm does not support
+     *     this operation.
+     */
+    public Enumeration getGroupNames (String username)
+        throws InvalidOperationException, NoSuchUserException
+    {
+        Vector v = (Vector)groupCache.get(username);
+        if (v == null) {
+            v = loadGroupNames(username);
+        }
+        
+        return v.elements();
+    }
+
+
+    /**
+     * Set group membership info for a user.
+     *
+     * <P>See bugs 4646133,4646270 on why this is here.
+     *
+     */
+    private void setGroupNames(String username, String[] groups)
+    {
+        Vector v = null;
+        
+        if (groups == null) {
+            v = emptyVector;
+
+        } else {
+            v = new Vector(groups.length + 1);
+            for (int i=0; i<groups.length; i++) {
+                v.add(groups[i]);
+            }
+        }
+        
+        synchronized (this) {
+            groupCache.put(username, v);
+        }
+    }
+
+
+    /**
+     * Invoke the native authentication call.
+     *
+     * @param username User to authenticate.
+     * @param password Given password.
+     * @returns true of false, indicating authentication status.
+     *
+     */
+    public String[] authenticate(String username, char[] password)
+    {
+        String[] grps = nativeAuthenticate(username, new String(password));
+        if(grps != null){
+            grps = addAssignGroups(grps);
+        }
+        setGroupNames(username, grps);
+        return grps;
+    }
+
+
+    /**
+     * Loads groups names for the given user by calling native method.
+     *
+     * <P>Group info is loaded when user authenticates, however in some
+     * cases (such as run-as) the group membership info is needed
+     * without an authentication event.
+     *
+     */
+    private Vector loadGroupNames(String username)
+    {
+        String[] grps = nativeGetGroups(username);
+        if (grps == null) {
+            _logger.fine("No groups returned for user: "+username);
+        }
+        
+        grps = addAssignGroups(grps);
+        setGroupNames(username, grps);
+        return (Vector)groupCache.get(username);
+    }
+
+
+    /**
+     * Native method. Authenticate using PAM.
+     *
+     */
+    private static native String[] nativeAuthenticate(String user,
+                                                     String password);
+    
+    /**
+     * Native method. Retrieve Solaris groups for user.
+     *
+     */
+    private static native String[] nativeGetGroups(String user);
+
+    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/authorize/.gitkeep_empty_dir b/nucleus/security/core/src/main/java/com/sun/enterprise/security/authorize/.gitkeep_empty_dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/authorize/.gitkeep_empty_dir
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CLIUtil.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CLIUtil.java
new file mode 100644
index 0000000..c608fb9
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CLIUtil.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.JaccProvider;
+import com.sun.enterprise.config.serverbeans.MessageSecurityConfig;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.Server;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import java.util.List;
+import org.glassfish.api.ActionReport;
+
+/**
+ *
+ * 
+ */
+public class CLIUtil {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(CLIUtil.class);    
+
+    /**
+     * Selects a config of interest from the domain, based on the target.
+     * (Eliminates duplicated code formerly in Create, Delete, and ListAuthRealm).
+     * 
+     * @param domain
+     * @param target
+     * @return 
+     */
+    static Config chooseConfig(final Domain domain, 
+            final String target) {
+        Config config = null;
+        Config tmp = null;
+        try {
+            tmp = domain.getConfigs().getConfigByName(target);
+        } catch (Exception ex) {
+        }
+
+        if (tmp != null) {
+            return tmp;
+        }
+        Server targetServer = domain.getServerNamed(target);
+        if (targetServer != null) {
+            config = domain.getConfigNamed(targetServer.getConfigRef());
+        }
+        com.sun.enterprise.config.serverbeans.Cluster cluster = domain.getClusterNamed(target);
+        if (cluster != null) {
+            config = domain.getConfigNamed(cluster.getConfigRef());
+        }
+        return config;
+    }
+    
+    static Config chooseConfig(final Domain domain,
+            final String target,
+            final ActionReport report) {
+        final Config config = chooseConfig(domain, target);
+        if (config == null) {
+            report.setMessage(localStrings.getLocalString(
+                "util.noconfigfortarget",
+                "Configuration for target {0} not found.", target));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+        }
+        return config;
+    }
+    
+    static boolean isRealmNew(final SecurityService securityService,
+            final String authRealmName) {
+        
+        // check if there exists an auth realm byt he specified name
+        // if so return failure.
+        List<AuthRealm> authrealms = securityService.getAuthRealm();
+        for (AuthRealm authrealm : authrealms) {
+            if (authrealm.getName().equals(authRealmName)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    static AuthRealm findRealm(final SecurityService securityService,
+            String authRealmName) {
+        // ensure we have the file authrealm
+        
+        if (authRealmName == null) {
+            authRealmName = securityService.getDefaultRealm();
+        }
+        
+        for (AuthRealm authRealm : securityService.getAuthRealm()) {            
+            if (authRealm.getName().equals(authRealmName)) {
+                return authRealm;
+            }
+        }     
+        return null;
+    }
+    
+    static JaccProvider findJaccProvider(final SecurityService securityService,
+            final String jaccProviderName) {
+        final List<JaccProvider> jaccProviders = securityService.getJaccProvider();
+        for (JaccProvider jaccProv : jaccProviders) {
+            if (jaccProv.getName().equals(jaccProviderName)) {
+                return jaccProv;
+            }
+        }
+        return null;
+    }
+    
+    static MessageSecurityConfig findMessageSecurityConfig(final SecurityService securityService,
+            final String authLayer) {
+        List<MessageSecurityConfig> mscs = securityService.getMessageSecurityConfig();        
+        
+        for (MessageSecurityConfig  msc : mscs) {
+            if (msc.getAuthLayer().equals(authLayer)) {
+                return msc;
+            }
+        }
+        return null;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ChangeAdminPassword.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ChangeAdminPassword.java
new file mode 100644
index 0000000..670cac3
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ChangeAdminPassword.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.AdminService;
+import java.lang.annotation.Annotation;
+import java.util.Enumeration;
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import org.glassfish.hk2.api.PerLookup;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.Configs;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.SecureAdmin;
+import com.sun.enterprise.security.auth.realm.file.FileRealm;
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import org.jvnet.hk2.config.types.Property;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.Server;
+import com.sun.enterprise.security.auth.realm.RealmsManager;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import java.util.List;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import org.glassfish.internal.api.Target;
+
+/**
+ * Change Admin Password Command
+ *
+ * Usage: change-admin-password [--user admin_user] [--terse=false] 
+ *        [--echo=false] [--host localhost] [--port 4848|4849] 
+ *        [--secure | -s]
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="change-admin-password")
+@PerLookup
+@I18n("change.admin.password")
+@ExecuteOn({RuntimeType.ALL})
+public class ChangeAdminPassword implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(ChangeAdminPassword.class);    
+
+    @Param(name="password", password=true)
+    private String oldpassword;
+   
+    @Param(name="newpassword", password=true)
+    private String newpassword;
+
+    @Param(name="username", primary=true)
+    private String userName;
+        
+    @Inject
+    private Configs configs;
+    @Inject
+    private Domain domain;
+
+    @Inject
+    private RealmsManager realmsManager;
+    
+    @Inject
+    private AdminService adminService;
+    
+    private SecureAdmin secureAdmin = null;
+    
+    private Config config;
+    
+    @AccessRequired.To("update")
+    private AuthRealm fileAuthRealm;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+        //Issue 17513 Fix - Check for null passwords if secureadmin is enabled
+        secureAdmin = domain.getSecureAdmin();
+        if (SecureAdmin.Util.isEnabled(secureAdmin)) {
+            if ((newpassword == null) || (newpassword.isEmpty())) {
+                report.setMessage(localStrings.getLocalString(
+                        "null_empty_password","The new password is null or empty"));
+                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                return false;
+            }           
+        }
+        final List <Config> configList = configs.getConfig();
+        config = configList.get(0);
+
+        SecurityService securityService = config.getSecurityService();
+       
+        fileAuthRealm = null;        
+        for (AuthRealm authRealm : securityService.getAuthRealm()) {            
+            if (authRealm.getName().equals(adminService.getAuthRealmName())) {                
+                fileAuthRealm = authRealm;            
+                break;
+            }
+        }        
+
+        if (fileAuthRealm == null) {
+            report.setMessage(localStrings.getLocalString(
+                "change.admin.password.adminrealmnotfound", "Server " +
+                "Error: There is no admin realm to perform this operation"));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;                                            
+        }
+        
+        return true;
+    }
+
+    
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+
+        final ActionReport report = context.getActionReport();
+
+        // Get FileRealm class name, match it with what is expected.
+        String fileRealmClassName = fileAuthRealm.getClassname();
+        
+        // Report error if provided impl is not the one expected
+        if (fileRealmClassName != null && 
+            !fileRealmClassName.equals(
+                "com.sun.enterprise.security.auth.realm.file.FileRealm")) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "change.admin.password.adminrealmnotsupported",
+                    "Configured admin realm is not supported."));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;                
+        }
+
+        // ensure we have the file associated with the authrealm
+        String keyFile = null;
+        for (Property fileProp : fileAuthRealm.getProperty()) {
+            if (fileProp.getName().equals("file"))
+                keyFile = fileProp.getValue();
+        }
+        if (keyFile == null) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "change.admin.password.keyfilenotfound",
+                    "There is no physical file associated with admin realm"));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;                                            
+        }
+                            
+        // We have the right impl so let's get to updating existing user 
+        FileRealm fr = null;
+        try {
+            realmsManager.createRealms(config);
+            fr = (FileRealm) realmsManager.getFromLoadedRealms(config.getName(), fileAuthRealm.getName());
+            if (fr == null) {
+                throw new NoSuchRealmException(fileAuthRealm.getName());
+            }
+        }  catch(NoSuchRealmException e) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "change.admin.password.realmnotsupported",
+                    "Configured admin realm does not exist.") +
+                "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+            return;
+        }
+
+        //now updating admin user password
+        try {
+            Enumeration en = fr.getGroupNames(userName);            
+            int size = 0;
+            while (en.hasMoreElements()) { 
+                size++; 
+                en.nextElement(); 
+            }            
+            String[] groups = new String[size];            
+            en = fr.getGroupNames(userName);            
+            for (int i = 0; i < size; i++) {
+                groups[i] = (String) en.nextElement();
+            }
+            fr.updateUser(userName,userName, newpassword.toCharArray(), groups);
+            fr.persist();
+            report.setActionExitCode(ActionReport.ExitCode.SUCCESS);            
+        } catch (Exception e) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "change.admin.password.userupdatefailed",
+                    "Password change failed for user named {0}", userName) +
+                "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+        }        
+    }
+ 
+
+  
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateAuditModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateAuditModule.java
new file mode 100644
index 0000000..0dd1d96
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateAuditModule.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import org.jvnet.hk2.config.types.Property;
+import java.util.List;
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+import com.sun.enterprise.config.serverbeans.Configs;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.AuditModule;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.Server;
+import com.sun.enterprise.security.SecurityConfigListener;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.util.SystemPropertyConstants;
+
+import java.beans.PropertyVetoException;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+
+/**
+ * Create Audit Module Command
+ *
+ * Usage: create-audit-module --classname classnme [--terse=false] 
+ *        [--echo=false] [--interactive=true] [--host localhost] 
+ *        [--port 4848|4849] [--secure | -s] [--user admin_user] 
+ *        [--passwordfile file_name] [--property (name=value)
+ *        [:name=value]*] [--target target(Default server)] audit_module_name
+ *  
+ * domain.xml element example
+ * <audit-module classname="com.foo.security.Audit" name="AM">
+ *     <property name="auditOn" value="false"/>
+ * </audit-module>
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="create-audit-module")
+@PerLookup
+@I18n("create.audit.module")
+@ExecuteOn({RuntimeType.DAS, RuntimeType.INSTANCE})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER,CommandTarget.CONFIG})
+public class CreateAuditModule implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(CreateAuditModule.class);    
+
+    @Param(name="classname")
+    String className;
+
+    @Param(name="auditmodulename", primary=true)
+    String auditModuleName;
+    
+    @Param(optional=true, name="property", separator=':')
+    java.util.Properties properties;   
+    
+    @Param(name = "target", optional = true, defaultValue =
+        SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+
+    @Inject
+    SecurityConfigListener securityConfigListener;
+
+    @AccessRequired.NewChild(type=AuditModule.class)
+    private SecurityService securityService = null;
+    
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        securityService = chooseSecurityService(context.getActionReport());
+        return (securityService != null);
+    }
+
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+
+       
+        // check if there exists an audit module by the specified name
+        // if so return failure.
+        List<AuditModule> ams = securityService.getAuditModule();
+        for (AuditModule am : ams) {
+            if (am.getName().equals(auditModuleName)) {
+                report.setMessage(localStrings.getLocalString(
+                    "create.audit.module.duplicatefound", 
+                    "AuditModule named {0} exists. " +
+                    "Cannot add duplicate AuditModule.", auditModuleName));
+                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                return;
+            }
+        }
+        
+        // No duplicate audit modules found. So add one.
+        try {
+            ConfigSupport.apply(new SingleConfigCode<SecurityService>() {
+
+                public Object run(SecurityService param) 
+                throws PropertyVetoException, TransactionFailure {
+                AuditModule newAuditModule = param.createChild(AuditModule.class);
+                    populateAuditModuleElement(newAuditModule);                    
+                    param.getAuditModule().add(newAuditModule);
+                    return newAuditModule;
+                }
+            }, securityService);
+
+        } catch(TransactionFailure e) {
+            report.setMessage(localStrings.getLocalString("create.audit.module.fail", 
+                    "Creation of AuditModule {0} failed", auditModuleName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+            return;
+        }
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+        //report.setMessage(localStrings.getLocalString("create.audit.module.success",
+        //    "Creation of AuditModule {0} completed successfully", auditModuleName));
+    }       
+    
+    private SecurityService chooseSecurityService(final ActionReport report) {
+        config = CLIUtil.chooseConfig(domain, target, report);
+        if (config == null) {
+            return null;
+        }
+        return config.getSecurityService();
+    }
+    
+    private void populateAuditModuleElement(AuditModule newAuditModule) 
+    throws PropertyVetoException, TransactionFailure {
+        newAuditModule.setName(auditModuleName);
+        newAuditModule.setClassname(className);
+        if (properties != null) {
+            for (Object propname: properties.keySet()) {
+                Property newprop = newAuditModule.createChild(Property.class);
+                newprop.setName((String) propname);
+                newprop.setValue(properties.getProperty((String) propname));            
+                newAuditModule.getProperty().add(newprop);    
+            }
+        }
+    }    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateAuthRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateAuthRealm.java
new file mode 100644
index 0000000..367577c
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateAuthRealm.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import java.util.List;
+import java.util.Properties;
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+import org.jvnet.hk2.config.types.Property;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Configs;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.Server;
+import com.sun.enterprise.security.SecurityConfigListener;
+import com.sun.enterprise.security.common.Util;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+
+import com.sun.enterprise.util.SystemPropertyConstants;
+import java.beans.PropertyVetoException;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.PropertyResolver;
+import org.glassfish.config.support.TargetType;
+import org.glassfish.internal.api.RelativePathResolver;
+
+
+/**
+ * CLI command to create JACC Provider
+ *
+ * Usage: create-auth-realm --classname realm_class [--terse=false] 
+ *        [--interactive=true] [--host localhost] [--port 4848|4849] 
+ *        [--secure | -s] [--user admin_user] [--passwordfile file_name] 
+ *        [--property (name=value)[:name=value]*] 
+ *        [--echo=false] [--target target(Default server)] auth_realm_name
+ *  
+ * domain.xml element example
+ * <auth-realm name="file" 
+ *   classname="com.sun.enterprise.security.auth.realm.file.FileRealm">
+ *   <property name="file" value="${com.sun.aas.instanceRoot}/config/keyfile"/>
+ *   <property name="jaas-context" value="fileRealm"/>
+ * </auth-realm>
+ *       Or
+ * <auth-realm name="certificate" 
+ *   classname="com.sun.enterprise.security.auth.realm.certificate.CertificateRealm">
+ * </auth-realm>
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="create-auth-realm")
+@PerLookup
+@I18n("create.auth.realm")
+@ExecuteOn({RuntimeType.DAS, RuntimeType.INSTANCE})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER, CommandTarget.CONFIG})
+public class CreateAuthRealm implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(CreateAuthRealm.class);    
+
+    @Param(name="classname")
+    private String className;
+
+    @Param(name="authrealmname", primary=true)
+    private String authRealmName;
+    
+    @Param(optional=true, name="property", separator=':')
+    private Properties properties;
+    
+    @Param(name = "target", optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Configs configs;
+
+    @Inject
+    private Domain domain;
+    @Inject
+    private SecurityConfigListener securityListener;
+    
+    //initialize the habitat in Util needed by Realm classes
+    @Inject
+    private Util util;
+    
+    @AccessRequired.NewChild(type=AuthRealm.class)
+    private SecurityService securityService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        securityService = config.getSecurityService();
+        if ( ! ensureRealmIsNew(context.getActionReport())) {
+            return false;
+        }
+        return true;
+    }
+
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+
+        // No duplicate auth realms found. So add one.
+        try {
+            ConfigSupport.apply(new SingleConfigCode<SecurityService>() {
+
+                public Object run(SecurityService param) 
+                throws PropertyVetoException, TransactionFailure {
+                AuthRealm newAuthRealm = param.createChild(AuthRealm.class);
+                    populateAuthRealmElement(newAuthRealm);
+                    param.getAuthRealm().add(newAuthRealm);
+                    //In case of cluster instances, this is required to
+                    //avoid issues with the listener's callback method
+                    SecurityConfigListener.authRealmCreated(config, newAuthRealm);
+                    return newAuthRealm;
+                    
+                }
+            }, securityService);
+        } catch(TransactionFailure e) {
+            report.setMessage(localStrings.getLocalString("create.auth.realm.fail", 
+                    "Creation of Authrealm {0} failed", authRealmName) +
+                              "  " + e.getLocalizedMessage() );
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+            return;
+        }
+
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+    }       
+    
+    private void populateAuthRealmElement(AuthRealm newAuthRealm) 
+    throws PropertyVetoException, TransactionFailure {
+        newAuthRealm.setName(authRealmName);
+        newAuthRealm.setClassname(className);
+        if (properties != null) {
+            for (Object propname: properties.keySet()) {
+                Property newprop = newAuthRealm.createChild(Property.class);
+                newprop.setName((String) propname);
+                String propValue = properties.getProperty((String) propname);
+                newprop.setValue(propValue);
+                newAuthRealm.getProperty().add(newprop);    
+            }
+        }
+    }
+    
+    private boolean ensureRealmIsNew(final ActionReport report){
+        if ( ! CLIUtil.isRealmNew(securityService, authRealmName)) {
+            report.setMessage(localStrings.getLocalString(
+                "create.auth.realm.duplicatefound", 
+                "Authrealm named {0} exists. Cannot add duplicate AuthRealm.", 
+                authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateFileUser.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateFileUser.java
new file mode 100644
index 0000000..6fcb5bd
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateFileUser.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.AdminService;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.types.Property;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.SecureAdmin;
+import com.sun.enterprise.security.auth.realm.file.FileRealm;
+import com.sun.enterprise.security.auth.realm.Realm;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.security.auth.realm.BadRealmException;
+import com.sun.enterprise.security.auth.realm.RealmsManager;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import java.beans.PropertyVetoException;
+import java.io.File;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+
+/**
+ * Create File User Command
+ * Usage: create-file-user [--terse=false] [--echo=false] [--interactive=true] 
+ *        [--host localhost] [--port 4848|4849] [--secure | -s] 
+ *        [--user admin_user] [--userpassword admin_passwd] 
+ *        [--passwordfile file_name] [--groups user_groups[:user_groups]*] 
+ *        [--authrealmname authrealm_name] [--target target(Default server)] 
+ *        username 
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="create-file-user")
+@PerLookup
+@I18n("create.file.user")
+@ExecuteOn({RuntimeType.ALL})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER, CommandTarget.CONFIG})
+@RestEndpoints({
+    @RestEndpoint(configBean=AuthRealm.class,
+        opType=RestEndpoint.OpType.POST, 
+        path="create-user", 
+        description="Create",
+        params={
+            @RestParam(name="authrealmname", value="$parent")
+        })
+})
+public class CreateFileUser implements /*UndoableCommand*/ AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(CreateFileUser.class);    
+
+    @Param(name="groups", optional=true, separator=':')
+    private List<String> groups = new ArrayList<String>(0); //by default, an empty list is better than a null
+
+    //TODO: this is still a String, need to convert to char[]
+    @Param(name="userpassword", password=true)
+    private String userpassword;
+
+    @Param(name="authrealmname", optional=true)
+    private String authRealmName;
+    
+    @Param(name = "target", optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Param(name="username", primary=true)
+    private String userName;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+
+    @Inject
+    private RealmsManager realmsManager;
+
+    @Inject
+    private ServerEnvironment se;
+    
+    @Inject
+    private AdminService adminService;
+    
+    private SecureAdmin secureAdmin = null;
+    
+    @AccessRequired.To("update")
+    private AuthRealm fileAuthRealm;
+    
+    private SecurityService securityService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        securityService = config.getSecurityService();
+        fileAuthRealm = CLIUtil.findRealm(securityService, authRealmName);
+        if (fileAuthRealm == null) {
+            final ActionReport report = context.getActionReport();
+            report.setMessage(localStrings.getLocalString(
+                "create.file.user.filerealmnotfound",
+                "File realm {0} does not exist", 
+                authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;                                            
+        }
+        /*
+         * The realm might have been defaulted, so capture the actual name.
+         */
+        authRealmName = fileAuthRealm.getName();
+        return true;
+    }
+    
+    
+
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        
+        final ActionReport report = context.getActionReport();
+
+        
+        
+        // Get FileRealm class name, match it with what is expected.
+        String fileRealmClassName = fileAuthRealm.getClassname();
+
+        // Report error if provided impl is not the one expected
+        if (fileRealmClassName != null && 
+            !fileRealmClassName.equals(
+                "com.sun.enterprise.security.auth.realm.file.FileRealm")) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "create.file.user.realmnotsupported",
+                    "Configured file realm {0} is not supported.", 
+                    fileRealmClassName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;                
+        }
+        // ensure we have the file associated with the authrealm
+        String keyFile = null;
+        for (Property fileProp : fileAuthRealm.getProperty()) {
+            if (fileProp.getName().equals("file"))
+                keyFile = fileProp.getValue();
+        }
+        final String kf = keyFile;
+        if (keyFile == null) {
+            report.setMessage(
+                localStrings.getLocalString("create.file.user.keyfilenotfound",
+                "There is no physical file associated with this file realm {0} ", 
+                authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;                                            
+        }
+        boolean exists = (new File(kf)).exists();
+        if (!exists) {
+            report.setMessage(
+                localStrings.getLocalString("file.realm.keyfilenonexistent",
+                "The specified physical file {0} associated with the file realm {1} does not exist.",
+                new Object[]{kf, authRealmName}));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;
+        }
+        // Now get all inputs ready. userid and groups are straightforward but
+        // password is tricky. It is stored in the file passwordfile passed 
+        // through the CLI options. It is stored under the name 
+        // AS_ADMIN_USERPASSWORD. Fetch it from there.
+        final String password = userpassword; // fetchPassword(report);
+        if (password == null) {
+            report.setMessage(localStrings.getLocalString(
+               "create.file.user.keyfilenotreadable", "Password for user {0} " +
+               "has to be specified in --userpassword option or supplied " +
+               "through AS_ADMIN_USERPASSWORD property in the file specified " +
+               "in --passwordfile option", userName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;
+        }
+        
+        //Issue 17525 Fix - Check for null passwords for admin-realm if secureadmin is enabled
+        secureAdmin = domain.getSecureAdmin();
+        if ((SecureAdmin.Util.isEnabled(secureAdmin))
+                && (authRealmName.equals(adminService.getAuthRealmName()))) {
+            if (password.isEmpty()) {
+                report.setMessage(localStrings.getLocalString(
+                        "null_empty_password","The admin user password is null or empty"));
+                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                return;
+            }           
+        }
+        // now adding user
+        try {
+            //even though create-file-user is not an update to the security-service
+            //do we need to make it transactional by referncing the securityservice
+            //hypothetically ?.
+            ConfigSupport.apply(new SingleConfigCode<SecurityService>() {
+
+                public Object run(SecurityService param)
+                        throws PropertyVetoException, TransactionFailure {
+                    try {
+                        realmsManager.createRealms(config);
+                        //If the (shared) keyfile is updated by an external process, load the users first
+                        refreshRealm(config.getName(),authRealmName);
+                        final FileRealm fr = (FileRealm) realmsManager.getFromLoadedRealms(config.getName(),authRealmName);
+                        CreateFileUser.handleAdminGroup(authRealmName, groups);
+                        String[] groups1 = groups.toArray(new String[groups.size()]);
+                        try {
+                            fr.addUser(userName, password.toCharArray(), groups1);
+                        }catch(BadRealmException br) {
+                            //Check if the server environment is  DAS. If is not  DAS (user creation was
+                            //successful on DAS), then the error is caused in the instances because of shared keyfile between
+                            // DAS and cluster instances - ignore the exception for instances.
+
+                            if(se != null && se.isDas()) {
+                                throw new BadRealmException(br);
+                            }
+                        }
+                        fr.persist();
+                        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+                    } catch (Exception e) {
+                        String localalizedErrorMsg = (e.getLocalizedMessage() == null)?"":e.getLocalizedMessage();
+                        report.setMessage(
+                                localStrings.getLocalString("create.file.user.useraddfailed",
+                                "Adding User {0} to the file realm {1} failed",
+                                userName, authRealmName) + "  " + localalizedErrorMsg);
+                        report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                        report.setFailureCause(e);
+                    }
+                    return null;
+                }
+            }, securityService);
+
+        } catch (Exception e) {
+            report.setMessage(
+                    localStrings.getLocalString("create.file.user.useraddfailed",
+                    "Adding User {0} to the file realm {1} failed",
+                    userName, authRealmName) + "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+        }
+    }
+
+    /* private String fetchPassword(ActionReport report) {
+       String password = null;
+       if (userpassword != null && passwordFile != null)
+           return password;
+       if (userpassword != null)
+           password = userpassword;
+       if (passwordFile != null) {
+           File passwdFile = new File(passwordFile);
+           InputStream is = null;
+           try {
+               is = new BufferedInputStream(new FileInputStream(passwdFile));
+               Properties prop = new Properties();
+               prop.load(is);
+               for (Enumeration e=prop.propertyNames(); e.hasMoreElements();) {
+                   String entry = (String)e.nextElement();
+                   if (entry.equals("AS_ADMIN_USERPASSWORD")) {
+                       password = prop.getProperty(entry);
+                       break;
+                   }
+               }
+           } catch(Exception e) {
+               report.setFailureCause(e);
+           } finally {
+               try {
+                   if (is != null)
+                       is.close();
+               } catch(final Exception ignore){}
+           }
+       }
+       return password;
+   } */
+
+    public static void refreshRealm(String configName, String realmName) {
+        if (realmName != null && realmName.length() > 0) {
+            try {
+                Realm realm = Realm.getInstance(configName, realmName);
+
+                if (realm != null) {
+                    realm.refresh(configName);
+                }
+            } catch (com.sun.enterprise.security.auth.realm.NoSuchRealmException nre) {
+                //	    _logger.fine("Realm: "+realmName+" is not configured");
+            } catch (com.sun.enterprise.security.auth.realm.BadRealmException bre) {
+                //	    _logger.fine("Realm: "+realmName+" is not configured");
+            }
+        }
+    }
+    static void handleAdminGroup(String lr, List<String> lg) {
+        String fr = "admin-realm";   //this should be a constant defined at a central place -- the name of realm for admin
+        String fg = "asadmin";       //this should be a constant defined at a central place -- fixed name of admin group
+        if (fr.equals(lr) && lg != null) {
+            lg.clear();             //basically, we are ignoring the group specified on command line when it's admin realm
+            lg.add(fg);
+        }
+    }
+
+//    @Override
+//    public ActionReport prepare(ParameterMap parameters) {
+//        //TODO: is there a way to check if in a Cluster some
+//        //instances are down
+////        com.sun.enterprise.config.serverbeans.Cluster cluster = domain.getClusterNamed(target);
+////        if (cluster!=null) {
+////            List<Server> servers = cluster.getInstances();
+////        }
+//        final ActionReport report = new ActionReport();
+//    }
+//
+//    @Override
+//    public void undo(ParameterMap parameters) {
+//        throw new UnsupportedOperationException("Not supported yet.");
+//    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateJACCProvider.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateJACCProvider.java
new file mode 100644
index 0000000..c90d6f3
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateJACCProvider.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.JaccProvider;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import java.beans.PropertyVetoException;
+import java.util.Properties;
+import org.glassfish.api.ActionReport;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+
+/**
+ * Create Jacc Provider Command
+ *
+ * Usage: create-jacc-provider   --policyconfigfactoryclass pc_factory_class
+ *         --policyproviderclass pol_provider_class
+ *         [--help] [--user admin_user] [--passwordfile file_name]
+ *         [ --property (name=value)[:name=value]*]
+ *         [ --target  target_name] jacc_provider_name
+ *
+ *
+ * domain.xml element example
+ *   <jacc-provider policy-provider="com.sun.enterprise.security.provider.PolicyWrapper" name="default" policy-configuration-factory-provider="com.sun.enterprise.security.provider.PolicyConfigurationFactoryImpl">
+ *         <property name="repository" value="${com.sun.aas.instanceRoot}/generated/policy" />
+ *   </jacc-provider>
+ *
+ */
+@Service(name="create-jacc-provider")
+@PerLookup
+@I18n("create.jacc.provider")
+@ExecuteOn({RuntimeType.DAS, RuntimeType.INSTANCE})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER, CommandTarget.CONFIG})
+public class CreateJACCProvider implements AdminCommand, AdminCommandSecurity.Preauthorization {
+
+    final private static LocalStringManagerImpl localStrings =
+        new LocalStringManagerImpl(CreateJACCProvider.class);
+
+    @Param(name="policyconfigfactoryclass", alias="policyConfigurationFactoryProvider")
+    private String polConfFactoryClass;
+
+    @Param(name="policyproviderclass", alias="policyProvider")
+    private String polProviderClass;
+
+    @Param(name="jaccprovidername", primary=true)
+    private String jaccProviderName;
+
+    @Param(optional=true, name="property", separator=':')
+    private Properties properties;
+
+    @Param(name = "target", optional = true,  defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+
+    @AccessRequired.NewChild(type=JaccProvider.class)
+    private SecurityService securityService;
+    
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        securityService = config.getSecurityService();
+        JaccProvider jaccProvider = CLIUtil.findJaccProvider(securityService, jaccProviderName);
+        if (jaccProvider != null) {
+            final ActionReport report = context.getActionReport();
+            report.setMessage(localStrings.getLocalString(
+                    "create.jacc.provider.duplicatefound",
+                    "JaccProvider named {0} exists. Cannot add duplicate JaccProvider.",
+                    jaccProviderName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;
+        }
+        return true;
+    }
+    
+    @Override
+    public void execute(AdminCommandContext context) {
+       final ActionReport report = context.getActionReport();
+
+        // No duplicate auth realms found. So add one.
+        try {
+            ConfigSupport.apply(new SingleConfigCode<SecurityService>() {
+
+                public Object run(SecurityService param)
+                        throws PropertyVetoException, TransactionFailure {
+                    JaccProvider newJacc = param.createChild(JaccProvider.class);
+                    newJacc.setName(jaccProviderName);
+                    newJacc.setPolicyConfigurationFactoryProvider(polConfFactoryClass);
+                    newJacc.setPolicyProvider(polProviderClass);
+                    param.getJaccProvider().add(newJacc);
+                    return newJacc;
+                }
+            }, securityService);
+
+        } catch(TransactionFailure e) {
+            report.setMessage(localStrings.getLocalString("create.auth.realm.fail",
+                    "Creation of Authrealm {0} failed", jaccProviderName) +
+                              "  " + e.getLocalizedMessage() );
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+            return;
+        }
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateMessageSecurityProvider.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateMessageSecurityProvider.java
new file mode 100644
index 0000000..9b5cb91
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateMessageSecurityProvider.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import org.jvnet.hk2.config.types.Property;
+import com.sun.enterprise.config.serverbeans.RequestPolicy;
+import java.util.List;
+import java.util.Properties;
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.MessageSecurityConfig;
+import com.sun.enterprise.config.serverbeans.ProviderConfig;
+import com.sun.enterprise.config.serverbeans.ResponsePolicy;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.util.SystemPropertyConstants;
+
+import java.beans.PropertyVetoException;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import org.jvnet.hk2.config.ConfigListener;
+
+/**
+ * Create Message Security Provider Command
+ * 
+ * Usage: create-message-security-provider [--terse=false] [--echo=false] 
+ *        [--interactive=true] [--host localhost] [--port 4848|4849] 
+ *        [--secure | -s] [--user admin_user] [--passwordfile file_name] 
+ *        [--target target(Default server)] [--layer message_layer=SOAP] 
+ *        [--providertype provider_type] [--requestauthsource request_auth_source] 
+ *        [--requestauthrecipient request_auth_recipient] 
+ *        [--responseauthsource response_auth_source] 
+ *        [--responseauthrecipient response_auth_recipient] [--isdefaultprovider] 
+ *        [--property (name=value)[:name=value]*] --classname provider_class 
+ *        provider_name
+ *  
+ * domain.xml element example
+ *  
+ *  <message-security-config auth-layer="SOAP">
+ *      <!-- turned off by default -->
+ *      <provider-config class-name="com.sun.wss.provider.ClientSecAuthModule" 
+ *                       provider-id="XWS_ClientProvider" provider-type="client">
+ *      <request-policy auth-source="content"/>
+ *      <response-policy auth-source="content"/>
+ *      <property name="encryption.key.alias" value="s1as"/>
+ *      <property name="signature.key.alias" value="s1as"/>
+ *      <property name="dynamic.username.password" value="false"/>
+ *      <property name="debug" value="false"/>
+ *      </provider-config>
+ *  </message-security-config>
+ *
+ *  @author Nandini Ektare
+ */
+
+@Service(name="create-message-security-provider")
+@PerLookup
+@I18n("create.message.security.provider")
+@ExecuteOn({RuntimeType.DAS, RuntimeType.INSTANCE})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER,CommandTarget.CONFIG})
+public class CreateMessageSecurityProvider implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(CreateMessageSecurityProvider.class);    
+    
+    private static final String SERVER = "server";
+    private static final String CLIENT = "client";
+    private static final String CLIENT_SERVER = "client-server";
+    
+    // auth-layer can only be SOAP | HttpServlet
+    @Param(name="layer", acceptableValues="SOAP,HttpServlet", 
+           defaultValue="SOAP")
+    String authLayer;
+    
+    // provider-type can only be - client | server | 'client-server' 
+    @Param(name="providertype", acceptableValues="client,server,client-server", 
+           optional=true, defaultValue="client-server")
+    String providerType;
+    
+    // auth-source can only be - sender | content
+    @Param(name="requestauthsource", optional=true)
+    String requestAuthSource;
+   
+    // auth-recipient can only be - before-content | after-content
+    @Param(name="requestauthrecipient", optional=true)
+    String requestAuthRecipient;
+    
+    // auth-source can only be - sender | content
+    @Param(name="responseauthsource", optional=true)
+    String responseAuthSource;
+    
+    // auth-recipient can only be - before-content | after-content
+    @Param(name="responseauthrecipient", optional=true)
+    String responseAuthRecipient;    
+
+    // isdefaultprovider can only be - client | server | 'client-server' 
+    @Param(name="isdefaultprovider", optional=true, defaultValue="false")
+    Boolean isDefaultProvider;
+
+    @Param(optional=true, name="property", separator=':')
+    Properties properties;
+    
+    @Param(name="classname")
+    String providerClass;
+
+    @Param(name="providername", primary=true)
+    String providerId;
+    
+    @Param(name = "target", optional = true, defaultValue =
+        SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+    @Inject
+    private Domain domain;
+
+    @AccessRequired.NewChild(type=MessageSecurityConfig.class)
+    private SecurityService secService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        secService = config.getSecurityService();
+        return true;
+    }
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are parameter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+
+        List<MessageSecurityConfig> mscs = secService.getMessageSecurityConfig();
+        
+        // Let's find the correct MessageSecurityConfig. As of now, 
+        // there can be only two of them - one for SOAP and one for 
+        // HttpServlet
+        MessageSecurityConfig msgSecCfg = null;
+        for (MessageSecurityConfig  msc : mscs) {
+            if (msc.getAuthLayer().equals(authLayer)) {
+                msgSecCfg = msc;
+            }
+        }
+
+        // If there is message security config for this type of layer
+        // then, add a new provider config under it provided it is not duplicate
+        if (msgSecCfg != null) {            
+            // check if there exists a provider config by the  
+            // specified provider name; if so return failure.
+            List<ProviderConfig> pcs = msgSecCfg.getProviderConfig();
+            for (ProviderConfig pc : pcs) {
+                if (pc.getProviderId().equals(providerId)) {            
+                    report.setMessage(localStrings.getLocalString(
+                        "create.message.security.provider.duplicatefound", 
+                        "Message security provider named {0} exists. " +
+                        "Cannot add duplicate.", providerId));
+                    report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                    return;
+                }
+            }
+        
+            // No duplicate message security providers found. So add one.
+            try {
+                ConfigSupport.apply(new SingleConfigCode<MessageSecurityConfig>() {
+                    public Object run(MessageSecurityConfig param) 
+                    throws PropertyVetoException, TransactionFailure {                        
+                        ProviderConfig newPC = param.createChild(ProviderConfig.class);
+                        populateProviderConfigElement(newPC);                    
+                        param.getProviderConfig().add(newPC);
+                        // Depending on the providerType of the new provider
+                        // the isDefaultProvider=true results in creation of
+                        // either default-provider attribute or 
+                        // default-client-provider or BOTH in the message 
+                        // security config object
+                        if (isDefaultProvider) {
+                            if (providerType.equals(SERVER) || 
+                                providerType.equals(CLIENT_SERVER) )
+                            param.setDefaultProvider(providerId);
+                            
+                            if (providerType.equals(CLIENT) || 
+                                providerType.equals(CLIENT_SERVER) )
+                            param.setDefaultClientProvider(providerId);
+                        }
+                        return newPC;
+                    }
+                }, msgSecCfg);
+            } catch(TransactionFailure e) {
+                report.setMessage(localStrings.getLocalString(
+                    "create.message.security.provider.fail", 
+                    "Creation of message security provider named {0} failed", 
+                    providerId));
+                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                report.setFailureCause(e);        
+                return;
+            }        
+            report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+            report.setMessage(localStrings.getLocalString(
+                "create.message.security.provider.success",
+                "Creation of message security provider named {0} completed " +
+                "successfully", providerId));        
+        } 
+        // Now if there is NO message security config for this type of layer
+        // then, first add a message security config for the layer and then
+        // add a provider config under this message security config
+        else {
+            try {
+                ConfigSupport.apply(new SingleConfigCode<SecurityService>() {
+                    public Object run(SecurityService param) 
+                    throws PropertyVetoException, TransactionFailure {                        
+                        MessageSecurityConfig newMSC = param.createChild(MessageSecurityConfig.class);
+                        newMSC.setAuthLayer(authLayer);
+                        param.getMessageSecurityConfig().add(newMSC);
+
+                        ProviderConfig newPC = newMSC.createChild(ProviderConfig.class);
+                        
+                        populateProviderConfigElement(newPC);                    
+                        newMSC.getProviderConfig().add(newPC);
+                        // Depending on the providerType of the new provider
+                        // the isDefaultProvider=true results in creation of
+                        // either default-provider attribute or 
+                        // default-client-provider or BOTH in the message 
+                        // security config object
+                        if (isDefaultProvider) {
+                            if (providerType.equals(SERVER) || 
+                                providerType.equals(CLIENT_SERVER) )
+                            newMSC.setDefaultProvider(providerId);
+                            
+                            if (providerType.equals(CLIENT) || 
+                                providerType.equals(CLIENT_SERVER) )
+                            newMSC.setDefaultClientProvider(providerId);
+                        }
+                        return newMSC;
+                    }
+                }, secService);
+            } catch(TransactionFailure e) {
+                report.setMessage(localStrings.getLocalString(
+                    "create.message.security.provider.fail", 
+                    "Creation of message security provider named {0} failed", 
+                    providerId));
+                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                report.setFailureCause(e);        
+                return;
+            }        
+            report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+           /* report.setMessage(localStrings.getLocalString(
+                "create.message.security.provider.success",
+                "Creation of message security provider named {0} completed " +
+                "successfully", providerId));  */
+        }        
+    }       
+    
+    private void populateProviderConfigElement(ProviderConfig newProviderConfig) 
+    throws PropertyVetoException, TransactionFailure {
+        
+        newProviderConfig.setClassName(providerClass);
+        newProviderConfig.setProviderId(providerId);
+        newProviderConfig.setProviderType(providerType);
+        
+        // create a new RequestPolicy config and add as child of this 
+        // new Provider Config
+        RequestPolicy reqPolicy = newProviderConfig.createChild(RequestPolicy.class);
+        reqPolicy.setAuthSource(requestAuthSource);
+        reqPolicy.setAuthRecipient(requestAuthRecipient);        
+        newProviderConfig.setRequestPolicy(reqPolicy);
+        
+        // create a new ResponsePolicy config and add as child of this 
+        // new Provider Config
+        ResponsePolicy respPolicy = newProviderConfig.createChild(ResponsePolicy.class);
+        respPolicy.setAuthSource(responseAuthSource);
+        respPolicy.setAuthRecipient(responseAuthRecipient);        
+        newProviderConfig.setResponsePolicy(respPolicy);
+        
+        // add properties
+        if (properties != null) {
+            for (Object propname: properties.keySet()) {
+                Property newprop = newProviderConfig.createChild(Property.class);
+                newprop.setName((String) propname);
+                newprop.setValue(properties.getProperty((String) propname));            
+                newProviderConfig.getProperty().add(newprop);    
+            }
+        }
+    }    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreatePasswordAlias.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreatePasswordAlias.java
new file mode 100644
index 0000000..77ea5db
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreatePasswordAlias.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.security.store.DomainScopedPasswordAliasStore;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import org.glassfish.hk2.api.PerLookup;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import javax.inject.Inject;
+
+/**
+ * Create Password Alias Command
+ *
+ * Usage: create-password-alias [--terse=false] [--echo=false] 
+ *        [--interactive=true] [--host localhost] [--port 4848|4849] 
+ *        [--secure | -s] [--user admin_user] [--passwordfile file_name] aliasname
+ *  
+ * Result of the command is that:
+ * <domain-dir>/<domain-name>/config/domain-passwords file gets appended with 
+ * the entry of the form: aliasname=<password encrypted with masterpassword>
+ *
+ * A user can use this aliased password now in setting passwords in domain.xml.
+ * Benefit is it is in NON-CLEAR-TEXT
+ *
+ * domain.xml example entry is:
+ * <provider-config class-name="com.sun.xml.wss.provider.ClientSecurityAuthModule" 
+ *                  provider-id="XWS_ClientProvider" provider-type="client">
+ *      <property name="password" value="${ALIAS=myalias}/>
+ * </provider-config> 
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="create-password-alias")
+@PerLookup
+@I18n("create.password.alias")
+@ExecuteOn(RuntimeType.ALL)
+@TargetType({CommandTarget.DAS,CommandTarget.DOMAIN})
+@RestEndpoints({
+    @RestEndpoint(configBean=Domain.class,
+        opType=RestEndpoint.OpType.POST, 
+        path="create-password-alias", 
+        description="create-password-alias")
+})
+@AccessRequired(resource="domain/passwordAliases", action="create")
+public class CreatePasswordAlias implements AdminCommand {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(CreatePasswordAlias.class);    
+
+    @Param(name="aliasname", primary=true)
+    private String aliasName;
+    
+    @Param(name="aliaspassword", password=true)
+    private String aliasPassword;
+
+    @Inject
+    private DomainScopedPasswordAliasStore domainPasswordAliasStore;
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are parameter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+        
+        try {
+            if (domainPasswordAliasStore.containsKey(aliasName)) {
+                report.setMessage(localStrings.getLocalString(
+                    "create.password.alias.alreadyexists",
+                    "Password alias with the specified name already exists. " +
+                    "Please use the update-password-alias command to change it",
+                    aliasName));
+                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                return;
+            }
+
+            domainPasswordAliasStore.put(aliasName, aliasPassword.toCharArray());
+
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            report.setMessage(localStrings.getLocalString(
+                "create.password.alias.fail", 
+                "Creation of Password Alias {0} failed", aliasName)+
+                              "  " + ex.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(ex);
+            return;            
+        }
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+        /*report.setMessage(localStrings.getLocalString(
+            "create.password.alias.success",
+            "Encrypted password for the alias name {0} stored successfully",
+            aliasName)); */
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteAuditModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteAuditModule.java
new file mode 100644
index 0000000..a9aa9f7
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteAuditModule.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.AuditModule;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Configs;
+import com.sun.enterprise.config.serverbeans.Domain;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.Server;
+import com.sun.enterprise.security.SecurityConfigListener;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.util.SystemPropertyConstants;
+
+import java.beans.PropertyVetoException;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+
+/**
+ * Delete Audit Module Command
+ * 
+* Usage: delete-audit-module [--terse=false] [--echo=false] 
+ *        [--interactive=true] [--host localhost] [--port 4848|4849] 
+ *        [--secure | -s] [--user admin_user] [--passwordfile file_name] 
+ *        [--target target(Default server)] auth_realm_name
+ *
+ * @author Nandini Ektare
+ */
+@Service(name="delete-audit-module")
+@PerLookup
+@I18n("delete.audit.module")
+@ExecuteOn({RuntimeType.DAS, RuntimeType.INSTANCE})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER,CommandTarget.CONFIG})
+public class DeleteAuditModule implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(DeleteAuditModule.class);
+
+    @Param(name="auditmodulename", primary=true)
+    String auditModuleName;
+
+    @Param(name = "target", optional = true, defaultValue =
+        SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+
+    @AccessRequired.To(value="delete")
+    private AuditModule auditModule = null;
+
+    @Inject
+    SecurityConfigListener securityConfigListener;
+    
+    private SecurityService securityService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        auditModule = chooseAuditModule(context.getActionReport());
+        return true;
+    }
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        
+        ActionReport report = context.getActionReport();
+
+        try {            
+            if (auditModule == null) {
+                report.setMessage(localStrings.getLocalString(
+                    "delete.audit.module.notfound", 
+                    "Specified Audit Module {0} not found", auditModuleName));
+                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                return;
+            }
+
+            ConfigSupport.apply(new SingleConfigCode<SecurityService>() {
+                public Object run(SecurityService param) 
+                throws PropertyVetoException, TransactionFailure {
+                    
+                    param.getAuditModule().remove(auditModule);
+                    return null;
+                }
+            }, securityService);
+        } catch(TransactionFailure e) {
+            report.setMessage(localStrings.getLocalString(
+                "delete.audit.module.fail", "Deletion of Audit Module {0} failed", 
+                auditModuleName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+        }
+
+        /*report.setMessage(localStrings.getLocalString("delete.audit.module.success",
+            "Deletion of Audit Module {0} completed successfully", auditModuleName));*/
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+    }
+    
+    private AuditModule chooseAuditModule(final ActionReport report) {
+        config = CLIUtil.chooseConfig(domain, target, report);
+        if (config == null) {
+            return null;
+        }
+        securityService = config.getSecurityService();
+        for (AuditModule am : securityService.getAuditModule()) {
+                if (am.getName().equals(auditModuleName)) {
+                    return am;
+                }
+        }
+        return null;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteAuthRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteAuthRealm.java
new file mode 100644
index 0000000..d0a0279
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteAuthRealm.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Domain;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.security.SecurityConfigListener;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+
+import com.sun.enterprise.util.SystemPropertyConstants;
+import java.beans.PropertyVetoException;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+
+/**
+ * Delete Auth Realm Command
+ * 
+* Usage: delete-auth-realm [--terse=false] [--echo=false] 
+ *        [--interactive=true] [--host localhost] [--port 4848|4849] 
+ *        [--secure | -s] [--user admin_user] [--passwordfile file_name] 
+ *        [--target target(Default server)] auth_realm_name
+ *
+ * @author Nandini Ektare
+ */
+@Service(name="delete-auth-realm")
+@PerLookup
+@I18n("delete.auth.realm")
+@ExecuteOn({RuntimeType.DAS, RuntimeType.INSTANCE})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER, CommandTarget.CONFIG})
+public class DeleteAuthRealm implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(DeleteAuthRealm.class);
+
+    @Param(name="authrealmname", primary=true)
+    private String authRealmName;
+ 
+    @Param(name = "target", optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+   // @Inject
+   // private SecurityConfigListener securityListener;
+
+    @AccessRequired.To("delete")
+    AuthRealm authRealm = null;
+    
+    private SecurityService securityService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        securityService = config.getSecurityService();
+        authRealm = findRealm();
+        if (authRealm == null) {
+            final ActionReport report = context.getActionReport();
+            report.setMessage(localStrings.getLocalString(
+                "delete.auth.realm.notfound", 
+                "Authrealm named {0} not found", authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+        }
+        return (authRealm != null);
+    }
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        ActionReport report = context.getActionReport();
+
+        try {            
+            ConfigSupport.apply(new SingleConfigCode<SecurityService>() {
+                public Object run(SecurityService param) 
+                throws PropertyVetoException, TransactionFailure {
+                    param.getAuthRealm().remove(authRealm);
+                    //temporary fix - since the SecurityConfigListener is  not being called on an realm delete.
+                    SecurityConfigListener.authRealmDeleted(authRealm);
+                    return null;
+                }
+            }, securityService);
+        } catch(TransactionFailure e) {
+            report.setMessage(localStrings.getLocalString(
+                "delete.auth.realm.fail", "Deletion of Authrealm {0} failed", 
+                authRealmName) + "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+            return;
+        }
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+    }
+    
+    private AuthRealm findRealm() {
+        for (AuthRealm realm : securityService.getAuthRealm()) {
+            if (realm.getName().equals(authRealmName)) {
+                return realm;
+            }
+        }
+        return null;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteFileUser.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteFileUser.java
new file mode 100644
index 0000000..2bec084
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteFileUser.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.Configs;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.security.auth.realm.file.FileRealm;
+import com.sun.enterprise.security.auth.realm.BadRealmException;
+import com.sun.enterprise.security.auth.realm.NoSuchUserException;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.Server;
+import com.sun.enterprise.security.auth.realm.RealmsManager;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import java.beans.PropertyVetoException;
+import java.io.File;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+import org.jvnet.hk2.config.types.Property;
+
+/**
+ * Delete File User Command
+ * Usage: delete-file-user [--terse=false] [--echo=false] [--interactive=true] 
+ * [--host localhost] [--port 4848|4849] [--secure | -s] [--user admin_user]
+ * [--passwordfile file_name] [--authrealmname authrealm_name] 
+ * [--target target(Default server)] username
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="delete-file-user")
+@PerLookup
+@I18n("delete.file.user")
+@ExecuteOn({RuntimeType.ALL})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER, CommandTarget.CONFIG})
+@RestEndpoints({
+    @RestEndpoint(configBean=AuthRealm.class,
+        opType=RestEndpoint.OpType.DELETE, 
+        path="delete-user", 
+        description="Delete",
+        params={
+            @RestParam(name="authrealmname", value="$parent")
+        })
+})
+public class DeleteFileUser implements /*UndoableCommand*/ AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(DeleteFileUser.class);    
+
+    @Param(name="authrealmname", optional=true)
+    private String authRealmName;
+    
+    @Param(name = "target", optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Param(name="username", primary=true)
+    private String userName;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+    @Inject
+    private RealmsManager realmsManager;
+
+    @AccessRequired.To("update")
+    private AuthRealm fileAuthRealm;
+    
+    private SecurityService securityService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        securityService = config.getSecurityService();
+        fileAuthRealm = CLIUtil.findRealm(securityService, authRealmName);
+        if (fileAuthRealm == null) {
+            final ActionReport report = context.getActionReport();
+            report.setMessage(localStrings.getLocalString(
+                "delete.file.user.filerealmnotfound",
+                "File realm {0} does not exist", authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;                                            
+        }
+        /*
+         * The realm might have been defaulted, so capture the actual name.
+         */
+        authRealmName = fileAuthRealm.getName();
+        return true;
+    }
+    
+    
+
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        
+        final ActionReport report = context.getActionReport();
+
+        // Get FileRealm class name, match it with what is expected.
+        String fileRealmClassName = fileAuthRealm.getClassname();
+        
+        // Report error if provided impl is not the one expected
+        if (fileRealmClassName != null && 
+            !fileRealmClassName.equals(
+                "com.sun.enterprise.security.auth.realm.file.FileRealm")) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "delete.file.user.realmnotsupported",
+                    "Configured file realm {0} is not supported.", 
+                    fileRealmClassName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;                
+        }
+
+        // ensure we have the file associated with the authrealm
+        String keyFile = null;
+        for (Property fileProp : fileAuthRealm.getProperty()) {
+            if (fileProp.getName().equals("file"))
+                keyFile = fileProp.getValue();
+        }
+        final String kFile = keyFile;
+        if (keyFile == null) {
+            report.setMessage(
+                localStrings.getLocalString("delete.file.user.keyfilenotfound",
+                "There is no physical file associated with this file realm {0} ", 
+                authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;                                            
+        }
+        boolean exists = (new File(kFile)).exists();
+        if (!exists) {
+            report.setMessage(
+                localStrings.getLocalString("file.realm.keyfilenonexistent",
+                "The specified physical file {0} associated with the file realm {1} does not exist.",
+                new Object[]{kFile, authRealmName}));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;
+        }
+        
+         //even though delete-file-user is not an update to the security-service
+         //do we need to make it transactional by referncing the securityservice
+         //hypothetically ?.
+        try {
+            ConfigSupport.apply(new SingleConfigCode<SecurityService>() {
+                public Object run(SecurityService param)
+                        throws PropertyVetoException, TransactionFailure {
+                    try {
+                        realmsManager.createRealms(config);
+                        final FileRealm fr = (FileRealm) realmsManager.getFromLoadedRealms(config.getName(),authRealmName);
+                        fr.removeUser(userName);
+                        fr.persist();
+                        CreateFileUser.refreshRealm(config.getName(),authRealmName);
+                        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+                    } catch (NoSuchUserException e) {
+                        report.setMessage(
+                                localStrings.getLocalString("delete.file.user.usernotfound",
+                                "There is no such existing user {0} in the file realm {1}.",
+                                userName, authRealmName) + "  " + e.getLocalizedMessage());
+                        report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                        report.setFailureCause(e);
+                    } catch (BadRealmException e) {
+                        report.setMessage(
+                                localStrings.getLocalString(
+                                "delete.file.user.realmcorrupted",
+                                "Configured file realm {0} is corrupted.", authRealmName) + "  " + e.getLocalizedMessage());
+                        report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                        report.setFailureCause(e);
+                   } catch (Exception e) {
+                        e.printStackTrace();
+                        report.setMessage(
+                                localStrings.getLocalString("delete.file.user.userdeletefailed",
+                                "Removing User {0} from file realm {1} failed",
+                                userName, authRealmName) + "  " + e.getLocalizedMessage());
+                        report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                        report.setFailureCause(e);
+                    }
+                    return null;
+                }
+            }, securityService);
+        } catch (Exception e) {
+            report.setMessage(
+                    localStrings.getLocalString("delete.file.user.userdeletefailed",
+                    "Removing User {0} from file realm {1} failed",
+                    userName, authRealmName) + "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+        }
+    }
+//    @Override
+//    public ActionReport prepare(ParameterMap parameters) {
+//        //TODO: is there a way to check if in a Cluster some
+//        //instances are down
+////        com.sun.enterprise.config.serverbeans.Cluster cluster = domain.getClusterNamed(target);
+////        if (cluster!=null) {
+////            List<Server> servers = cluster.getInstances();
+////        }
+//        final ActionReport report = new ActionReport();
+//    }
+//
+//    @Override
+//    public void undo(ParameterMap parameters) {
+//        throw new UnsupportedOperationException("Not supported yet.");
+//    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteJaccProvider.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteJaccProvider.java
new file mode 100644
index 0000000..54fc455
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteJaccProvider.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.JaccProvider;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import java.beans.PropertyVetoException;
+import java.util.List;
+import org.glassfish.api.ActionReport;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+
+/**
+ *Usage: delete-jacc-provider
+ *         [--help] [--user admin_user] [--passwordfile file_name]
+ *         [ --target  target_name] jacc_provider_name
+ * 
+ */
+@Service(name="delete-jacc-provider")
+@PerLookup
+@I18n("delete.jacc.provider")
+@ExecuteOn({RuntimeType.DAS, RuntimeType.INSTANCE})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER, CommandTarget.CONFIG})
+public class DeleteJaccProvider implements AdminCommand, AdminCommandSecurity.Preauthorization {
+
+    final private static LocalStringManagerImpl localStrings =
+        new LocalStringManagerImpl(DeleteJaccProvider.class);
+
+    @Param(name="jaccprovidername", primary=true)
+    private String jaccprovider;
+
+    @Param(name = "target", optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+
+    private SecurityService securityService;
+    
+    @AccessRequired.To("delete")
+    private JaccProvider jprov;
+    
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+        config = CLIUtil.chooseConfig(domain, target, report);
+        if (config == null) {
+            return false;
+        }
+        securityService = config.getSecurityService();
+        jprov = CLIUtil.findJaccProvider(securityService, jaccprovider);
+        if (jprov == null) {
+            report.setMessage(localStrings.getLocalString(
+                    "delete.jacc.provider.notfound",
+                    "JaccProvider named {0} not found", jaccprovider));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;
+        }
+        if ("default".equals(jprov.getName())
+                    || "simple".equals(jprov.getName())) {
+            report.setMessage(localStrings.getLocalString(
+                   "delete.jacc.provider.notallowed",
+                   "JaccProvider named {0} is a system provider and cannot be deleted", jaccprovider));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;
+         }
+        
+        return true;
+    }
+    
+    @Override
+    public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+        try {
+            List<JaccProvider> jaccProviders = securityService.getJaccProvider();
+            JaccProvider jprov = null;
+            for (JaccProvider jaccProv : jaccProviders) {
+               if (jaccProv.getName().equals(jaccprovider)) {
+                   jprov = jaccProv;
+                   break;
+               }
+            }
+            
+            final JaccProvider jaccprov = jprov;
+            ConfigSupport.apply(new SingleConfigCode<SecurityService>() {
+                public Object run(SecurityService param)
+                throws PropertyVetoException, TransactionFailure {
+                    param.getJaccProvider().remove(jaccprov);
+                    return null;
+                }
+            }, securityService);
+        } catch(TransactionFailure e) {
+            report.setMessage(localStrings.getLocalString(
+                "delete.jacc.provider.fail", "Deletion of JaccProvider {0} failed",
+                jaccprovider) + "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+            return;
+        }
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteMessageSecurityProvider.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteMessageSecurityProvider.java
new file mode 100644
index 0000000..ac20b97
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeleteMessageSecurityProvider.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Domain;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.MessageSecurityConfig;
+import com.sun.enterprise.config.serverbeans.ProviderConfig;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.util.SystemPropertyConstants;
+
+import java.beans.PropertyVetoException;
+import java.util.List;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import org.jvnet.hk2.config.ConfigListener;
+
+/**
+ * Delete Message Security Provider Command
+ * 
+ * Usage: delete-message-security-provider --layer message_layer [--terse=false] 
+ *        [--echo=false] [--interactive=true] [--host localhost] [--port 4848|4849] 
+ *        [--secure | -s] [--user admin_user] [--passwordfile file_name] 
+ *        [--target target(Defaultserver)] provider_name
+ *
+ * @author Nandini Ektare
+ */
+@Service(name="delete-message-security-provider")
+@PerLookup
+@I18n("delete.message.security.provider")
+@ExecuteOn({RuntimeType.DAS, RuntimeType.INSTANCE})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER,CommandTarget.CONFIG})
+public class DeleteMessageSecurityProvider implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(DeleteMessageSecurityProvider.class);
+
+    @Param(name="providername", primary=true)
+    String providerId;
+ 
+    // auth-layer can only be SOAP | HttpServlet
+    @Param(name="layer",defaultValue="SOAP")
+    String authLayer;
+    
+    @Param(name = "target", optional = true, defaultValue =
+        SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+
+    ProviderConfig thePC = null;
+
+    @AccessRequired.To("delete")
+    private MessageSecurityConfig msgSecCfg = null;
+    
+    private SecurityService secService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        secService = config.getSecurityService();
+        msgSecCfg = CLIUtil.findMessageSecurityConfig(secService, authLayer);
+        if (msgSecCfg == null) {
+            final ActionReport report = context.getActionReport();
+            report.setMessage(localStrings.getLocalString(
+                "delete.message.security.provider.confignotfound", 
+                "A Message security config does not exist for the layer {0}", 
+                authLayer));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;            
+        }
+        return true;
+    }
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        
+        ActionReport report = context.getActionReport();
+        
+        List<ProviderConfig> pcs = msgSecCfg.getProviderConfig();
+        for (ProviderConfig pc : pcs) {
+            if (pc.getProviderId().equals(providerId)) { 
+                thePC = pc;
+                try {
+                    ConfigSupport.apply(
+                        new SingleConfigCode<MessageSecurityConfig>() {
+                        
+                        public Object run(MessageSecurityConfig param) 
+                        throws PropertyVetoException, TransactionFailure {
+
+                            if ((param.getDefaultProvider() != null) &&
+                                param.getDefaultProvider().equals(
+                                    thePC.getProviderId())) {
+                                param.setDefaultProvider(null);
+                            }
+                                
+                            if ((param.getDefaultClientProvider() != null) &&
+                                 param.getDefaultClientProvider().equals(
+                                    thePC.getProviderId())) {
+                                param.setDefaultClientProvider(null);
+                            }
+                            
+                            param.getProviderConfig().remove(thePC);                                                                                       
+                            return null;
+                        }
+                    }, msgSecCfg);
+                } catch(TransactionFailure e) {
+                    e.printStackTrace();
+                    report.setMessage(localStrings.getLocalString(
+                        "delete.message.security.provider.fail", 
+                        "Deletion of message security provider named {0} failed", 
+                        providerId));
+                    report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                    report.setFailureCause(e);
+                    return;
+                }
+                /*report.setMessage(localStrings.getLocalString(
+                    "delete.message.security.provider.success", 
+                    "Deletion of message security provider {0} completed " +
+                    "successfully", providerId));*/
+                report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+                return;                
+            }
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeletePasswordAlias.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeletePasswordAlias.java
new file mode 100644
index 0000000..bdd02bd
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/DeletePasswordAlias.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.security.store.DomainScopedPasswordAliasStore;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import org.glassfish.api.ActionReport;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import javax.inject.Inject;
+
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+
+/**
+ * Delete Password Alias Command
+ *
+ * Usage: delete-password-alias [--terse=false] [--echo=false]
+ *        [--interactive=true] [--host localhost] [--port 4848|4849]
+ *        [--secure | -s] [--user admin_user] [--passwordfile file_name] aliasname
+ *
+ * Result of the command is that:
+ * The entry of the form: aliasname=<password-encrypted-with-masterpassword>
+ * in <domain-dir>/<domain-name>/config/domain-passwords file is removed
+ *
+ * domain.xml example entry is:
+ * <provider-config class-name="com.sun.xml.wss.provider.ClientSecurityAuthModule"
+ *                  provider-id="XWS_ClientProvider" provider-type="client">
+ *      <property name="password" value="${ALIAS=myalias}/>
+ * </provider-config>
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="delete-password-alias")
+@PerLookup
+@I18n("delete.password.alias")
+@ExecuteOn(RuntimeType.ALL)
+@TargetType({CommandTarget.DAS,CommandTarget.DOMAIN})
+@RestEndpoints({
+    @RestEndpoint(configBean=Domain.class,
+        opType=RestEndpoint.OpType.POST, // TODO: Should be DELETE
+        path="delete-password-alias", 
+        description="delete-password-alias")
+})
+
+@AccessRequired(resource="domain/passwordAliases/passwordAlias/$aliasName", action="delete")
+public class DeletePasswordAlias implements AdminCommand, AdminCommandSecurity.Preauthorization {
+
+    final private static LocalStringManagerImpl localStrings =
+        new LocalStringManagerImpl(DeletePasswordAlias.class);
+
+    @Param(name="aliasname", primary=true)
+    private String aliasName;
+    
+    @Inject
+    private DomainScopedPasswordAliasStore domainPasswordAliasStore;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+        try {
+            if ( ! domainPasswordAliasStore.containsKey(aliasName)) {
+                report.setMessage(localStrings.getLocalString(
+                    "delete.password.alias.notfound",
+                    "Password alias for the alias {0} does not exist.",
+                    aliasName));
+                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                return false;
+            }
+        } catch (Exception ex) {
+            reportFailure(context.getActionReport(), ex);
+            return false;
+        }
+        return true;
+    }
+
+    
+
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+
+        try {
+            domainPasswordAliasStore.remove(aliasName);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            reportFailure(report, ex);
+            return;
+        }
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+        /*report.setMessage(localStrings.getLocalString(
+            "delete.password.alias.success",
+            "Password alias for the alias {0} deleted successfully",
+            aliasName));*/
+    }
+    
+    private void reportFailure(final ActionReport report,
+            final Exception ex) {
+        report.setMessage(localStrings.getLocalString(
+                "delete.password.alias.fail",
+                "Deletion of Password Alias {0} failed", aliasName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(ex);
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListAuditModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListAuditModule.java
new file mode 100644
index 0000000..897b840
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListAuditModule.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.admin.CommandLock;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.config.serverbeans.AuditModule;
+import com.sun.enterprise.config.serverbeans.Configs;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.Server;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+
+/**
+ * List Audit Modules Command
+ * Usage: list-audit-modules [--terse=false] [--echo=false] [--interactive=true] 
+ *        [--host localhost] [--port 4848|4849] [--secure | -s] 
+ *        [--user admin_user] [--passwordfile file_name] [target(Default server)]
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="list-audit-modules")
+@PerLookup
+@CommandLock(CommandLock.LockType.NONE)
+@I18n("list.audit.module")
+@ExecuteOn({RuntimeType.DAS})
+@TargetType({CommandTarget.DAS,CommandTarget.CLUSTERED_INSTANCE,
+CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER,CommandTarget.CONFIG})
+@RestEndpoints({
+    @RestEndpoint(configBean=SecurityService.class,
+        opType=RestEndpoint.OpType.GET, 
+        path="list-audit-modules", 
+        description="List Audit Modules")
+})
+public class ListAuditModule implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(ListAuditModule.class);    
+
+    @Param(name = "target", primary=true, optional = true, defaultValue =
+        SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+    
+    @AccessRequired.To(value="read")
+    private SecurityService securityService = null;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        securityService = chooseSecurityService(context.getActionReport());
+        return true;
+    }
+
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+
+        final ActionReport report = context.getActionReport();
+
+        report.getTopMessagePart().setChildrenType("audit-module");
+        for (AuditModule am : securityService.getAuditModule()) {
+            ActionReport.MessagePart part = report.getTopMessagePart().addChild();
+            part.setMessage(am.getName());
+        }
+    }
+    
+    private SecurityService chooseSecurityService(final ActionReport report) {
+        config = CLIUtil.chooseConfig(domain, target, report);
+        if (config == null) {
+            return null;
+        }
+        return config.getSecurityService();
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListAuthRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListAuthRealm.java
new file mode 100644
index 0000000..56e834b
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListAuthRealm.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+
+
+
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.admin.CommandLock;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.security.auth.realm.RealmsManager;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+
+
+/**
+ * List Auth Realms Command
+ * Usage: list-auth-realms [--terse=false] [--echo=false] [--interactive=true] 
+ *        [--host localhost] [--port 4848|4849] [--secure | -s] 
+ *        [--user admin_user] [--passwordfile file_name] [target(Default server)]
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="list-auth-realms")
+@PerLookup
+@CommandLock(CommandLock.LockType.NONE)
+@I18n("list.auth.realm")
+@ExecuteOn({RuntimeType.DAS})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,
+CommandTarget.CLUSTER, CommandTarget.CONFIG,CommandTarget.CLUSTERED_INSTANCE})
+@RestEndpoints({
+    @RestEndpoint(configBean=SecurityService.class,
+        opType=RestEndpoint.OpType.GET, 
+        path="list-auth-realms", 
+        description="List Auth Realms")
+})
+public class ListAuthRealm implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(ListAuthRealm.class);    
+
+    @Param(name = "target", primary=true, optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+    @Inject
+    private RealmsManager realmsManager;
+
+    @AccessRequired.To("read")
+    private SecurityService securityService;
+            
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        securityService = config.getSecurityService();
+        return true;
+    }
+
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        
+        final ActionReport report = context.getActionReport();
+
+//        Enumeration realms = Realm.getRealmNames();
+//
+//        if ( realms == null || !realms.hasMoreElements()) {
+//            //Create realms
+//            realmsManager.createRealms(securityService);
+//        }
+
+        for (AuthRealm authRealm : securityService.getAuthRealm()) {
+            ActionReport.MessagePart part = report.getTopMessagePart().addChild();
+            part.setMessage(authRealm.getName());
+        }
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListFileGroup.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListFileGroup.java
new file mode 100644
index 0000000..70af683
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListFileGroup.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import java.util.Enumeration;
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.admin.CommandLock;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.types.Property;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.Configs;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.security.auth.realm.file.FileRealm;
+import com.sun.enterprise.security.auth.realm.BadRealmException;
+import com.sun.enterprise.security.auth.realm.NoSuchUserException;
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.Server;
+import com.sun.enterprise.security.auth.realm.RealmsManager;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+
+/**
+ * List File GroupsCommand
+ * Usage: list-file-groups [--terse={true|false}][ --echo={true|false} ]
+ *        [ --interactive={true|false} ] [--host  host] [--port port]
+ *        [--secure| -s ] [--user  admin_user] [--passwordfile filename]
+ *        [--help] [--name username] [--authrealmname auth_realm_name] [ target]
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="list-file-groups")
+@PerLookup
+@CommandLock(CommandLock.LockType.NONE)
+@I18n("list.file.group")
+@ExecuteOn({RuntimeType.DAS})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER,
+CommandTarget.CLUSTERED_INSTANCE, CommandTarget.CONFIG})
+@RestEndpoints({
+    @RestEndpoint(configBean=SecurityService.class,
+        opType=RestEndpoint.OpType.GET, 
+        path="list-file-groups", 
+        description="list-file-groups")
+})
+public class ListFileGroup implements AdminCommand, AdminCommandSecurity.Preauthorization {
+
+    final private static LocalStringManagerImpl localStrings =
+        new LocalStringManagerImpl(ListFileGroup.class);
+
+    @Param(name="authrealmname", optional=true)
+    private String authRealmName;
+
+    @Param(name="name", optional=true)
+    private String fileUserName;
+
+    @Param(name = "target", primary=true, optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Configs configs;
+
+    @Inject
+    private Domain domain;
+
+    @Inject
+    private RealmsManager realmsManager;
+
+    @AccessRequired.To("read")
+    private AuthRealm fileAuthRealm;
+    
+    private SecurityService securityService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        securityService = config.getSecurityService();
+        fileAuthRealm = CLIUtil.findRealm(securityService, authRealmName);
+        if (fileAuthRealm == null) {
+            final ActionReport report = context.getActionReport();
+            report.setMessage(localStrings.getLocalString(
+                "list.file.group.filerealmnotfound",
+                "File realm {0} does not exist", authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;                                            
+        }
+        /*
+         * The realm might have been defaulted, so capture the actual name.
+         */
+        authRealmName = fileAuthRealm.getName();
+        return true;
+    }
+    
+    
+
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+
+        final ActionReport report = context.getActionReport();
+
+        try {
+            // Get all users of this file realm. If a username has
+            // been passed in through the --name CLI option use that
+            FileRealm fr = getFileRealm(securityService, fileAuthRealm, report);
+
+            if (fr == null) {
+                // the getFileRealm method would have filled
+                // in the right cause of this situation
+                return;
+            }
+            
+            Enumeration groups = null;
+            if (fileUserName != null) {
+                fr.getUser(fileUserName);
+                groups = fr.getGroupNames(fileUserName);
+            } else {
+                groups = fr.getGroupNames();
+            }
+
+            report.getTopMessagePart().setMessage(localStrings.getLocalString(
+                "list.file.group.success",
+                "list-file-groups successful"));
+            report.getTopMessagePart().setChildrenType("file-group");
+            while (groups.hasMoreElements()) {
+                final ActionReport.MessagePart part =
+                     report.getTopMessagePart().addChild();
+                part.setMessage((String) groups.nextElement());
+            }
+            report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+        } catch (BadRealmException e) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "list.file.group.realmcorrupted",
+                    "Configured file realm {0} is corrupted.", authRealmName) +
+                "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+        } catch (NoSuchUserException e) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "list.file.group.usernotfound",
+                    "Specified file user {0} not found.", fileUserName) +
+                "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+        }
+    }
+
+    private FileRealm getFileRealm(final SecurityService securityService, AuthRealm fileAuthRealm, ActionReport report) {
+        // Get FileRealm class name, match it with what is expected.
+        String fileRealmClassName = fileAuthRealm.getClassname();
+
+        // Report error if provided impl is not the one expected
+        if (fileRealmClassName != null &&
+            !fileRealmClassName.equals(
+                "com.sun.enterprise.security.auth.realm.file.FileRealm")) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "list.file.user.realmnotsupported",
+                    "Configured file realm {0} is not supported.",
+                    fileRealmClassName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return null;
+        }
+
+        // ensure we have the file associated with the authrealm
+        String keyFile = null;
+        for (Property fileProp : fileAuthRealm.getProperty()) {
+            if (fileProp.getName().equals("file"))
+                keyFile = fileProp.getValue();
+        }
+        if (keyFile == null) {
+            report.setMessage(
+                localStrings.getLocalString("list.file.user.keyfilenotfound",
+                "There is no physical file associated with this file realm {0} ",
+                authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return null;
+        }
+
+        // We have the right impl so let's try to remove one
+        FileRealm fr = null;
+        try {
+            realmsManager.createRealms(config);
+            fr = (FileRealm) realmsManager.getFromLoadedRealms(config.getName(),authRealmName);
+            if (fr == null) {
+                throw new NoSuchRealmException(authRealmName);
+            }
+        }  catch(NoSuchRealmException e) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "list.file.user.realmnotsupported",
+                    "Configured file realm {0} is not supported.", authRealmName) +
+                "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+        }
+        return fr;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListFileUser.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListFileUser.java
new file mode 100644
index 0000000..bf34baa
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListFileUser.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.security.auth.realm.NoSuchUserException;
+import java.util.Enumeration;
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.admin.CommandLock;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.types.Property;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.security.auth.realm.file.FileRealm;
+import com.sun.enterprise.security.auth.realm.BadRealmException;
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.security.auth.realm.RealmsManager;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import java.io.File;
+import org.glassfish.api.admin.ExecuteOn;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+
+/**
+ * List File Users Command
+ * Usage: list-file-users [--terse=false] [--echo=false] [--interactive=true] 
+ * [--host localhost] [--port 4848|4849] [--secure | -s] [--user admin_user] 
+ * [--passwordfile file_name] [--authrealmname authrealm_name] 
+ * [target(Default server)]
+ * @author Nandini Ektare
+ */
+
+@Service(name="list-file-users")
+@PerLookup
+@CommandLock(CommandLock.LockType.NONE)
+@I18n("list.file.user")
+@ExecuteOn({RuntimeType.DAS})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER,
+    CommandTarget.CLUSTERED_INSTANCE,CommandTarget.CONFIG})
+@RestEndpoints({
+    @RestEndpoint(configBean=AuthRealm.class,
+        opType=RestEndpoint.OpType.GET, 
+        path="list-users", 
+        description="List Users",
+        params={
+            @RestParam(name="authrealmname", value="$parent")
+        })
+})
+public class ListFileUser implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(ListFileUser.class);    
+
+    @Param(name="authrealmname", optional=true)
+    private String authRealmName;
+    
+    @Param(name = "target", primary=true, optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+
+    @Inject
+    private RealmsManager realmsManager;
+
+    @AccessRequired.To("read")
+    private AuthRealm fileAuthRealm;
+    
+    private SecurityService securityService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        securityService = config.getSecurityService();
+        fileAuthRealm = CLIUtil.findRealm(securityService, authRealmName);
+        if (fileAuthRealm == null) {
+            final ActionReport report = context.getActionReport();
+            report.setMessage(localStrings.getLocalString(
+                "list.file.user.filerealmnotfound",
+                "File realm {0} does not exist", authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;                                            
+        }
+        /*
+         * The realm might have been defaulted, so capture the actual name.
+         */
+        authRealmName = fileAuthRealm.getName();
+        return true;
+    }
+
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        
+        final ActionReport report = context.getActionReport();
+
+        // Get FileRealm class name, match it with what is expected.
+        String fileRealmClassName = fileAuthRealm.getClassname();
+        
+        // Report error if provided impl is not the one expected
+        if (fileRealmClassName != null && 
+            !fileRealmClassName.equals(
+                "com.sun.enterprise.security.auth.realm.file.FileRealm")) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "list.file.user.realmnotsupported",
+                    "Configured file realm {0} is not supported.", 
+                    fileRealmClassName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;                
+        }
+
+        // ensure we have the file associated with the authrealm
+        String keyFile = null;
+        for (Property fileProp : fileAuthRealm.getProperty()) {
+            if (fileProp.getName().equals("file"))
+                keyFile = fileProp.getValue();
+        }
+        if (keyFile == null) {
+            report.setMessage(
+                localStrings.getLocalString("list.file.user.keyfilenotfound",
+                "There is no physical file associated with this file realm {0} ", 
+                authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;                                            
+        }
+
+        boolean exists = (new File(keyFile)).exists();
+        if (!exists) {
+            report.setMessage(
+                localStrings.getLocalString("file.realm.keyfilenonexistent",
+                "The specified physical file {0} associated with the file realm {1} does not exist.",
+                new Object[]{keyFile, authRealmName}));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;
+        }
+        // We have the right impl so let's try to remove one 
+        FileRealm fr = null;
+        try {
+            realmsManager.createRealms(config);
+            //account for updates to realms from outside this config sharing
+            //same keyfile
+            CreateFileUser.refreshRealm(config.getName(), authRealmName);
+            fr = (FileRealm) realmsManager.getFromLoadedRealms(config.getName(),authRealmName);
+            if (fr == null) {
+                throw new NoSuchRealmException(authRealmName);
+            }
+        }  catch(NoSuchRealmException e) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "list.file.user.realmnotsupported",
+                    "Configured file realm {0} is not supported.", authRealmName) +
+                "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+            return;
+        }
+
+        try {
+            Enumeration users = fr.getUserNames();
+            List userList = new ArrayList();
+            
+            while (users.hasMoreElements()) {
+                final ActionReport.MessagePart part = report.getTopMessagePart().addChild();
+                String userName = (String) users.nextElement();
+                part.setMessage(userName);
+                Map userMap = new HashMap();
+                userMap.put("name", userName);
+                try {
+                    userMap.put("groups", Collections.list(fr.getGroupNames(userName)));
+                } catch (NoSuchUserException ex) {
+                    // This should never be thrown since we just got the user name from the realm
+                }
+                userList.add(userMap);
+            }
+            Properties extraProperties = new Properties();
+            extraProperties.put("users", userList);
+            report.setExtraProperties(extraProperties);
+            report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+        } catch (BadRealmException e) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "list.file.user.realmcorrupted",
+                    "Configured file realm {0} is corrupted.", authRealmName) +
+                "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+        }        
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListJaccProviders.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListJaccProviders.java
new file mode 100644
index 0000000..8e26d15
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListJaccProviders.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Configs;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.JaccProvider;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.Server;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import java.util.List;
+import org.glassfish.api.ActionReport;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+
+/**
+ *Usage: list-jacc-providers
+ *         [--help] [--user admin_user] [--passwordfile file_name]
+ *         [target(Default server)]
+ *
+ */
+@Service(name="list-jacc-providers")
+@PerLookup
+@CommandLock(CommandLock.LockType.NONE)
+@I18n("list.jacc.provider")
+@ExecuteOn({RuntimeType.DAS})
+@TargetType({CommandTarget.DAS,CommandTarget.CLUSTERED_INSTANCE,
+CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER, CommandTarget.CONFIG})
+@RestEndpoints({
+    @RestEndpoint(configBean=SecurityService.class,
+        opType=RestEndpoint.OpType.GET, 
+        path="list-jacc-providers", 
+        description="list-jacc-providers")
+})
+public class ListJaccProviders implements AdminCommand, AdminCommandSecurity.Preauthorization {
+
+    final private static LocalStringManagerImpl localStrings =
+        new LocalStringManagerImpl(DeleteJaccProvider.class);
+
+    @Param(name = "target", primary=true, optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Configs configs;
+
+    @Inject
+    private Domain domain;
+
+    @AccessRequired.To("read")
+    private SecurityService securityService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+        config = CLIUtil.chooseConfig(domain, target, report);
+        if (config == null) {
+            return false;
+        }
+        securityService = config.getSecurityService();
+        return true;
+    }
+    
+    
+    
+    @Override
+    public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+        
+        List<JaccProvider> jaccProviders = securityService.getJaccProvider();
+        JaccProvider jprov = null;
+        for (JaccProvider jaccProv : jaccProviders) {
+            ActionReport.MessagePart part = report.getTopMessagePart().addChild();
+            part.setMessage(jaccProv.getName());
+        }
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListMessageSecurityProvider.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListMessageSecurityProvider.java
new file mode 100644
index 0000000..3ebbf47
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListMessageSecurityProvider.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.admin.CommandLock;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.MessageSecurityConfig;
+import com.sun.enterprise.config.serverbeans.ProviderConfig;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+/**
+ * List Message Security Providers Command
+ * 
+ * Usage: list-message-security-providers [--terse=false] [--echo=false] 
+ *        [--interactive=true] [--host localhost] [--port 4848|4849] 
+ *        [--secure | -s] [--user admin_user] [--passwordfile file_name] 
+ *        [--layer message_layer] [target(Default server)] 
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="list-message-security-providers")
+@PerLookup
+@CommandLock(CommandLock.LockType.NONE)
+@I18n("list.message.security.provider")
+@ExecuteOn({RuntimeType.DAS})
+@TargetType({CommandTarget.DAS,CommandTarget.CLUSTERED_INSTANCE,
+CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER, CommandTarget.CONFIG})
+@RestEndpoints({
+    @RestEndpoint(configBean=SecurityService.class,
+        opType=RestEndpoint.OpType.GET, 
+        path="list-message-security-providers", 
+        description="list-message-security-providers")
+})
+public class ListMessageSecurityProvider implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(ListMessageSecurityProvider.class);    
+
+    @Param(name = "target", primary=true, optional = true, defaultValue =
+        SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+    // auth-layer can only be SOAP | HttpServlet
+    @Param(name="layer", acceptableValues="SOAP,HttpServlet", optional=true)
+    String authLayer;
+    
+    @AccessRequired.To("read")
+    private SecurityService secService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        secService = config.getSecurityService();
+        return true;
+    }
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        
+        final ActionReport report = context.getActionReport();
+
+        secService.getMessageSecurityConfig();
+
+        report.getTopMessagePart().setMessage(
+            localStrings.getLocalString(
+                "list.message.security.provider.success", 
+                "list-message-security-providers successful"));
+        report.getTopMessagePart().setChildrenType("");
+        
+        for (MessageSecurityConfig msc : secService.getMessageSecurityConfig()) {
+            if (authLayer == null) {
+                for (ProviderConfig pc : msc.getProviderConfig()) {
+                    ActionReport.MessagePart part = 
+                        report.getTopMessagePart().addChild();
+                    part.setMessage(pc.getProviderId());                
+                }
+            } else {
+                if (msc.getAuthLayer().equals(authLayer)) {
+                    for (ProviderConfig pc : msc.getProviderConfig()) {
+                        ActionReport.MessagePart part = 
+                            report.getTopMessagePart().addChild();
+                        part.setMessage(pc.getProviderId());                                    
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListPasswordAlias.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListPasswordAlias.java
new file mode 100644
index 0000000..5e42c4d
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListPasswordAlias.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.security.store.DomainScopedPasswordAliasStore;
+import java.util.Iterator;
+import org.glassfish.api.admin.AccessRequired;
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.admin.CommandLock;
+import org.glassfish.api.I18n;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import org.glassfish.hk2.api.PerLookup;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import javax.inject.Inject;
+
+/**
+ * List Password Aliases Command
+ *
+ * Usage: list-password-aliases [--terse=false] [--echo=false]
+ *        [--interactive=true] [--host localhost] [--port 4848|4849]
+ *        [--secure | -s] [--user admin_user] [--passwordfile file_name]
+ *
+ * Result of the command is that:
+ * <domain-dir>/<domain-name>/config/domain-passwords file gets appended with
+ * the entry of the form: aliasname=<password encrypted with masterpassword>
+ *
+ * A user can use this aliased password now in setting passwords in domin.xml.
+ * Benefit is it is in NON-CLEAR-TEXT
+ *
+ * domain.xml example entry is:
+ * <provider-config class-name="com.sun.xml.wss.provider.ClientSecurityAuthModule"
+ *                  provider-id="XWS_ClientProvider" provider-type="client">
+ *      <property name="password" value="${ALIAS=myalias}/>
+ * </provider-config>
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="list-password-aliases")
+@PerLookup
+@CommandLock(CommandLock.LockType.NONE)
+@I18n("list.password.alias")
+@ExecuteOn({RuntimeType.DAS})
+@TargetType({CommandTarget.DAS,CommandTarget.DOMAIN})
+@RestEndpoints({
+    @RestEndpoint(configBean=Domain.class,
+        opType=RestEndpoint.OpType.GET, 
+        path="list-password-aliases", 
+        description="list-password-aliases")
+})
+@AccessRequired(resource="domain/passwordAliases", action="read")
+public class ListPasswordAlias implements AdminCommand {
+
+    final private static LocalStringManagerImpl localStrings =
+        new LocalStringManagerImpl(ListPasswordAlias.class);
+
+    @Inject
+    private DomainScopedPasswordAliasStore domainPasswordAliasStore;
+
+
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+
+        try {
+            final Iterator<String> it = domainPasswordAliasStore.keys();
+
+            if (! it.hasNext()) {
+                report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+                report.setMessage(localStrings.getLocalString(
+                    "list.password.alias.nothingtolist",
+                    "Nothing to list"));
+            }
+            
+            while (it.hasNext()) {
+                ActionReport.MessagePart part =
+                    report.getTopMessagePart().addChild();
+                part.setMessage(it.next());
+            }
+            
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            report.setMessage(localStrings.getLocalString(
+               "list.password.alias.fail", "Listing of Password Alias failed"));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(ex);
+            return;
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListSupportedCipherSuites.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListSupportedCipherSuites.java
new file mode 100644
index 0000000..51d59bc
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/ListSupportedCipherSuites.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.security.ssl.SSLUtils;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import org.glassfish.api.ActionReport;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import javax.inject.Inject;
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+
+/**
+ * author - Nithya Subramanian
+ *
+ * Usage: list-supported-cipher-suites
+ *         [--help] [--user admin_user] [--passwordfile file_name]
+ *         [target_name(default server)]
+ **/
+
+@Service(name = "list-supported-cipher-suites")
+@PerLookup
+@CommandLock(CommandLock.LockType.NONE)
+@I18n("list.supported.cipher.suites")
+@ExecuteOn({RuntimeType.DAS})
+@TargetType({CommandTarget.DAS, CommandTarget.STANDALONE_INSTANCE, CommandTarget.CLUSTERED_INSTANCE})
+@RestEndpoints({
+    @RestEndpoint(configBean=SecurityService.class,
+        opType=RestEndpoint.OpType.GET, 
+        path="list-supported-cipher-suites", 
+        description="List Supported Cipher Suites")
+})
+@AccessRequired(resource="domain/security-service", action="read")
+public class ListSupportedCipherSuites implements AdminCommand {
+
+    final private static LocalStringManagerImpl localStrings =
+            new LocalStringManagerImpl(ListSupportedCipherSuites.class);
+    @Inject
+    SSLUtils sslutils;
+
+    /*@Param(name = "target", optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;*/
+    @Param(optional = true, primary = true, defaultValue = SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+
+    @Override
+    public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+        String[] cipherSuites = sslutils.getSupportedCipherSuites();
+
+        for (String cipherSuite : cipherSuites) {
+            if (!cipherSuite.contains("_KRB5_")) {
+                ActionReport.MessagePart part = report.getTopMessagePart().addChild();
+                part.setMessage(cipherSuite);
+            }
+        }
+
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/LocalStrings.properties b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/LocalStrings.properties
new file mode 100644
index 0000000..248681d
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/LocalStrings.properties
@@ -0,0 +1,100 @@
+#
+# Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+file.realm.keyfilenonexistent=The specified physical file {0} associated with the file realm {1} does not exist.
+create.file.user.usagetext=create-file-user\n\t[--authrealmname <authrealm_name>] [--target target] \n\t[--groups user_groups[:user_groups]*] \n\t[-?|--help[=<help(default:false)>]] username
+create.file.user.filerealmnotfound=File realm {0} does not exist
+create.file.user.keyfilenotfound=No physical file is associated with file realm {0}.
+create.file.user.keyfilenotreadable=None of password or groups have been specified for update, Password for user {0} has to be specified through AS_ADMIN_USERPASSWORD property in the file specified in --passwordfile option.
+create.file.user.realmnotsupported=Configured file realm {0} is not supported.
+create.file.user.realmcorrupted=Configured file realm {0} is corrupted.
+create.file.user.useraddfailed=Adding User {0} to file realm {1} failed.
+create.file.user.userpassword=The user password
+create.file.user.userpassword.prompt=Enter the user password
+create.file.user.userpassword.promptAgain=Enter the user password again
+delete.file.user.filerealmnotfound=File realm {0} does not exist
+delete.file.user.keyfilenotfound=No physical file is associated with the file realm {0}.
+delete.file.user.realmnotsupported=Configured file realm {0} is not supported.
+delete.file.user.realmcorrupted=Configured file realm {0} is corrupted.
+delete.file.user.userdeletefailed=Removing User {0} from file realm {0} failed.
+delete.file.user.usernotfound=User {0} does not exist in file realm {1}.
+delete.file.user.success=delete-file-user Successful.
+update.file.user.filerealmnotfound=File realm {0} does not exist.
+update.file.user.keyfilenotfound=No physical file associated with this file realm {0}.
+update.file.user.keyfilenotreadable=Password for user {0} has to be specified in --userpassword option or supplied through AS_ADMIN_USERPASSWORD property in the file specified in --passwordfile option.
+update.file.user.realmcorrupted=Configured file realm {0} is corrupted.
+update.file.user.realmnotsupported=Configured file realm {0} is not supported.
+update.file.user.userupdatefailed=Updating user {0} in file realm {1} failed.
+update.file.user.success=update-file-user Successful.
+update.file.user.userpassword=The user password
+update.file.user.userpassword.prompt=Enter the user password
+update.file.user.userpassword.promptAgain=Enter the user password again
+list.file.user.filerealmnotfound=File realm {0} does not exist
+list.file.user.realmnotsupported=Configured file realm {0} is not supported.
+list.file.user.keyfilenotfound=There is no physical file associated with the file realm {0}
+list.file.user.realmcorrupted=Configured file realm {0} is corrupted.
+list.file.user.success=list-file-users Successful.
+create.user.ok.anon.allowed=A new ''admin user'' {0} is now created for immediate use, however, this domain still allows anonymous admin access. You should consider removing the admin user ''anonymous''.
+create.user.ok=A new ''admin user'' {0} is now created for immediate use
+
+create.auth.realm.duplicatefound=Authrealm named {0} exists. Cannot add duplicate Authrealm.
+create.auth.realm.fail=Creation of Authrealm {0} failed.
+create.auth.realm.success=Creation of Authrealm {0} completed successfully.
+delete.auth.realm.notfound=Authrealm named {0} not found.
+delete.auth.realm.fail=Deletion of Authrealm {0} failed.
+delete.auth.realm.success=Deletion of Authrealm {0} completed successfully.
+list.auth.realm.success=list-auth-realms Successful
+
+list.file.group.filerealmnotfound=File realm {0} does not exist
+list.file.group.success=list-file-groups Successful
+list.file.group.realmcorrupted=Configured file realm {0} is corrupted
+list.file.group.usernotfound=Specified file user {0} not found
+list.file.group.realmnotsupported=Configured file realm {0} is not supported
+list.file.group.keyfilenotfound=There is no physical file associated with this file realm {0}
+
+change.admin.password.adminrealmnotfound=There is no admin realm to perform this operation.
+change.admin.password.adminrealmnotsupported=Configured admin realm is not of supported type.
+change.admin.password.keyfilenotfound=There is no physical file associated with admin realm.
+change.admin.password.realmcorrupted=Configured admin realm is corrupted.
+change.admin.password.realmnotsupported=Configured admin realm does not exist.
+change.admin.password.userupdatefailed=Password change failed for user named {0}.
+
+create.password.alias.fail=Creation of Password Alias {0} failed
+create.password.alias.success=Encrypted password for the alias name {0} stored successfully
+create.password.alias.aliaspassword=The alias password
+create.password.alias.aliaspassword.prompt=Enter the alias password
+create.password.alias.aliaspassword.promptAgain=Enter the alias password again
+list.password.alias.fail=Listing of Password Alias failed
+list.password.alias.success=List password aliases executed successfully
+list.password.alias.nothingtolist=Nothing to list
+delete.password.alias.success=Password alias for the alias {0} deleted successfully
+delete.password.alias.fail=Deletion of Password Alias {0} failed
+delete.password.alias.notfound=Password alias for the alias {0} does not exist.
+update.password.alias.notfound=Password alias for the alias {0} does not exist.
+update.password.alias.fail=Update of Password Alias {0} failed
+update.password.alias.success=Encrypted password for the alias {0} updated successfully
+update.password.alias.aliaspassword=The alias password
+update.password.alias.aliaspassword.prompt=Enter the alias password
+update.password.alias.aliaspassword.promptAgain=Enter the alias password again
+#realm.not.refreshed=Admin auth realm could not be refreshed. Please restart the server.
+create.password.alias.alreadyexists=Password alias with the specified name already exists. Please use the update-password-alias command to change it
+#create-jacc-provider
+create.jacc.provider.duplicatefound=JaccProvider named {0} exists. Cannot add duplicate JaccProvider.
+delete.jacc.provider.notfound=JaccProvider named {0} not found.
+delete.jacc.provider.fail=Deletion of JaccProvider {0} failed.
+delete.jacc.provider.notallowed=JaccProvider named {0} is a system provider and cannot be deleted.
+
+util.noconfigfortarget=Configuration for target {0} not found.
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/UpdateFileUser.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/UpdateFileUser.java
new file mode 100644
index 0000000..b7db42d
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/UpdateFileUser.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.AdminService;
+import java.util.List;
+
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.types.Property;
+import com.sun.enterprise.config.serverbeans.Config;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.Configs;
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.SecureAdmin;
+import com.sun.enterprise.security.auth.realm.file.FileRealm;
+import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.config.serverbeans.Server;
+import com.sun.enterprise.security.auth.realm.RealmsManager;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import java.io.File;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+
+/**
+ * Update File User Command
+ *
+ * Usage: update-file-user [--terse=false] [--echo=false] [--interactive=true] 
+ *   [--host localhost] [--port 4848|4849] [--secure | -s] [--user admin_user]
+ *   [--passwordfile file_name] [--userpassword admin_passwd] 
+ *   [--groups user_groups[:user_groups]*] [--authrealmname authrealm_name] 
+ *   [--target target(Default server)] username
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="update-file-user")
+@PerLookup
+@I18n("update.file.user")
+@ExecuteOn({RuntimeType.ALL})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER, CommandTarget.CONFIG})
+@RestEndpoints({
+    @RestEndpoint(configBean=AuthRealm.class,
+        opType=RestEndpoint.OpType.POST, 
+        path="update-user", 
+        description="Update Users",
+        params={
+            @RestParam(name="authrealmname", value="$parent")
+        })
+})
+public class UpdateFileUser implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    
+    final private static LocalStringManagerImpl localStrings = 
+        new LocalStringManagerImpl(UpdateFileUser.class);    
+
+    @Param(name="groups", optional=true, separator=':')
+    private List<String> groups = null;
+
+    // @Param(name="userpasswordfile", optional=true)
+    // String passwordFile;
+
+    @Param(name="userpassword", optional=true, password=true)
+    private String userpassword;
+
+    @Param(name="authrealmname", optional=true)
+    private String authRealmName;
+    
+    @Param(name = "target", optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    @Param(name="username", primary=true)
+    private String userName;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private Config config;
+
+    @Inject
+    private Domain domain;
+    
+    @Inject
+    private RealmsManager realmsManager;
+    
+    @Inject
+    private AdminService adminService;
+    
+    private SecureAdmin secureAdmin = null;
+
+    @AccessRequired.To("update")
+    private AuthRealm fileAuthRealm;
+    
+    private SecurityService securityService;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        config = CLIUtil.chooseConfig(domain, target, context.getActionReport());
+        if (config == null) {
+            return false;
+        }
+        securityService = config.getSecurityService();
+        fileAuthRealm = CLIUtil.findRealm(securityService, authRealmName);
+        if (fileAuthRealm == null) {
+            final ActionReport report = context.getActionReport();
+            report.setMessage(localStrings.getLocalString(
+                "update.file.user.filerealmnotfound",
+                "File realm {0} does not exist", 
+                authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;                                            
+        }
+        /*
+         * The realm might have been defaulted, so capture the actual name.
+         */
+        authRealmName = fileAuthRealm.getName();
+        return true;
+    }
+    
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are the paramter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        
+        final ActionReport report = context.getActionReport();
+
+        // Get FileRealm class name, match it with what is expected.
+        String fileRealmClassName = fileAuthRealm.getClassname();
+        
+        // Report error if provided impl is not the one expected
+        if (fileRealmClassName != null && 
+            !fileRealmClassName.equals(
+                "com.sun.enterprise.security.auth.realm.file.FileRealm")) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "update.file.user.realmnotsupported",
+                    "Configured file realm {0} is not supported.",
+                    fileRealmClassName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;                
+        }
+
+        // ensure we have the file associated with the authrealm
+        String keyFile = null;
+        for (Property fileProp : fileAuthRealm.getProperty()) {
+            if (fileProp.getName().equals("file"))
+                keyFile = fileProp.getValue();
+        }
+        if (keyFile == null) {
+            report.setMessage(
+                localStrings.getLocalString("update.file.user.keyfilenotfound",
+                "There is no physical file associated with file realm {0}", 
+                authRealmName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;                                            
+        }
+        boolean exists = (new File(keyFile)).exists();
+        if (!exists) {
+            report.setMessage(
+                localStrings.getLocalString("file.realm.keyfilenonexistent",
+                "The specified physical file {0} associated with the file realm {1} does not exist.",
+                new Object[]{keyFile, authRealmName}));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;
+        }
+        
+        // Now get all inputs ready. userid and groups are straightforward but
+        // password is tricky. It is stored in the file passwordfile passed 
+        // through the CLI options. It is stored under the name 
+        // AS_ADMIN_USERPASSWORD. Fetch it from there.
+        String password = userpassword; // fetchPassword(report);
+        if (password == null && groups == null) {
+            report.setMessage(localStrings.getLocalString(
+                "update.file.user.keyfilenotreadable", "None of password or groups have been specified for update,"
+              + "Password for user {0} has to be specified"
+              + "through AS_ADMIN_USERPASSWORD property in the file specified " 
+              + "in --passwordfile option", userName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;
+        }
+        //Issue 17525 Fix - Check for null passwords for admin-realm if secureadmin is enabled
+        if (password != null) {
+            secureAdmin = domain.getSecureAdmin();
+            if ((SecureAdmin.Util.isEnabled(secureAdmin))
+                    && (adminService.getAuthRealmName().equals(authRealmName))) {
+                if ((password.isEmpty())) {
+                    report.setMessage(localStrings.getLocalString(
+                            "null_empty_password", "The admin user password is empty"));
+                    report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                    return;
+                }
+            }
+        }
+
+        //even though update-file-user is not an update to the security-service
+        //do we need to make it transactional by referncing the securityservice
+        //hypothetically ?.
+        //TODO: check and enclose the code below inside ConfigSupport.apply(...)
+        FileRealm fr = null;
+        try {
+            realmsManager.createRealms(config);
+            fr = (FileRealm) realmsManager.getFromLoadedRealms(config.getName(),authRealmName);
+            if (fr == null) {
+                throw new NoSuchRealmException(authRealmName);
+            }
+        } catch(NoSuchRealmException e) {
+            report.setMessage(
+                localStrings.getLocalString(
+                    "update.file.user.realmnotsupported",
+                    "Configured file realm {0} does not exist.", authRealmName) +
+                "  " + e.getLocalizedMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+            return;
+        }
+
+        //now updating user
+        try {
+            CreateFileUser.handleAdminGroup(authRealmName, groups);
+            String[] groups1 = (groups == null) ? null: groups.toArray(new String[groups.size()]);
+            fr.updateUser(userName, userName, password, groups1);
+            fr.persist();
+            report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+        } catch (Exception e) {
+            report.setMessage(
+                localStrings.getLocalString("update.file.user.userupdatefailed",
+                "Updating user {0} in file realm {1} failed", 
+                userName, authRealmName) + "  " + e.getLocalizedMessage() );
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(e);
+        }        
+    }
+        
+    /* private String fetchPassword(ActionReport report) {
+        String password = null;
+        if (userpassword != null && passwordFile != null)
+            return password;
+        if (userpassword != null) 
+            password = userpassword;
+        if (passwordFile != null) {
+            File passwdFile = new File(passwordFile);
+            InputStream is = null;
+            try {
+                is = new BufferedInputStream(new FileInputStream(passwdFile));
+                Properties prop = new Properties();
+                prop.load(is);            
+                for (Enumeration e=prop.propertyNames(); e.hasMoreElements();) {
+                    String entry = (String)e.nextElement();
+                    if (entry.equals("AS_ADMIN_USERPASSWORD")) {                    
+                        password = prop.getProperty(entry);
+                        break;
+                    }
+                }
+            } catch(Exception e) {
+                report.setFailureCause(e);
+            } finally {
+                try {
+                    if (is != null) 
+                        is.close();
+                } catch(final Exception ignore){}
+            }        
+        } 
+        return password;
+    } */
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/UpdatePasswordAlias.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/UpdatePasswordAlias.java
new file mode 100644
index 0000000..99264a2
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/UpdatePasswordAlias.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.cli;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.security.store.DomainScopedPasswordAliasStore;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.I18n;
+import org.glassfish.api.Param;
+import org.glassfish.api.ActionReport;
+import org.jvnet.hk2.annotations.Service;
+
+import org.glassfish.hk2.api.PerLookup;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import javax.inject.Inject;
+
+/**
+ * Update Password Alias Command
+ *
+ * Usage: update-password-alias [--terse=false] [--echo=false]
+ *        [--interactive=true] [--host localhost] [--port 4848|4849]
+ *        [--secure | -s] [--user admin_user] [--passwordfile file_name] aliasname
+ *
+ * Result of the command is that:
+ * the entry of the form: aliasname=<password-encrypted-with-masterpassword> in
+ * <domain-dir>/<domain-name>/config/domain-passwords file gets updated with the
+ * new alias password
+ *
+ * domain.xml example entry is:
+ * <provider-config class-name="com.sun.xml.wss.provider.ClientSecurityAuthModule"
+ *                  provider-id="XWS_ClientProvider" provider-type="client">
+ *      <property name="password" value="${ALIAS=myalias}/>
+ * </provider-config>
+ *
+ * @author Nandini Ektare
+ */
+
+@Service(name="update-password-alias")
+@PerLookup
+@I18n("update.password.alias")
+@ExecuteOn({RuntimeType.DAS})
+@TargetType({CommandTarget.DAS,CommandTarget.DOMAIN})
+@RestEndpoints({
+    @RestEndpoint(configBean=Domain.class,
+        opType=RestEndpoint.OpType.POST, 
+        path="update-password-alias", 
+        description="update-password-alias")
+})
+@AccessRequired(resource="domain/passwordAliases/passwordAlias/$aliasName", action="update")
+public class UpdatePasswordAlias implements AdminCommand {
+
+    final private static LocalStringManagerImpl localStrings =
+        new LocalStringManagerImpl(CreatePasswordAlias.class);
+
+    @Param(name="aliasname", primary=true)
+    private String aliasName;
+
+    @Param(name="aliaspassword", password=true)
+    private String aliasPassword;
+
+    @Inject
+    private DomainScopedPasswordAliasStore domainPasswordAliasStore;
+
+    /**
+     * Executes the command with the command parameters passed as Properties
+     * where the keys are parameter names and the values the parameter values
+     *
+     * @param context information
+     */
+    public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+
+        try {
+            if ( ! domainPasswordAliasStore.containsKey(aliasName)) {
+                report.setMessage(localStrings.getLocalString(
+                    "update.password.alias.notfound",
+                    "Password alias for the alias {0} does not exist.",
+                    aliasName));
+                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                return;
+            }
+
+            domainPasswordAliasStore.put(aliasName, aliasPassword.toCharArray());
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            report.setMessage(localStrings.getLocalString(
+                "update.password.alias.fail",
+                "Update of Password Alias {0} failed", aliasName));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(ex);
+            return;
+        }
+        report.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+        report.setMessage(localStrings.getLocalString(
+            "update.password.alias.success",
+            "Encrypted password for the alias {0} updated successfully",
+            aliasName));
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/AbstractSecurityContext.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/AbstractSecurityContext.java
new file mode 100644
index 0000000..16e012d
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/AbstractSecurityContext.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.common;
+
+import com.sun.enterprise.security.integration.AppServSecurityContext;
+import java.security.Principal;
+import javax.security.auth.Subject;
+
+/**
+ * This base class defines the methods that Security Context should exhibit.
+ * There are two places where a derived class are used. They are on the 
+ * appclient side and ejb side. The derived classes can use thread local
+ * storage to store the security contexts.
+ * 
+ * @author Harpreet Singh
+ */
+public abstract class AbstractSecurityContext implements AppServSecurityContext, java.io.Serializable {
+    // the principal that this security context represents.
+    protected Principal initiator = null;
+    protected Subject subject = null;
+    
+    /**
+     * This method should  be implemented by the subclasses to
+     * return the caller principal. This information may be redundant
+     * since the same information can be inferred by inspecting the
+     * Credentials of the caller. 
+     * @return The caller Principal. 
+     */
+    abstract public Principal getCallerPrincipal();
+    
+    /**
+     * This method should be implemented by the subclasses to return 
+     * the Credentials of the caller principal.
+     * @return A credentials object associated with the current client 
+     * invocation.
+     */
+    abstract public Subject getSubject();
+}
+
+
+
+
+
+
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/AppservAccessController.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/AppservAccessController.java
new file mode 100644
index 0000000..12b481c
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/AppservAccessController.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.common;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * This class provides an optimization for some methods in
+ * java.security.AccessController.
+ * @author Shing Wai Chan
+ */
+public final class AppservAccessController {
+    private static boolean isSecMgrOff = (System.getSecurityManager() == null);
+
+    private AppservAccessController() {
+    }
+
+    public static Object doPrivileged(PrivilegedAction action) {
+        if (isSecMgrOff) {
+            return action.run();
+        } else {
+            return AccessController.doPrivileged(action);
+        }
+    }
+
+    public static Object doPrivileged(PrivilegedExceptionAction action)
+             throws PrivilegedActionException {
+
+        if (isSecMgrOff) {
+            try {
+                return action.run();       
+            } catch(Exception e) {
+                throw new PrivilegedActionException(e);
+            }
+        } else {
+            return AccessController.doPrivileged(action);
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/ClientSecurityContext.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/ClientSecurityContext.java
new file mode 100644
index 0000000..7a6ec68
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/ClientSecurityContext.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.common;
+
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.security.integration.AppServSecurityContext;
+import java.security.Principal;
+import javax.security.auth.Subject;
+
+import org.glassfish.security.common.PrincipalImpl;
+//V3:Comment import com.sun.enterprise.ServerConfiguration;
+
+import java.util.logging.*;
+import com.sun.logging.*;
+
+
+/**
+ * This class represents the security context on the client side.
+ * For usage of the IIOP_CLIENT_PER_THREAD_FLAG flag, see
+ * UsernamePasswordStore. When set to false, the volatile
+ * field sharedCsc is used to store the context.
+ *
+ * @see UsernamePasswordStore
+ * @author Harpreet Singh
+ *
+ */
+public final class ClientSecurityContext extends AbstractSecurityContext {
+    
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+
+    public static final String IIOP_CLIENT_PER_THREAD_FLAG =
+        "com.sun.appserv.iiopclient.perthreadauth";
+
+    // Bug Id: 4787940
+    private static final boolean isPerThreadAuth = 
+            Boolean.getBoolean(IIOP_CLIENT_PER_THREAD_FLAG);
+
+    // either the thread local or shared version will be used
+    private static ThreadLocal localCsc =
+        isPerThreadAuth ? new ThreadLocal() : null;
+    private static volatile ClientSecurityContext sharedCsc;
+
+    /**
+     * This creates a new ClientSecurityContext object.
+     * @param The name of the user.
+     * @param The Credentials of the user.
+     */
+    public ClientSecurityContext(String userName, 
+				 Subject s) {
+
+	this.initiator = new PrincipalImpl(userName);
+	this.subject = s ;
+    }
+
+    /**
+     * Initialize the SecurityContext & handle the unauthenticated
+     * principal case
+     
+    public static ClientSecurityContext init() {
+	ClientSecurityContext sc = getCurrent();
+	if (sc == null) { // there is no current security context
+            // create a default one if
+	    sc = generateDefaultSecurityContext();
+        }
+	return sc;
+    }*/
+    
+   /*
+    private static ClientSecurityContext generateDefaultSecurityContext() {
+	final String PRINCIPAL_NAME = "auth.default.principal.name";
+	final String PRINCIPAL_PASS = "auth.default.principal.password";
+	
+        
+	//ServerConfiguration config = ServerConfiguration.getConfiguration();
+	//String username = config.getProperty(PRINCIPAL_NAME, "guest");
+	//String password = config.getProperty(PRINCIPAL_PASS, "guest123");
+	
+        //Temporary hardcoding to make V3 code for WebProfile compile
+        String username ="guest";
+        char[] password = new char[]{'g','e','t','s','t','1','2','3'};
+        synchronized (ClientSecurityContext.class) {
+            // login & all that stuff..
+            try {
+                final Subject subject = new Subject();
+                final PasswordCredential pc = new PasswordCredential(username,
+                        password, "default");
+                AppservAccessController.doPrivileged(new PrivilegedAction() {
+                    public java.lang.Object run() {
+                        subject.getPrivateCredentials().add(pc);
+                        return null;
+                    }
+                });
+                // we do not need to generate any credential as authorization
+                // decisions are not being done on the appclient side.
+                ClientSecurityContext defaultCSC =
+                    new ClientSecurityContext(username, subject);
+                setCurrent(defaultCSC);
+                return defaultCSC;
+            } catch(Exception e) {
+                _logger.log(Level.SEVERE,
+                            "java_security.gen_security_context", e);
+                return null;
+            }
+        }
+    }
+    */
+
+    /**
+     * This method gets the SecurityContext stored here.  If using a
+     * per-thread authentication model, it gets the context from
+     * Thread Local Store (TLS) of the current thread. If not using a
+     * per-thread authentication model, it gets the singleton context.
+     *
+     * @return The current Security Context stored here. It returns
+     *      null if SecurityContext could not be found.
+     */
+    public static ClientSecurityContext getCurrent() {
+        if (isPerThreadAuth) {
+            return (ClientSecurityContext) localCsc.get();
+        } else {
+            return sharedCsc;
+        }
+    }
+
+    /**
+     * This method sets the SecurityContext to be stored here.
+     * 
+     * @param The Security Context that should be stored.
+     */
+    public static void setCurrent(ClientSecurityContext sc) {
+        if (isPerThreadAuth) {
+            localCsc.set(sc);
+        } else {
+            sharedCsc = sc;
+        }
+    } 
+
+    /**
+     * This method returns the caller principal. 
+     * This information may be redundant since the same information 
+     * can be inferred by inspecting the Credentials of the caller.
+     * 
+     * @return The caller Principal. 
+     */
+    public Principal getCallerPrincipal() {
+	return initiator;
+    }
+
+    
+    public Subject getSubject() {
+	return subject;
+    }
+
+    public String toString() {
+	return "ClientSecurityContext[ " + "Initiator: " + initiator +
+	    "Subject " + subject + " ]";
+    }
+    
+    //added for CR:6620388
+    public static boolean hasEmtpyCredentials(ClientSecurityContext sc) {
+        if (sc == null) {
+            return true;
+        }
+        Subject s = sc.getSubject();
+        if (s == null) {
+            return true;
+        }
+        if (s.getPrincipals().isEmpty()) {
+            return true;
+        }
+        return false;
+    }
+
+    public AppServSecurityContext newInstance(String userName, Subject subject, String realm) {
+        //TODO:V3 ignoring realm in this case
+        return new ClientSecurityContext(userName, subject);
+    }
+
+    public AppServSecurityContext newInstance(String userName, Subject subject) {
+        return new ClientSecurityContext(userName, subject);
+    }
+
+    public void setCurrentSecurityContext(AppServSecurityContext context) {
+        if (context instanceof ClientSecurityContext) {
+            setCurrent((ClientSecurityContext)context);
+            return;
+        }
+        throw new IllegalArgumentException("Expected ClientSecurityContext, found " + context);
+    }
+
+    public AppServSecurityContext getCurrentSecurityContext() {
+         return getCurrent();
+    }
+
+    public void setUnauthenticatedSecurityContext() {
+        throw new UnsupportedOperationException("Not supported yet in V3.");
+    }
+
+    public void setSecurityContextWithPrincipal(Principal principal) {
+        throw new UnsupportedOperationException("Not supported yet in V3.");
+    }
+    
+
+}
+
+
+
+
+
+
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/EmbeddedSecurityLifeCycle.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/EmbeddedSecurityLifeCycle.java
new file mode 100644
index 0000000..58f3096
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/EmbeddedSecurityLifeCycle.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.common;
+
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.security.EmbeddedSecurity;
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.server.pluggable.SecuritySupport;
+import com.sun.enterprise.util.io.FileUtils;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.internal.embedded.EmbeddedFileSystem;
+import org.glassfish.internal.embedded.EmbeddedLifecycle;
+import org.glassfish.internal.embedded.Server;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jvnet.hk2.annotations.Service;
+
+/**
+ *
+ * @author Nithya Subramanian
+ */
+
+@Service
+public class EmbeddedSecurityLifeCycle
+        implements EmbeddedLifecycle{
+
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+
+    @Inject
+    private EmbeddedSecurity embeddedSecurity;
+
+    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
+    private SecurityService securityService;
+
+    @Override
+    public void creation(Server server) {
+
+        //If the instanceRoot is not set to a non-embedded GF install,
+        //copy the security config files from the security.jar to the instanceRoot/config dir
+
+        EmbeddedFileSystem fileSystem = server.getFileSystem();
+        File instanceRoot = fileSystem.instanceRoot;
+        if (instanceRoot == null) {
+            return;
+        }
+
+        try {
+            //Get the keyfile names from the security service
+            List<String> keyFileNames = embeddedSecurity.getKeyFileNames(securityService);
+            for(String keyFileName:keyFileNames) {
+                //Copy the keyfiles in instanceRoot/config. If file is already present, then exit (handled by getManagedFile)
+                FileUtils.getManagedFile("config" + File.separator + embeddedSecurity.parseFileName(keyFileName), instanceRoot);
+            }
+            //Copy the other security files to instanceRoot/config
+            //Assuming that these files are present as config/filename in the embedded jar file and are to be extracted that way/
+            FileUtils.getManagedFile("config" + File.separator + "login.conf", instanceRoot);
+            FileUtils.getManagedFile("config" + File.separator + "server.policy", instanceRoot);
+            FileUtils.getManagedFile("config" + File.separator + "cacerts.jks", instanceRoot);
+            FileUtils.getManagedFile("config" + File.separator + "keystore.jks", instanceRoot);
+            String keystoreFile = null;
+            String truststoreFile = null;
+            try {
+                keystoreFile = Util.writeConfigFileToTempDir("keystore.jks").getAbsolutePath();
+                truststoreFile = Util.writeConfigFileToTempDir("cacerts.jks").getAbsolutePath();
+            } catch (IOException ex) {
+                _logger.log(Level.SEVERE, SecurityLoggerInfo.obtainingKeyAndTrustStoresError, ex);
+            }
+            System.setProperty(SecuritySupport.keyStoreProp, keystoreFile);
+            System.setProperty(SecuritySupport.trustStoreProp, truststoreFile);
+        }catch(IOException ioEx) {
+           _logger.log(Level.WARNING, SecurityLoggerInfo.copyingSecurityConfigFilesIOError, ioEx);
+        }
+    }
+
+    @Override
+    public void destruction(Server server) {
+
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/SecurityConstants.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/SecurityConstants.java
new file mode 100644
index 0000000..5c73baf
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/SecurityConstants.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.common;
+
+/**
+ *
+ * @author Kumar
+ */
+public interface SecurityConstants {
+
+    //copied from appclient.security to avoid dependency
+    public static final int USERNAME_PASSWORD = 1;
+    public static final int CERTIFICATE = 2;
+    // harry - added for LoginContextDriver access
+    public static final int ALL = 3;
+    
+    public static final String CLIENT_JAAS_PASSWORD = "default";
+    public static final String CLIENT_JAAS_CERTIFICATE = "certificate";
+
+    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/Util.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/Util.java
new file mode 100644
index 0000000..bd92d9f
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/common/Util.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.common;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import javax.security.auth.callback.CallbackHandler;
+import org.glassfish.api.admin.ProcessEnvironment;
+import org.glassfish.api.admin.ProcessEnvironment.ProcessType;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.internal.api.Globals;
+import org.glassfish.internal.embedded.Server;
+import javax.inject.Inject;
+
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Singleton;
+
+/**
+ *
+ * @author venu
+ * TODO: need to change this class, it needs to be similar to SecurityServicesUtil
+ */
+@Service
+@Singleton
+public class Util {
+    private static ServiceLocator habitat = Globals.getDefaultHabitat();
+    
+    @Inject 
+    private ProcessEnvironment penv;
+    
+   
+    //stuff required for AppClient
+    private CallbackHandler callbackHandler;
+    private Object appClientMsgSecConfigs;
+    
+    //Note: Will return Non-Null only after Util has been 
+    //Injected in some Service.
+    public static ServiceLocator getDefaultHabitat() {
+        return habitat;
+    }
+    
+    public static Util getInstance() {
+        // return my singleton service
+        return habitat.getService(Util.class);
+    }
+    
+    public boolean isACC() {
+        return penv.getProcessType().equals(ProcessType.ACC);
+    }
+    public boolean isServer() {
+        return penv.getProcessType().isServer();
+    }
+    public boolean isNotServerOrACC() {
+        return penv.getProcessType().equals(ProcessType.Other);
+    }
+
+    public CallbackHandler getCallbackHandler() {
+        return callbackHandler;
+    }
+
+    public void setCallbackHandler(CallbackHandler callbackHandler) {
+        this.callbackHandler = callbackHandler;
+    }
+
+    public Object getAppClientMsgSecConfigs() {
+        return appClientMsgSecConfigs;
+    }
+
+    public void setAppClientMsgSecConfigs(Object appClientMsgSecConfigs) {
+        this.appClientMsgSecConfigs = appClientMsgSecConfigs;
+    }
+    
+    public static boolean isEmbeddedServer() {
+        List<String> servers = Server.getServerNames();
+        if (!servers.isEmpty()) {
+            return true;
+        }
+        return false;
+    }
+    
+    public static File writeConfigFileToTempDir(String fileName) throws IOException {
+        File filePath = new File(fileName);
+
+        if (filePath.exists()) {
+            //the string provided is a filepath, so return
+            return filePath;
+        }
+        File localFile = null;
+        //Parent directories until the fileName exist, so create the file that has been provided
+        if (filePath.getParentFile() != null && filePath.getParentFile().exists()) {
+            localFile = filePath;
+            if(!localFile.createNewFile()) {
+                throw new IOException();
+            }
+
+        } else {
+            /*
+             * File parent directory does not exist - so create parent directory as user.home/.glassfish-{embedded}/config
+             * */
+            String userHome = System.getProperty("user.home");
+
+            String embeddedServerName = getCurrentEmbeddedServerName();
+            File tempDir = new File(userHome + File.separator + ".glassfish5-"+embeddedServerName+File.separator + "config");
+            boolean mkDirSuccess = true;
+            if (!tempDir.exists()) {
+                mkDirSuccess = tempDir.mkdirs();
+            }
+
+            localFile = new File(tempDir.getAbsolutePath()+File.separator + fileName);
+
+
+            if (mkDirSuccess && !localFile.exists()) {
+                localFile.createNewFile();
+            }
+        }
+        FileOutputStream oStream = null;
+        InputStream iStream = null;
+        try {
+            oStream = new FileOutputStream(localFile);
+            iStream = Util.class.getResourceAsStream("/config/" + fileName);
+
+            while (iStream != null && iStream.available() > 0) {
+                oStream.write(iStream.read());
+            }
+        } finally {
+	    if (oStream != null) {
+                oStream.close();
+	    }
+            if  (iStream != null) {
+                iStream.close();
+            }
+
+        }
+
+        return localFile;
+
+    }
+
+    public static String getCurrentEmbeddedServerName() {
+        List<String> embeddedServerNames = Server.getServerNames();
+        String embeddedServerName = (embeddedServerNames.get(0) == null) ? "embedded" : embeddedServerNames.get(0);
+        return embeddedServerName;
+
+    }
+    
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/embedded/EmbeddedSecurityUtil.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/embedded/EmbeddedSecurityUtil.java
new file mode 100644
index 0000000..28a1f75
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/embedded/EmbeddedSecurityUtil.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.embedded;
+
+import com.sun.enterprise.config.serverbeans.AuthRealm;
+import com.sun.enterprise.config.serverbeans.SecurityService;
+import com.sun.enterprise.security.EmbeddedSecurity;
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.util.StringUtils;
+import com.sun.enterprise.util.io.FileUtils;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.server.ServerEnvironmentImpl;
+
+import org.jvnet.hk2.annotations.Service;
+import javax.inject.Singleton;
+import org.jvnet.hk2.config.types.Property;
+
+/**
+ * Utility file to copy the security related config files
+ * from the passed non-embedded instanceDir to the embedded
+ * server instance's config.
+ * This is a service that is protected. This implements
+ * the Contract EmbeddedSecurity
+ * 
+ * @author Nithya Subramanian
+ */
+
+@Service
+@Singleton
+public class EmbeddedSecurityUtil implements EmbeddedSecurity {
+
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+    
+    public void copyConfigFiles(ServiceLocator habitat, File fromInstanceDir, File domainXml) {
+        //For security reasons, permit only an embedded server instance to carry out the copy operations
+        ServerEnvironment se = habitat.getService(ServerEnvironment.class);
+        if (!isEmbedded(se)) {
+            return;
+        }
+
+        if ((fromInstanceDir == null) || (domainXml == null)) {
+            throw new IllegalArgumentException("Null inputs");
+        }
+
+        File toInstanceDir = habitat.<ServerEnvironmentImpl>getService(ServerEnvironmentImpl.class).getInstanceRoot();
+
+        List<String> fileNames = new ArrayList<String>();
+
+        //Handling the exception here, since it is causing CTS failure - CR 6981191
+
+        try {
+
+            //Add FileRealm keyfiles to the list
+            fileNames.addAll(new EmbeddedSecurityUtil().new DomainXmlSecurityParser(domainXml).getAbsolutePathKeyFileNames(fromInstanceDir));
+
+            //Add keystore and truststore files
+
+            // For the embedded server case, will the system properties be set in case of multiple embedded instances?
+            //Not sure - so obtain the other files from the usual locations instead of from the System properties
+
+            String keyStoreFileName = fromInstanceDir + File.separator + "config" + File.separator + "keystore.jks";
+            String trustStoreFileName = fromInstanceDir + File.separator + "config" + File.separator + "cacerts.jks";
+
+            fileNames.add(keyStoreFileName);
+            fileNames.add(trustStoreFileName);
+
+            //Add login.conf and security policy
+
+            String loginConf = fromInstanceDir + File.separator + "config" + File.separator + "login.conf";
+            String secPolicy = fromInstanceDir + File.separator + "config" + File.separator + "server.policy";
+
+            fileNames.add(loginConf);
+            fileNames.add(secPolicy);
+
+            File toConfigDir = new File(toInstanceDir, "config");
+            if (!toConfigDir.exists()) {
+                if(!toConfigDir.mkdir()) {
+                    throw new IOException();
+                }
+            }
+
+            //Copy files into new directory
+            for (String fileName : fileNames) {
+                FileUtils.copyFile(new File(fileName), new File(toConfigDir, parseFileName(fileName)));
+            }
+        }catch(IOException e) {
+            _logger.log(Level.WARNING, SecurityLoggerInfo.ioError, e);
+        }catch(XMLStreamException e) {
+            _logger.log(Level.WARNING, SecurityLoggerInfo.xmlStreamingError, e);
+        }
+
+
+
+    }
+
+    public String parseFileName(String fullFilePath) {
+        if (fullFilePath == null) {
+            return null;
+        }
+        File file = new File(fullFilePath);
+        return file.getName();
+       
+    }
+
+    public boolean isEmbedded(ServerEnvironment se) {
+        if (se.getRuntimeType() == RuntimeType.EMBEDDED) {
+            return true;
+        }
+        return false;
+    }
+
+    public List<String> getKeyFileNames(SecurityService securityService) {
+        List<String> keyFileNames = new ArrayList<String>();
+
+        List<AuthRealm> authRealms = securityService.getAuthRealm();
+        for (AuthRealm authRealm : authRealms) {
+            String className = authRealm.getClassname();
+            if ("com.sun.enterprise.security.auth.realm.file.FileRealm".equals(className)) {
+                List<Property> props = authRealm.getProperty();
+                for (Property prop : props) {
+                    if ("file".equals(prop.getName())) {
+                        keyFileNames.add(prop.getValue());
+                    }
+                }
+            }
+        }
+
+        return keyFileNames;
+    }
+
+    //Inner class to parse the domainXml to obtain the keyfile names
+    class DomainXmlSecurityParser {
+
+        XMLStreamReader xmlReader;
+        XMLInputFactory xif =
+                (XMLInputFactory.class.getClassLoader() == null)
+                ? XMLInputFactory.newInstance()
+                : XMLInputFactory.newInstance(XMLInputFactory.class.getName(),
+                XMLInputFactory.class.getClassLoader());
+
+        private static final String AUTH_REALM = "auth-realm";
+        private static final String CONFIG = "config";
+        private static final String CLASSNAME = "classname";
+        private static final String FILE_REALM_CLASS = "com.sun.enterprise.security.auth.realm.file.FileRealm";
+        private static final String PROPERTY = "property";
+        private static final String NAME = "name";
+        private static final String VALUE = "value";
+        private static final String FILE = "file";
+        private static final String INSTANCE_DIR_PLACEHOLDER = "${com.sun.aas.instanceRoot}";
+
+        DomainXmlSecurityParser(File domainXml) throws XMLStreamException, FileNotFoundException {
+            xif.setProperty("javax.xml.stream.isSupportingExternalEntities", false);
+            xif.setProperty("javax.xml.stream.isValidating", true);
+            xmlReader = xif.createXMLStreamReader(new FileReader(domainXml));
+        }
+
+        private String replaceInstanceDir(String fromInstanceDir, String keyFileName) {
+            return StringUtils.replace(keyFileName, INSTANCE_DIR_PLACEHOLDER, fromInstanceDir);
+
+        }
+        //Obtain the keyfile names for the server-config (the first appearing config in domain.xml
+        List<String> getAbsolutePathKeyFileNames(File fromInstanceDir) throws XMLStreamException {
+            List<String> keyFileNames = new ArrayList<String>();
+            while (skipToStartButNotPast(AUTH_REALM, CONFIG)) {
+                String realmClass = xmlReader.getAttributeValue(null, CLASSNAME);
+                if (realmClass.equals(FILE_REALM_CLASS)) {
+                    while (skipToStartButNotPast(PROPERTY, AUTH_REALM)) {
+                        if (FILE.equals(xmlReader.getAttributeValue(null, NAME))) {
+                            String keyFileName = xmlReader.getAttributeValue(null, VALUE);
+                            //Replace the Placeholder in the keyfile names
+                            keyFileNames.add(replaceInstanceDir(fromInstanceDir.getAbsolutePath(),keyFileName ));
+
+                        }
+                    }
+                }
+            }
+            return keyFileNames;
+        }
+
+        private boolean skipToStartButNotPast(String startName, String stopName) throws XMLStreamException {
+            if (!StringUtils.ok(startName) || !StringUtils.ok(stopName)) {
+                throw new IllegalArgumentException();
+            }
+
+            while (xmlReader.hasNext()) {
+                xmlReader.next();
+                // getLocalName() will throw an exception in many states.  Be careful!!
+                if (xmlReader.isStartElement() && startName.equals(xmlReader.getLocalName())) {
+                    return true;
+                }
+                if (xmlReader.isEndElement() && stopName.equals(xmlReader.getLocalName())) {
+                    return false;
+                }
+            }
+            return false;
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/factory/SecurityManagerFactory.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/factory/SecurityManagerFactory.java
new file mode 100644
index 0000000..5887a83
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/factory/SecurityManagerFactory.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.factory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * @author monzillo
+ */
+public class SecurityManagerFactory {
+
+    protected SecurityManagerFactory() {
+      //do not allow creation of this base class directly
+    }
+    /**
+     * find SecurityManager by policy context identifier and name (as 
+     * secondary key). There is a separate SecurityManager for each EJB of
+     * a module; they all share the same policy context identifier, and are 
+     * differentiated by (ejb) name. There is one SecurityManager per web 
+     * module/policy context identifier.
+     * 
+     * @param iD2sMmap maps policy context id (as key) to subordinate map 
+     * (as value) of (module) name (as key) to SecurityManagers (as value).
+     * @param ctxId the policy context identifier (i.e., the primary key of the
+     * lookup
+     * @param name the name of the component (e.g., the ejb name when looking up
+     * an EJBSecurityManager. for WebSecurityManagers this value should be null 
+     * @param remove boolean indicating whether the corresponding SecurityManager
+     * is to be deleted from the map. 
+     * @return the selected SecurityManager or null.
+     */
+    public<T> T getManager(Map<String, Map<String, T>> iD2sMmap,
+            String ctxId, String name, boolean remove) {
+
+        T manager = null;
+
+        synchronized (iD2sMmap) {
+            Map<String, T> managerMap = iD2sMmap.get(ctxId);
+            if (managerMap != null) {
+                manager = managerMap.get(name);
+                if (remove) {
+                    managerMap.remove(name);
+                    if (managerMap.isEmpty()) {
+                        iD2sMmap.remove(ctxId);
+                    }
+                }
+            }
+
+        }
+
+        return manager;
+    }
+
+    /**
+     * Get all SecurityManagers associated with a policy context identifier. 
+     * EJBs from the same jar, all share the same policy context identifier, but
+     * each have their own SecurityManager. WebSecurityManager(s)
+     * map 1-to-1 to policy context identifier.
+     * 
+     * @param iD2sMmap maps policy context id (as key) to subordinate map 
+     * (as value) of (module) name (as key) to SecurityManagers (as value).
+     * @param ctxId the policy context identifier (i.e., the lookup key).
+     * @param remove boolean indicating whether the corresponding
+     * SecurityManager(s) are to be deleted from the map. 
+     * @return a non-empty ArrayList containing the selected managers, or null. 
+     */
+    public <T> ArrayList<T> getManagers(Map<String, Map<String, T>> iD2sMmap,
+            String ctxId, boolean remove) {
+
+        ArrayList<T> managers = null;
+
+        synchronized (iD2sMmap) {
+            Map<String, T> managerMap = iD2sMmap.get(ctxId);
+
+            if (managerMap != null && !managerMap.isEmpty()) {
+                managers = new ArrayList(managerMap.values());
+            }
+            if (remove) {
+                iD2sMmap.remove(ctxId);
+            }
+        }
+        return managers;
+    }
+
+    /**
+     * Get (Web or EJB) SecurityManagers associated with an application.
+     * Note that the WebSecurityManager and EJBSecurityManager classes manage
+     * separate maps for their respectibe security manager types.
+     * 
+     * @param iD2sMmap maps policy context id (as key) to subordinate map 
+     * (as value) of (module) name (as key) to SecurityManagers (as value).
+     * @param app2iDmap maps appName (as key) to list of policy context
+     * identifiers (as value). 
+     * @param appName the application name, (i.e., the lookup key)
+     * @param remove boolean indicating whether the corresponding mappings
+     * are to be removed from the app2iDmap and aiD2sMmap.
+     * @return a non-empty ArrayList containing the selected managers, or null. 
+     */
+    public <T> ArrayList<T> getManagersForApp(Map<String, Map<String, T>> iD2sMmap,
+            Map<String, ArrayList<String>> app2iDmap, String appName, boolean remove) {
+
+        ArrayList<T> managerList = null;
+        String[] ctxIds = getContextsForApp(app2iDmap, appName, remove);
+        if (ctxIds != null) {
+            ArrayList<T> managers = null;
+            synchronized (iD2sMmap) {
+                for (String id : ctxIds) {
+                    managers = getManagers(iD2sMmap, id, remove);
+                    if (managers != null) {
+                        if (managerList == null) {
+                            managerList = new ArrayList<T>();
+                        }
+                        managerList.addAll(managers);
+                    }
+                }
+            }
+        }
+
+        return managerList;
+    }
+
+    /**
+     * Get (EJB or Web) Policy context identifiers for app.
+     * 
+     * @param app2iDmap maps appName (as key) to list of policy context 
+     * identifiers (as value). 
+     * @param appName the application name, (i.e., the lookup key).
+     * @param remove boolean indicating whether the corresponding mappings
+     * are to be removed from the app2iDmap.
+     * @return a non-zero length array containing the selected
+     * policy context identifiers, or null.
+     */
+    public <T> String[] getContextsForApp(Map<String, ArrayList<String>> app2iDmap,
+            String appName, boolean remove) {
+
+        String[] ctxIds = null;
+
+        synchronized (app2iDmap) {
+
+            ArrayList<String> ctxList = app2iDmap.get(appName);
+            if (ctxList != null && !ctxList.isEmpty()) {
+                ctxIds = ctxList.toArray(new String[ctxList.size()]);
+            }
+            if (remove) {
+                app2iDmap.remove(appName);
+            }
+        }
+
+        return ctxIds;
+    }
+
+    /**
+     * In iD2sMmap, maps manager to  ctxId and name, and in app2iDmap, 
+     * includes ctxID in values mapped to appName.   
+     * 
+     * @param iD2sMmap maps policy context id (as key) to subordinate map 
+     * (as value) of (module) name (as key) to SecurityManagers (as value).
+     * @param app2iDmap maps appName (as key) to list of policy context
+     * identifiers (as value). 
+     * @param ctxId the policy context identifier
+     * @param name the component name (the EJB name or null for web modules)
+     * @param appName the application name
+     * @param manager the SecurityManager
+     */
+    public <T> void addManagerToApp(Map<String, Map<String, T>> iD2sMmap,
+            Map<String, ArrayList<String>> app2iDmap,
+            String ctxId, String name, String appName, T manager) {
+
+        synchronized (iD2sMmap) {
+
+            Map<String, T> managerMap = iD2sMmap.get(ctxId);
+
+            if (managerMap == null) {
+                managerMap = new HashMap<String, T>();
+                iD2sMmap.put(ctxId, managerMap);
+            }
+
+            managerMap.put(name, manager);
+        }
+        synchronized (app2iDmap) {
+            ArrayList<String> ctxList = app2iDmap.get(appName);
+
+            if (ctxList == null) {
+                ctxList = new ArrayList<String>();
+                app2iDmap.put(appName, ctxList);
+            }
+
+            if (!ctxList.contains(ctxId)) {
+                ctxList.add(ctxId);
+            }
+        }
+    }
+}   
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/jauth/callback/.gitkeep_empty_dir b/nucleus/security/core/src/main/java/com/sun/enterprise/security/jauth/callback/.gitkeep_empty_dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/jauth/callback/.gitkeep_empty_dir
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/jmac/callback/.gitkeep_empty_dir b/nucleus/security/core/src/main/java/com/sun/enterprise/security/jmac/callback/.gitkeep_empty_dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/jmac/callback/.gitkeep_empty_dir
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/jmac/config/.gitkeep_empty_dir b/nucleus/security/core/src/main/java/com/sun/enterprise/security/jmac/config/.gitkeep_empty_dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/jmac/config/.gitkeep_empty_dir
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/provider/.gitkeep_empty_dir b/nucleus/security/core/src/main/java/com/sun/enterprise/security/provider/.gitkeep_empty_dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/provider/.gitkeep_empty_dir
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/GlassfishSSLImpl.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/GlassfishSSLImpl.java
new file mode 100644
index 0000000..75a5f38
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/GlassfishSSLImpl.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.ssl;
+
+import java.net.Socket;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
+import org.glassfish.grizzly.config.ssl.SSLImplementation;
+import org.glassfish.grizzly.config.ssl.ServerSocketFactory;
+import org.glassfish.grizzly.ssl.SSLSupport;
+import org.jvnet.hk2.annotations.ContractsProvided;
+import org.jvnet.hk2.annotations.Service;
+
+/**
+ *
+ * @author Sudarsan Sridhar
+ */
+@Service(name="com.sun.enterprise.security.ssl.GlassfishSSLImpl")
+@ContractsProvided({GlassfishSSLImpl.class, SSLImplementation.class})
+public class GlassfishSSLImpl extends SSLImplementation {
+    public GlassfishSSLImpl() {
+    }
+
+    public String getImplementationName() {
+        return "Glassfish";
+    }
+
+    public ServerSocketFactory getServerSocketFactory() {
+        return new GlassfishServerSocketFactory();
+    }
+
+    public SSLSupport getSSLSupport(Socket socket) {
+        if(socket instanceof SSLSocket) {
+            return new GlassfishSSLSupport((SSLSocket)socket);
+        }
+        return null;
+    }
+
+    public SSLSupport getSSLSupport(SSLEngine ssle) {
+        return new GlassfishSSLSupport(ssle);
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/GlassfishSSLSupport.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/GlassfishSSLSupport.java
new file mode 100644
index 0000000..535ae0d
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/GlassfishSSLSupport.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.ssl;
+
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import org.glassfish.grizzly.ssl.SSLSupport;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.cert.CertificateFactory;
+import java.util.logging.Level;
+import javax.security.cert.X509Certificate;
+import java.util.logging.Logger;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+/**
+ *
+ * @author Sudarsan Sridhar
+ */
+public class GlassfishSSLSupport implements SSLSupport {
+
+    private final static Logger logger = SecurityLoggerInfo.getLogger();
+    
+    /**
+     * A mapping table to determine the number of effective bits in the key
+     * when using a cipher suite containing the specified cipher name.  The
+     * underlying data came from the TLS Specification (RFC 2246), Appendix C.
+     */
+    private static final CipherData ciphers[] = {
+        new CipherData("_WITH_NULL_", 0),
+        new CipherData("_WITH_IDEA_CBC_", 128),
+        new CipherData("_WITH_RC2_CBC_40_", 40),
+        new CipherData("_WITH_RC4_40_", 40),
+        new CipherData("_WITH_RC4_128_", 128),
+        new CipherData("_WITH_DES40_CBC_", 40),
+        new CipherData("_WITH_DES_CBC_", 56),
+        new CipherData("_WITH_3DES_EDE_CBC_", 168),
+        new CipherData("_WITH_AES_128_", 128),
+        new CipherData("_WITH_AES_256_", 256)
+    };
+    
+    private final SSLSocket socket;
+    private final SSLEngine engine;
+    private SSLSession session;
+
+    public GlassfishSSLSupport(SSLSocket socket) {
+        this.socket = socket;
+        this.engine = null;
+        session = socket.getSession();
+    }
+
+    public GlassfishSSLSupport(SSLEngine engine) {
+        this.socket = null;
+        this.engine = engine;
+        if(engine != null) {
+            session = engine.getSession();
+        }
+    }
+
+    public String getCipherSuite() throws IOException {
+        if (session == null) {
+            return null;
+        }
+        return session.getCipherSuite();
+    }
+
+    public Object[] getPeerCertificateChain() throws IOException {
+        return getPeerCertificateChain(false);
+    }
+
+    public Object[] getPeerCertificateChain(boolean force) throws IOException {
+        if (session == null) {
+            return null;
+        }
+        X509Certificate[] certs = null;
+        certs = session.getPeerCertificateChain();
+        if (certs == null) {
+            certs = new X509Certificate[0];
+        }
+        if (certs.length == 0 && force) {
+            session.invalidate();
+            handshake();
+
+            if (socket == null) {
+                session = engine.getSession();
+            } else {
+                session = socket.getSession();
+            }
+        }
+        return getX509Certs();
+    }
+
+    public Integer getKeySize() throws IOException {
+        if (session == null) {
+            return null;
+        }
+        Integer keySize = (Integer) session.getValue(KEY_SIZE_KEY);
+        if (keySize == null) {
+            int size = 0;
+            String cipherSuite = session.getCipherSuite();
+            for (CipherData cipher : ciphers) {
+                if (cipherSuite.contains(cipher.phrase)) {
+                    size = cipher.keySize;
+                    break;
+                }
+            }
+            keySize = size;
+            session.putValue(KEY_SIZE_KEY, keySize);
+        }
+        return keySize;
+    }
+
+    public String getSessionId() throws IOException {
+        if (session == null) {
+            return null;
+        }
+        byte[] sessionId = session.getId();
+        if (sessionId == null) {
+            return null;
+        }
+        StringBuilder Id = new StringBuilder();
+        for (byte b : sessionId) {
+            String digit = Integer.toHexString(b);
+            if (digit.length() < 2) {
+                Id.append('0');
+            } else if (digit.length() > 2) {
+                digit = digit.substring(digit.length() - 2);
+            }
+            Id.append(digit);
+        }
+        return Id.toString();
+    }
+
+    private void handshake() throws IOException {
+        socket.setNeedClientAuth(true);
+        socket.startHandshake();
+    }
+
+    private Object[] getX509Certs() {
+        X509Certificate certs[] = null;
+        try {
+            certs = session.getPeerCertificateChain();
+        } catch (Throwable ex) {
+            // Get rid of the warning in the logs when no Client-Cert is
+            // available
+        }
+
+        if (certs == null) {
+            certs = new X509Certificate[0];
+        }
+        java.security.cert.X509Certificate[] x509Certs =
+                new java.security.cert.X509Certificate[certs.length];
+        for (int i = 0; i < x509Certs.length; i++) {
+            try {
+                byte buffer[] = certs[i].getEncoded();
+                CertificateFactory cf =
+                        CertificateFactory.getInstance("X.509");
+                ByteArrayInputStream stream =
+                        new ByteArrayInputStream(buffer);
+                x509Certs[i] = (java.security.cert.X509Certificate) cf.generateCertificate(stream);
+                if (logger.isLoggable(Level.FINEST)) {
+                    logger.log(Level.FINE, "Cert #{0} = {1}", new Object[]{i, x509Certs[i]});
+                }
+            } catch (Exception ex) {
+                logger.log(Level.INFO, SecurityLoggerInfo.convertingCertError, new Object[] {certs[i], ex.toString()});
+                return null;
+            }
+        }
+
+        if (x509Certs.length < 1) {
+            return null;
+        }
+        return x509Certs;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/GlassfishServerSocketFactory.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/GlassfishServerSocketFactory.java
new file mode 100644
index 0000000..c2e2d76
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/GlassfishServerSocketFactory.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.ssl;
+
+import java.io.IOException;
+import java.security.KeyStore;
+import java.util.logging.Level;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.X509KeyManager;
+
+import org.glassfish.grizzly.config.ssl.JSSE14SocketFactory;
+import org.glassfish.internal.api.Globals;
+
+/**
+ *
+ * @author Sudarsan Sridhar
+ */
+public class GlassfishServerSocketFactory extends JSSE14SocketFactory {
+
+    private SSLUtils sslUtils;
+
+    @Override
+    protected KeyManager[] getKeyManagers(String algorithm, String keyAlias) throws Exception {
+        if (sslUtils == null) {
+            initSSLUtils();
+        }
+        String keystoreFile = (String) attributes.get("keystore");
+        if (logger.isLoggable(Level.FINE)) {
+            logger.log(Level.FINE, "Keystore file= {0}", keystoreFile);
+        }
+
+        String keystoreType = (String) attributes.get("keystoreType");
+        if (logger.isLoggable(Level.FINE)) {
+            logger.log(Level.FINE, "Keystore type= {0}", keystoreType);
+        }
+        KeyManager[] kMgrs = sslUtils.getKeyManagers(algorithm);
+        if (keyAlias != null && keyAlias.length() > 0 && kMgrs != null) {
+            for (int i = 0; i < kMgrs.length; i++) {
+                kMgrs[i] = new J2EEKeyManager((X509KeyManager) kMgrs[i], keyAlias);
+            }
+        }
+        return kMgrs;
+    }
+
+    @Override
+    protected KeyStore getTrustStore() throws IOException {
+        if (sslUtils == null) {
+            initSSLUtils();
+        }
+        return sslUtils.getTrustStore();
+    }
+
+    private void initSSLUtils() {
+        if (sslUtils == null) {
+            if (Globals.getDefaultHabitat() != null) {
+                sslUtils = Globals.getDefaultHabitat().getService(SSLUtils.class);
+            } else {
+                sslUtils = new SSLUtils();
+                sslUtils.postConstruct();
+            }
+        }
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/J2EEKeyManager.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/J2EEKeyManager.java
new file mode 100644
index 0000000..9450129
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/J2EEKeyManager.java
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.ssl;
+
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509KeyManager;
+import javax.security.auth.Subject;
+
+import com.sun.enterprise.security.SecurityLoggerInfo;
+//import com.sun.enterprise.Switch;
+import com.sun.enterprise.security.common.ClientSecurityContext;
+import com.sun.enterprise.security.auth.login.common.X509CertificateCredential;
+//copied code from LoginContextDriver to break dependency
+//import com.sun.enterprise.security.auth.login.common.LoginContextDriver;
+import com.sun.enterprise.security.auth.login.common.LoginException;
+import com.sun.enterprise.security.auth.login.common.PasswordCredential;
+import com.sun.enterprise.security.common.AppservAccessController;
+import com.sun.enterprise.security.common.SecurityConstants;
+import com.sun.enterprise.security.common.Util;
+
+import java.util.logging.*;
+import com.sun.logging.*;
+import java.security.PrivilegedAction;
+import java.util.Set;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.security.auth.login.LoginContext;
+import com.sun.enterprise.security.ssl.manager.UnifiedX509KeyManager;
+
+/**
+ * This a J2EE specific Key Manager class that is used to select 
+ * user certificates for SSL client authentication. It delegates most
+ * of the functionality to the provider specific KeyManager class.
+ * @author Vivek Nagar
+ * @author Harpreet Singh
+ */
+public final class J2EEKeyManager /*implements X509KeyManager */ extends X509ExtendedKeyManager {
+
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+
+    private X509KeyManager mgr = null; // delegate
+    
+    private String alias = null;
+
+    private Map<String, X509KeyManager> tokenName2MgrMap = null;
+    private boolean supportTokenAlias = false;
+
+    public J2EEKeyManager(X509KeyManager mgr, String alias) {
+        this.mgr = mgr;
+	this.alias = alias;
+
+        if (mgr instanceof UnifiedX509KeyManager) {
+            UnifiedX509KeyManager umgr = (UnifiedX509KeyManager)mgr;
+            X509KeyManager[] mgrs = umgr.getX509KeyManagers();
+            String[] tokenNames = umgr.getTokenNames();
+
+            tokenName2MgrMap = new HashMap<String, X509KeyManager>();
+            for (int i = 0; i < mgrs.length; i++) {
+                if (tokenNames[i] != null) {
+                    tokenName2MgrMap.put(tokenNames[i], mgrs[i]);
+                }
+            }
+            supportTokenAlias = (tokenName2MgrMap.size() > 0);
+        }
+    }
+
+    public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) {
+        return mgr.chooseClientAlias(keyType, issuers, null);
+    }
+
+    public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
+        return alias;
+    }
+
+    /**
+     * Choose the client alias that will be used to select the client
+     * certificate for SSL client auth.
+     * @param the keytype
+     * @param the certificate issuers.
+     * @param the socket used for this connection. This parameter can be null,
+     *        in which case the method will return the most generic alias to use.
+     * @return the alias.
+     */
+    public String chooseClientAlias(String[] keyType, Principal[] issuers,
+    Socket socket) {
+        
+        String clientAlias = null;
+        
+        if(this.alias == null){
+            //InvocationManager im = Switch.getSwitch().getInvocationManager();
+            //if (im == null) {
+            if(Util.getInstance().isNotServerOrACC()) {
+                // standalone client
+                clientAlias = mgr.chooseClientAlias(keyType, issuers, socket);
+            } else {
+                //ComponentInvocation ci = im.getCurrentInvocation();
+                //if (ci == null) {       // 4646060
+                //    throw new InvocationException();
+                //}
+                //Object containerContext = ci.getContainerContext();
+                //if(containerContext != null &&
+                //(containerContext instanceof AppContainer)) {
+                   if (Util.getInstance().isACC()) {
+                    ClientSecurityContext ctx = ClientSecurityContext.getCurrent();
+                    Subject s = ctx.getSubject();
+                    if (s == null) {
+                        // pass the handler and do the login
+                        //TODO V3: LoginContextDriver.doClientLogin(AppContainer.CERTIFICATE,
+                        //AppContainer.getCallbackHandler());
+                        doClientLogin(SecurityConstants.CERTIFICATE,
+                                Util.getInstance().getCallbackHandler());
+                        s = ctx.getSubject();
+                    }
+                    Iterator itr = s.getPrivateCredentials().iterator();
+                    while(itr.hasNext()) {
+                        Object o = itr.next();
+                        if(o instanceof X509CertificateCredential) {
+                            X509CertificateCredential crt =
+                            (X509CertificateCredential) o;
+                            clientAlias = crt.getAlias();
+                            break;
+                        }
+                    }
+                }
+            }
+        }else{
+            clientAlias = this.alias;
+        }
+        if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE, "Choose client Alias :{0}", clientAlias);
+        }
+        return clientAlias;
+    }
+
+    /**
+     * Choose the server alias that will be used to select the server
+     * certificate for SSL server auth.
+     * @param the keytype
+     * @param the certificate issuers.
+     * @param the socket used for this connection. This parameter can be null,
+     *        in which case the method will return the most generic alias to use.
+     * @return the alias
+     */
+    public String chooseServerAlias(String keyType, Principal[] issuers,
+            Socket socket) {
+
+        String serverAlias = null;
+        if(this.alias != null){
+            serverAlias = this.alias;
+        }else{
+            serverAlias =  mgr.chooseServerAlias(keyType, issuers, socket);
+	}
+        if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE, "Choosing server alias :{0}", serverAlias);
+        }         
+        return serverAlias;
+    }
+
+    /**
+     * Return the certificate chain for the specified alias.
+     * @param the alias.
+     * @return the chain of X509 Certificates.
+     */
+    public X509Certificate[] getCertificateChain(String alias) {
+        if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE,"Getting certificate chain");
+        }
+        X509KeyManager keyMgr = getManagerFromToken(alias);
+        if (keyMgr != null) {
+            String aliasName = alias.substring(alias.indexOf(':') + 1);
+            return keyMgr.getCertificateChain(aliasName);
+        } else {
+            return mgr.getCertificateChain(alias);
+        }
+    }
+
+    /**
+     * Return all the available client aliases for the specified key type.
+     * @param the keytype
+     * @param the certificate issuers.
+     * @return the array of aliases.
+     */
+    public String[] getClientAliases(String keyType, Principal[] issuers) {
+        if(_logger.isLoggable(Level.FINE)){
+	    _logger.log(Level.FINE,"Getting client aliases");
+        }
+	return mgr.getClientAliases(keyType, issuers);
+    }
+
+    /**
+     * Return all the available server aliases for the specified key type.
+     * @param the keytype
+     * @param the certificate issuers.
+     * @return the array of aliases.
+     */
+    public String[] getServerAliases(String keyType, Principal[] issuers) {
+        if(_logger.isLoggable(Level.FINE)){
+            _logger.log(Level.FINE,"Getting server aliases");
+        }
+        return mgr.getServerAliases(keyType, issuers);
+    }
+
+    /**
+     * Return the private key for the specified alias.
+     * @param the alias.
+     * @return the private key.
+     */
+    public PrivateKey getPrivateKey(String alias) {
+        if(_logger.isLoggable(Level.FINE)){
+	    _logger.log(Level.FINE, "Getting private key for alias:{0}", alias);
+	}
+        X509KeyManager keyMgr = getManagerFromToken(alias);
+        if (keyMgr != null) {
+            String aliasName = alias.substring(alias.indexOf(':') + 1);
+            return keyMgr.getPrivateKey(aliasName);
+        } else {
+            return mgr.getPrivateKey(alias);
+        }
+    }    
+
+    
+    /**
+     * Find the corresponding X509KeyManager associated to token in alias.
+     * It returns null if there is n
+     * @param tokenAlias of the form &lt;tokenName&gt;:&lt;aliasName&gt;
+     */
+    private X509KeyManager getManagerFromToken(String tokenAlias) {
+        X509KeyManager keyMgr = null;
+        int ind = -1;
+        if (supportTokenAlias && tokenAlias != null && (ind = tokenAlias.indexOf(':')) != -1) {
+            String tokenName = alias.substring(0, ind);
+            keyMgr = tokenName2MgrMap.get(tokenName);
+        }
+        return keyMgr;
+    }
+    
+    //TODO:V3 copied all method(s)below from LoginContextDriver to break dependencies among modules
+     private static final String CLIENT_JAAS_PASSWORD = "default";
+    /**
+     * Perform login on the client side.
+     * It just simulates the login on the client side.
+     * The method uses the callback handlers and generates correct
+     * credential information that will be later sent to the server
+     * @param int type whether it is <i> username_password</i> or 
+     * <i> certificate </i> based login.
+     * @param CallbackHandler the callback handler to gather user information.
+     * @exception LoginException the exception thrown by the callback handler.
+     */
+    public  static Subject doClientLogin(int type,
+                     javax.security.auth.callback.CallbackHandler jaasHandler)
+        throws LoginException
+    {
+        final javax.security.auth.callback.CallbackHandler handler =
+            jaasHandler;
+        // the subject will actually be filled in with a PasswordCredential
+        // required by the csiv2 layer in the LoginModule.
+        // we create the dummy credential here and call the 
+        // set security context. Thus, we have 2  credentials, one each for
+        // the csiv2 layer and the other for the RI.
+        final Subject subject = new Subject();
+        //V3:Commented : TODO uncomment later for Appcontainer
+        if (type == SecurityConstants.USERNAME_PASSWORD){
+            AppservAccessController.doPrivileged(new PrivilegedAction() {
+                public java.lang.Object run() {
+                    try{
+                        LoginContext lg = 
+                            new LoginContext(SecurityConstants.CLIENT_JAAS_PASSWORD, 
+                                             subject, handler);
+                        lg.login();
+                    }catch(javax.security.auth.login.LoginException e){
+                        throw (LoginException)
+                            new LoginException(e.toString()).initCause(e);
+                    }
+                    
+                    return null;
+                }
+            });
+            postClientAuth(subject, PasswordCredential.class);
+            return subject;
+        } else if (type == SecurityConstants.CERTIFICATE){
+            AppservAccessController.doPrivileged(new PrivilegedAction() {
+                public java.lang.Object run() {
+                    try{
+                        LoginContext lg = 
+                            new LoginContext(SecurityConstants.CLIENT_JAAS_CERTIFICATE,
+                                             subject, handler);
+                        lg.login();
+                    }catch(javax.security.auth.login.LoginException e){
+                        throw (LoginException)
+                            new LoginException(e.toString()).initCause(e);
+                    }
+                    
+                    return null;
+                }
+            });
+            postClientAuth(subject, X509CertificateCredential.class);
+            return subject;
+        } else if (type == SecurityConstants.ALL){
+            AppservAccessController.doPrivileged(new PrivilegedAction() {
+                public java.lang.Object run() {
+                    try{
+                        LoginContext lgup =
+                            new LoginContext(SecurityConstants.CLIENT_JAAS_PASSWORD,
+                                             subject, handler);
+                        LoginContext lgc = 
+                            new LoginContext(SecurityConstants.CLIENT_JAAS_CERTIFICATE,
+                                                 subject, handler);
+                        lgup.login();
+                        postClientAuth(subject, PasswordCredential.class);
+                        
+                        lgc.login();
+                        postClientAuth(subject,
+                                       X509CertificateCredential.class);
+                    }catch(javax.security.auth.login.LoginException e){
+                        throw (LoginException)
+                            new LoginException(e.toString()).initCause(e);
+                    }
+                    
+                    return null;
+                }
+            });
+            return subject;
+        } else{ 
+            AppservAccessController.doPrivileged(new PrivilegedAction() {
+                public java.lang.Object run() {
+                    try{
+                        LoginContext lg =
+                            new LoginContext(SecurityConstants.CLIENT_JAAS_PASSWORD, 
+                                             subject, handler);
+                        lg.login();
+                        postClientAuth(subject, PasswordCredential.class);
+                    }catch(javax.security.auth.login.LoginException e){
+                        throw (LoginException)
+                            new LoginException(e.toString()).initCause(e);
+                    }
+                    return null;
+                }
+            });
+            return subject;
+        }
+    }
+    
+     /**
+     * Extract the relevant username and realm information from the
+     * subject and sets the correct state in the security context. The
+     * relevant information is set into the Thread Local Storage from
+     * which then is extracted to send over the wire.
+     *
+     * @param Subject the subject returned by the JAAS login.
+     * @param Class the class of the credential object stored in the subject
+     *
+     */
+    private  static void postClientAuth(Subject subject, Class<?> clazz){
+        final Class<?> clas = clazz;
+        final Subject fs = subject;
+        Set credset = 
+            (Set) AppservAccessController.doPrivileged(new PrivilegedAction<Set>() {
+                public Set run() {
+                if(_logger.isLoggable(Level.FINEST)){
+                    _logger.log(Level.FINEST, "LCD post login subject :{0}", fs);
+                }
+                    return fs.getPrivateCredentials(clas);
+                }
+            });
+        final Iterator iter = credset.iterator();
+        while(iter.hasNext()) {
+            Object obj = null;    
+            try{
+                obj = AppservAccessController.doPrivileged(new PrivilegedAction(){
+                    public java.lang.Object run(){
+                        return iter.next();
+                    }
+                });
+            } catch (Exception e){
+                // should never come here 
+                _logger.log(Level.SEVERE,
+                            SecurityLoggerInfo.securityAccessControllerActionError,
+                            e);
+            }
+            if(obj instanceof PasswordCredential) {
+                PasswordCredential p = (PasswordCredential) obj;
+                String user = p.getUser();
+                if(_logger.isLoggable(Level.FINEST)){
+                    String realm = p.getRealm();
+                    _logger.log(Level.FINEST, "In LCD user-pass login:{0} realm :{1}",
+                            new Object[]{user, realm});
+                }
+                setClientSecurityContext(user, fs);
+                return;
+            } else if (obj instanceof X509CertificateCredential){
+                X509CertificateCredential p = (X509CertificateCredential) obj;
+                String user = p.getAlias();
+                if(_logger.isLoggable(Level.FINEST)){
+                    String realm = p.getRealm();
+                    _logger.log(Level.FINEST, "In LCD cert-login::{0} realm :{1}",
+                            new Object[]{user, realm});
+                }
+                setClientSecurityContext(user, fs);
+                return;
+            }
+        }
+    }
+
+     /**
+     * Sets the security context on the appclient side.
+     * It sets the relevant information into the TLS
+     * @param String username is the user who authenticated
+     * @param Subject is the subject representation of the user
+     * @param Credentials the credentials that the server associated with it
+     */
+    private static void setClientSecurityContext(String username, 
+                                                 Subject subject) {
+                                                 
+        ClientSecurityContext securityContext =
+            new ClientSecurityContext(username, subject);
+        ClientSecurityContext.setCurrent(securityContext);
+    }
+
+}
+
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/JarSigner.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/JarSigner.java
new file mode 100644
index 0000000..ed0aad8
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/JarSigner.java
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.ssl;
+
+import com.sun.enterprise.server.pluggable.SecuritySupport;
+import com.sun.enterprise.universal.GFBase64Encoder;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
+import java.security.SignatureException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.KeyStore;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import sun.security.pkcs.ContentInfo;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.SignerInfo;
+import sun.security.x509.AlgorithmId;
+import sun.security.x509.X500Name;
+
+/**
+ * A utility class to sign jar files.
+ *
+ * @author Sudarsan Sridhar
+ */
+public class JarSigner {
+
+    private static final GFBase64Encoder b64encoder = new GFBase64Encoder();
+    private final MessageDigest md;
+    private final String digestAlgorithm;
+    private final String keyAlgorithm;
+    private static final SecuritySupport secSupp = SecuritySupport.getDefaultInstance();
+
+    public JarSigner(String digestAlgorithm, String keyAlgorithm)
+            throws NoSuchAlgorithmException {
+        this.digestAlgorithm = digestAlgorithm;
+        this.keyAlgorithm = keyAlgorithm;
+        this.md = MessageDigest.getInstance(digestAlgorithm);
+    }
+
+    public static void main(String[] args) throws Exception {
+        File in = new File(args[0]);
+        File out = new File(args[1]);
+        new JarSigner("SHA1", "RSA").signJar(in, out, "s1as");
+    }
+
+    /**
+     * Hash the string completely.
+     *
+     * @param content String to be hashed.
+     * @return the hash.
+     */
+    private String hash(String content) {
+        return hash(content.getBytes());
+    }
+
+    /**
+     * Hash the data.
+     * 
+     * @param data
+     * @return 
+     */
+    private String hash(final byte[] data) {
+        return b64encoder.encodeBuffer(md.digest(data)).trim();
+    }
+
+    /**
+     * Signs a jar.
+     * 
+     * @param input input jar file
+     * @param output output jar file
+     * @param alias signing alias in the keystore
+     */
+    public void signJar(File input, File output, String alias)
+            throws IOException, KeyStoreException, NoSuchAlgorithmException,
+            InvalidKeyException, UnrecoverableKeyException, SignatureException {
+        
+        signJar(input, output, alias, null);
+    }
+    
+    /**
+     * Signs a JAR, adding caller-specified attributes to the manifest's main attrs.
+     * 
+     * @param input input JAR file
+     * @param output output JAR file
+     * @param alias signing alias in the keystore
+     * @param additionalAttrs additional attributes to add to the manifest's main attrs (null if none)
+     */
+    public void signJar(File input, File output, String alias, final Attributes additionalAttrs) 
+            throws IOException, KeyStoreException, NoSuchAlgorithmException,
+            InvalidKeyException, UnrecoverableKeyException, SignatureException {
+        final ZipOutputStream zout = new ZipOutputStream(
+            new FileOutputStream(output));
+        try {
+            signJar(input, zout, alias, additionalAttrs, Collections.EMPTY_MAP);
+        } finally {
+            zout.close();
+        }
+    }
+    
+    /**
+     * Signs a JAR, adding caller-specified attributes to the manifest's main attrs and also
+     * inserting (and signing) additional caller-supplied content as new entries in the
+     * zip output stream.
+     * @param input input JAR file
+     * @param zout Zip output stream created
+     * @param alias signing alias in the keystore
+     * @param additionalAttrs additional attributes to add to the manifest's main attrs (null if none)
+     * @param additionalEntries entry-name/byte[] pairs of additional content to add to the signed output
+     * @throws IOException
+     * @throws KeyStoreException
+     * @throws NoSuchAlgorithmException
+     * @throws InvalidKeyException
+     * @throws UnrecoverableKeyException
+     * @throws SignatureException 
+     */
+    public void signJar(File input, ZipOutputStream zout, String alias, final Attributes additionalAttrs,
+            Map<String,byte[]> additionalEntries)
+            throws IOException, KeyStoreException, NoSuchAlgorithmException,
+            InvalidKeyException, UnrecoverableKeyException, SignatureException {
+
+        JarFile jf = new JarFile(input);
+        try {
+            Enumeration<JarEntry> jes;
+            // manifestEntries is content of META-INF/MANIFEST.MF
+            StringBuilder manifestEntries = new StringBuilder();
+
+            byte[] manifestContent;
+            byte[] sigFileContent = getExistingSignatureFile(jf);
+            boolean signed = (sigFileContent != null);
+
+            if (!signed || ! additionalEntries.isEmpty()) {
+                jes = jf.entries();// manifestHeader is header of META-INF/MANIFEST.MF, initialized to default
+                Manifest manifest = retrieveManifest(jf);
+                StringBuilder manifestHeader = new StringBuilder();
+                Attributes mfAttrs = manifest.getMainAttributes();
+                if (additionalAttrs != null) {
+                    mfAttrs.putAll(additionalAttrs);
+                }
+                appendAttributes(manifestHeader, mfAttrs);
+                
+                // sigFileEntries is content of META-INF/ME.SF
+                StringBuilder sigFileEntries = new StringBuilder();
+                while (jes.hasMoreElements()) {
+                    JarEntry je = jes.nextElement();
+                    String name = je.getName();
+                    if ((je.isDirectory() && manifest.getAttributes(name) == null)
+                            || name.equals(JarFile.MANIFEST_NAME)) {
+                        continue;
+                    }
+                    processMetadataForEntry(manifest, manifestEntries, sigFileEntries, name, readJarEntry(jf, je));
+                }
+
+                if (additionalEntries != null) {
+                    for (Map.Entry<String,byte[]> entry : additionalEntries.entrySet()) {
+                        processMetadataForEntry(manifest, manifestEntries, sigFileEntries, entry.getKey(), entry.getValue());
+                    }
+                }
+                
+                // META-INF/ME.SF
+                StringBuilder sigFile = new StringBuilder("Signature-Version: 1.0\r\n").append(digestAlgorithm).append("-Digest-Manifest-Main-Attributes: ").append(hash(manifestHeader.toString())).append("\r\n").append("Created-By: ").append(System.getProperty("java.version")).append(" (").append(System.getProperty("java.vendor")).append(")\r\n");
+                // Combine header and content of MANIFEST.MF, and rehash
+                manifestHeader.append(manifestEntries);
+                sigFile.append(digestAlgorithm).append("-Digest-Manifest: ").append(hash(manifestHeader.toString())).append("\r\n\r\n");
+
+                // Combine header and content of ME.SF
+                sigFile.append(sigFileEntries);
+                manifestContent = manifestHeader.toString().getBytes();
+                sigFileContent = sigFile.toString().getBytes();
+            } else {
+                manifestContent = readJarEntry(jf,
+                        jf.getJarEntry(JarFile.MANIFEST_NAME));
+            }
+            X509Certificate[] certChain = null;
+            PrivateKey privKey = null;
+            KeyStore[] ks = secSupp.getKeyStores();
+            for (int i = 0; i < ks.length; i++) {
+                privKey = secSupp.getPrivateKeyForAlias(alias, i);
+                if (privKey != null) {
+                    Certificate[] cs = ks[i].getCertificateChain(alias);
+                    certChain = new X509Certificate[cs.length];
+                    for (int j = 0; j < cs.length; j++) {
+                        certChain[j] = (X509Certificate) cs[j];
+                    }
+                }
+            }
+
+            // Sign ME.SF
+            Signature sig = Signature.getInstance(digestAlgorithm + "with" + keyAlgorithm);
+            sig.initSign(privKey);
+            sig.update(sigFileContent);
+
+            // Create PKCS7 block
+            PKCS7 pkcs7 = new PKCS7(
+                    new AlgorithmId[]{AlgorithmId.get(digestAlgorithm)},
+                    new ContentInfo(sigFileContent),
+                    certChain,
+                    new SignerInfo[]{new SignerInfo(
+                        (X500Name) certChain[0].getIssuerDN(),
+                        certChain[0].getSerialNumber(),
+                        AlgorithmId.get(digestAlgorithm),
+                        AlgorithmId.get(keyAlgorithm),
+                        sig.sign())
+                    });
+            ByteArrayOutputStream bout = new ByteArrayOutputStream();
+            pkcs7.encodeSignedData(bout);
+
+            // Write output
+            
+            zout.putNextEntry((signed)
+                    ? getZipEntry(jf.getJarEntry(JarFile.MANIFEST_NAME))
+                    : new ZipEntry(JarFile.MANIFEST_NAME));
+            zout.write(manifestContent);
+
+            zout.putNextEntry(new ZipEntry("META-INF/"
+                    + alias.toUpperCase(Locale.US) + ".SF"));
+            zout.write(sigFileContent);
+
+            zout.putNextEntry(new ZipEntry("META-INF/"
+                    + alias.toUpperCase(Locale.US) + "." + keyAlgorithm));
+            zout.write(bout.toByteArray());
+
+            jes = jf.entries();
+            while (jes.hasMoreElements()) {
+                JarEntry je = jes.nextElement();
+                String name = je.getName();
+                if (!name.equals(JarFile.MANIFEST_NAME)) {
+                    zout.putNextEntry(getZipEntry(je));
+                    byte[] data = readJarEntry(jf, je);
+                    zout.write(data);
+                }
+            }
+            if (additionalEntries != null) {
+                for (Map.Entry<String, byte[]> entry : additionalEntries.entrySet()) {
+                    final ZipEntry newZipEntry = new ZipEntry(entry.getKey());
+                    zout.putNextEntry(newZipEntry);
+                    zout.write(entry.getValue());
+                }
+            }
+
+        } finally {
+            jf.close();
+        }
+    }
+
+    private void processMetadataForEntry(final Manifest manifest, 
+            final StringBuilder manifestEntries,
+            final StringBuilder sigFileEntries,
+            final String name, 
+            final byte[] content) {
+        StringBuilder me = new StringBuilder();
+        StringBuilder currentLine = new StringBuilder();
+        // Create digest lines in MANIFEST.MF
+        currentLine.append("Name: ").append(name);
+        appendLine(me, currentLine);
+        currentLine.setLength(0);
+        me.append(digestAlgorithm).append("-Digest: ").append(hash(content)).append("\r\n");
+        appendAttributes(me, manifest, name);
+        // Create digest lines in ME.SF
+        currentLine.append("Name: ").append(name);
+        appendLine(sigFileEntries, currentLine);
+        currentLine.setLength(0);
+        sigFileEntries.append(digestAlgorithm).append("-Digest: ").append(hash(me.toString())).append("\r\n\r\n");
+        manifestEntries.append(me);
+    }
+    
+    /**
+     * Retrieve manifest from jar, create a default template if none exists.
+     *
+     * @param jf The jar file
+     * @return The Manifest
+     * @throws IOException
+     */
+    private Manifest retrieveManifest(JarFile jf) throws IOException {
+        Manifest manifest = jf.getManifest();
+        if (manifest == null) {
+            manifest = new Manifest();
+            Attributes mainAttributes = manifest.getMainAttributes();
+            mainAttributes.putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1.0");
+            mainAttributes.putValue("Created-By", System.getProperty("java.version")
+                    + " (" + System.getProperty("java.vendor") + ")");
+        }
+        Map<String, Attributes> entriesMap = manifest.getEntries();
+        for (Iterator<String> entries = entriesMap.keySet().iterator(); entries.hasNext();) {
+            if (jf.getJarEntry(entries.next()) == null) {
+                entries.remove();
+            }
+        }
+        return manifest;
+    }
+
+    /**
+     * Add attributes for the current entry.
+     *
+     * @param manifestEntry - The StringBuilder to which the attributes are to be added.
+     * @param manifest - The Jar Manifest Entry
+     * @param entry - The named entry in the manifest. null means the Main Attribute section.
+     * @return manifestEntry with attributes added.
+     */
+    private static StringBuilder appendAttributes(StringBuilder manifestEntry,
+            Manifest manifest, String entry) {
+        return appendAttributes(manifestEntry, (entry == null)
+                ? manifest.getMainAttributes() : manifest.getAttributes(entry));
+    }
+    
+    private static StringBuilder appendAttributes(StringBuilder manifestEntry,
+            Attributes attributes) {
+        StringBuilder line = new StringBuilder();
+        if (attributes != null) {
+            for (Map.Entry attr : attributes.entrySet()) {
+                line.append(attr.getKey().toString()).append(": ").append((String) attr.getValue());
+                appendLine(manifestEntry, line);
+                line.setLength(0);
+            }
+        }
+        return manifestEntry.append("\r\n");
+    }
+
+    /**
+     * Process a long manifest line and add continuation if required
+     *
+     * @param sb - The output string
+     * @param line - The line to be processed.
+     * @return sb with the line added.
+     */
+    private static StringBuilder appendLine(StringBuilder sb, StringBuilder line) {
+        int begin = 0;
+        for (int end = 70; line.length() - begin > 70; end += 69) {
+            sb.append(line.subSequence(begin, end)).append("\r\n ");
+            begin = end;
+        }
+        return sb.append(line.subSequence(begin, line.length())).append("\r\n");
+    }
+
+    /**
+     * If jar is signed, return existing Signature file, else return null.
+     *
+     * @param jf The jar file
+     * @return Signature file
+     * @throws IOException
+     */
+    private static byte[] getExistingSignatureFile(JarFile jf) throws IOException {
+        Enumeration<JarEntry> entries = jf.entries();
+        JarEntry je = null;
+        while (entries.hasMoreElements()) {
+            JarEntry cje = entries.nextElement();
+            if (cje.getName().startsWith("META-INF/") && cje.getName().endsWith(".SF")) {
+                je = cje;
+                break;
+            }
+        }
+        return readJarEntry(jf, je);
+    }
+
+    /**
+     * Read completely the bytes from Entry je of jarfile jf.
+     * 
+     * @param jf the jar file
+     * @param je the jar entry
+     * @return bytes from je.
+     * @throws IOException
+     */
+    private static byte[] readJarEntry(JarFile jf, JarEntry je) throws IOException {
+        if (je == null) {
+            return null;
+        }
+        byte[] data = new byte[(int) je.getSize()];
+        InputStream jis = jf.getInputStream(je);
+        int current;
+        int idx = 0;
+        while ((current = jis.read()) > -1) {
+            data[idx++] = (byte) current;
+        }
+        return data;
+    }
+
+    /**
+     * Get the ZipEntry for the given JarEntry. Added in order to suppress the
+     * compressedSize field as it was causing errors
+     *
+     * @param je The jar entry.
+     * @return ZipEntry with fields populated from the JarEntry.
+     */
+    private static ZipEntry getZipEntry(JarEntry je) {
+        ZipEntry ze = new ZipEntry(je.getName());
+
+        ze.setComment(je.getComment());
+        ze.setCrc(je.getCrc());
+        ze.setExtra(je.getExtra());
+        ze.setMethod(je.getMethod());
+        ze.setSize(je.getSize());
+        ze.setTime(je.getTime());
+
+        return ze;
+    }
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/SSLUtils.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/SSLUtils.java
new file mode 100644
index 0000000..c3c71d8
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/ssl/SSLUtils.java
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.ssl;
+
+import com.sun.enterprise.security.SecurityLoggerInfo;
+import com.sun.enterprise.security.common.Util;
+import java.io.IOException;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.security.cert.Certificate;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509KeyManager;
+
+
+//V3:Commented import com.sun.enterprise.config.clientbeans.Ssl
+import com.sun.enterprise.server.pluggable.SecuritySupport;
+//V3:Commented import com.sun.web.security.SSLSocketFactory;
+import com.sun.enterprise.security.integration.AppClientSSL;
+import java.util.logging.*;
+import com.sun.logging.*;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Permission;
+import java.util.PropertyPermission;
+import javax.net.ssl.SSLSocketFactory;
+import org.jvnet.hk2.annotations.Service;
+import javax.inject.Inject;
+import org.glassfish.hk2.api.PostConstruct;
+
+import javax.inject.Singleton;
+
+/**
+ *  Handy class containing static functions.
+ * @author Harpreet Singh
+ * @author Vivek Nagar
+ * @author Shing Wai Chan
+ */
+@Service
+@Singleton
+public final class SSLUtils implements PostConstruct {
+    private static final String DEFAULT_OUTBOUND_KEY_ALIAS = "s1as";
+    public static final String HTTPS_OUTBOUND_KEY_ALIAS = "com.sun.enterprise.security.httpsOutboundKeyAlias";
+    private static final String DEFAULT_SSL_PROTOCOL = "TLS";
+
+    private static final Logger _logger = SecurityLoggerInfo.getLogger();
+
+    @Inject
+    private SecuritySupport secSupp;
+
+    private boolean hasKey = false;
+    private KeyStore mergedTrustStore = null;
+    private AppClientSSL appclientSsl = null;
+    private SSLContext ctx = null;
+    
+    public void postConstruct() {
+        try {
+            //TODO: To check the right implementation once we support EE.
+            if(secSupp == null){
+                secSupp = SecuritySupport.getDefaultInstance();
+            }
+            KeyStore[] keyStores = getKeyStores();
+            if (keyStores != null) {
+                for (KeyStore keyStore : keyStores) {
+                    Enumeration aliases = keyStore.aliases();
+                    while (aliases.hasMoreElements()) {
+                        String alias = (String) aliases.nextElement();
+                        if (keyStore.isKeyEntry(alias)) {
+                            hasKey = true;
+                            break;
+                        }
+                    }
+                    if (hasKey) {
+                        break;
+                    }
+                }
+            }
+            mergedTrustStore = mergingTrustStores(secSupp.getTrustStores());
+            getSSLContext(null, null, null);
+        } catch(Exception ex) {
+            if (_logger.isLoggable(Level.FINE)) {
+                _logger.log(Level.FINE, "SSLUtils static init fails.", ex);
+            }
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    SSLContext getSSLContext(String protocol, String algorithm, String trustAlgorithm) {
+        try {
+            //V3:Commented to break dependency on WebTier.
+            //The SSLSocketFactory CTOR will now take care of setting the kmgr and tmgr
+            //SSLSocketFactory.setManagers(getKeyManagers(), getTrustManagers());
+
+            // Creating a default SSLContext and HttpsURLConnection for clients
+            // that use Https
+            if (protocol == null) {
+                protocol = DEFAULT_SSL_PROTOCOL;
+            }
+            ctx = SSLContext.getInstance(protocol);
+            String keyAlias = System.getProperty(HTTPS_OUTBOUND_KEY_ALIAS);
+            KeyManager[] kMgrs = getKeyManagers(algorithm);
+            if (keyAlias != null && keyAlias.length() > 0 && kMgrs != null) {
+                for (int i = 0; i < kMgrs.length; i++) {
+                    kMgrs[i] = new J2EEKeyManager((X509KeyManager)kMgrs[i], keyAlias);
+                }
+            }
+            ctx.init(kMgrs, getTrustManagers(trustAlgorithm), null);
+
+            HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
+            //refer issue :http://java.net/jira/browse/GLASSFISH-15369
+            SSLContext.setDefault(ctx);
+        } catch (Exception e) {
+            throw new Error(e);
+        }
+        return ctx;
+    }
+
+    public boolean verifyMasterPassword(final char[] masterPass) {
+        return secSupp.verifyMasterPassword(masterPass);
+    }
+
+    public KeyStore[] getKeyStores() throws IOException{
+        return secSupp.getKeyStores();
+    }
+
+    public KeyStore getKeyStore() throws IOException{
+        return getKeyStores()[0];
+    }
+
+    public KeyStore[] getTrustStores() throws IOException{
+        return secSupp.getTrustStores();
+    }
+
+    public KeyStore getTrustStore() throws IOException{
+        return getTrustStores()[0];
+    }
+
+    /**
+     * This API is for temporary purpose.  It will be removed once JSR 196
+     * is updated.
+     */
+    public KeyStore getMergedTrustStore() {
+        return mergedTrustStore;
+    }
+
+    public KeyManager[] getKeyManagers() throws Exception{
+        return getKeyManagers(null);
+    }
+    public KeyManager[] getKeyManagers(String algorithm) throws IOException,
+            KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException{
+        return secSupp.getKeyManagers(algorithm);
+    } 
+    public TrustManager[] getTrustManagers() throws Exception{
+        return getTrustManagers(null);
+    }
+    public TrustManager[] getTrustManagers(String algorithm) throws IOException,
+            KeyStoreException, NoSuchAlgorithmException{
+        return secSupp.getTrustManagers(algorithm);
+    }
+
+    
+    public void setAppclientSsl(AppClientSSL ssl){
+        appclientSsl = ssl;
+    }
+
+    public  AppClientSSL getAppclientSsl() {
+        return appclientSsl;
+    }
+
+    public static String getKeyStoreType() {
+        return System.getProperty(SecuritySupport.KEYSTORE_TYPE_PROP, KeyStore.getDefaultType());
+    }
+
+    public static String getTrustStoreType() {
+        return System.getProperty(SecuritySupport.TRUSTSTORE_TYPE_PROP, KeyStore.getDefaultType());
+    }
+
+    /**
+     * This method checks whether a private key is available or not.
+     */
+    public boolean isKeyAvailable() {
+        return hasKey;
+    }
+
+    /**
+     * Check whether given String is of the form [&lt;TokenName&gt;:]alias
+     * where alias is an key entry.
+     * @param certNickname
+     * @return boolean
+     */ 
+    public boolean isTokenKeyAlias(String certNickname) throws Exception {
+        boolean isTokenKeyAlias = false;
+        if (certNickname != null) {
+            int ind = certNickname.indexOf(':');
+            KeyStore[] kstores = getKeyStores();
+            int count = -1;
+            String aliasName = null;
+            if (ind != -1) {
+                String[] tokens = secSupp.getTokenNames();
+                String tokenName = certNickname.substring(0, ind);
+                aliasName = certNickname.substring(ind + 1);
+                for (int i = 0; i < tokens.length; i++) {
+                    if (tokenName.equals(tokens[i])) {
+                        count = i;
+                    }
+                }
+            }
+
+            if (count != -1) {
+                isTokenKeyAlias = kstores[count].isKeyEntry(aliasName);
+            } else {
+                for (KeyStore kstore : kstores) {
+                    if (kstore.isKeyEntry(certNickname)) {
+                        isTokenKeyAlias = true;
+                        break;
+                    }
+                }
+            }
+        }
+        return isTokenKeyAlias;
+    }
+
+    /**
+     * Get a PrivateKeyEntry with certNickName is of the form
+     * [&lt;TokenName&gt;:]alias where alias is an key entry.
+     * @param certNickname
+     * @return PrivateKeyEntry
+     */ 
+    public PrivateKeyEntry getPrivateKeyEntryFromTokenAlias(
+            String certNickname) throws Exception {
+        checkPermission(SecuritySupport.KEYSTORE_PASS_PROP);
+        PrivateKeyEntry privKeyEntry = null;
+        if (certNickname != null) {
+            int ind = certNickname.indexOf(':');
+            KeyStore[] kstores = getKeyStores();
+            int count = -1;
+            String aliasName = certNickname;
+            if (ind != -1) {
+                String[] tokens = secSupp.getTokenNames();
+                String tokenName = certNickname.substring(0, ind);
+                aliasName = certNickname.substring(ind + 1);
+                for (int i = 0; i < tokens.length; i++) {
+                    if (tokenName.equals(tokens[i])) {
+                        count = i;
+                    }
+                }
+            }
+
+            if (count != -1 && kstores.length >= count) {
+                PrivateKey privKey = secSupp.getPrivateKeyForAlias(aliasName, count);
+                if (privKey != null) {
+                    Certificate[] certs = kstores[count].getCertificateChain(
+                            aliasName);
+                    privKeyEntry = new PrivateKeyEntry(privKey, certs);
+                }
+            } else {
+                for (int i = 0; i < kstores.length; i++) {
+                    PrivateKey privKey = secSupp.getPrivateKeyForAlias(aliasName, i);
+                    if (privKey != null) {
+                       Certificate[] certs =
+                                kstores[i].getCertificateChain(
+                                aliasName);
+                        privKeyEntry = new PrivateKeyEntry(privKey, certs);
+                        break;
+                    }
+                }
+            }
+        }
+
+        return privKeyEntry;
+    }
+
+    public static void checkPermission(String key) {
+        try {
+            // Checking a random permission to check if it is server.
+            if(Util.isEmbeddedServer() || Util.getDefaultHabitat() == null
+                    || Util.getInstance().isACC() || Util.getInstance().isNotServerOrACC()){
+                return;
+            }
+            Permission perm = new RuntimePermission("SSLPassword");
+            AccessController.checkPermission(perm);
+        } catch (AccessControlException e) {
+            String message = e.getMessage();
+            Permission perm = new PropertyPermission(key, "read");
+            if (message != null) {
+                message = message.replace(e.getPermission().toString(), perm.toString());
+            }
+            throw new AccessControlException(message, perm);
+        }
+    }
+    
+    public String[] getSupportedCipherSuites() {
+         //postConstruct is already setting this.
+         return  HttpsURLConnection.getDefaultSSLSocketFactory().getSupportedCipherSuites();
+    }
+    
+    private KeyStore mergingTrustStores(KeyStore[] trustStores)
+            throws IOException, KeyStoreException,
+            NoSuchAlgorithmException, CertificateException {
+        KeyStore mergedStore;
+        try {
+            mergedStore = secSupp.loadNullStore("CaseExactJKS", secSupp.getKeyStores().length - 1);
+        } catch(KeyStoreException ex) {
+            mergedStore = secSupp.loadNullStore("JKS", secSupp.getKeyStores().length - 1);
+        }
+
+        String[] tokens = secSupp.getTokenNames();
+        for (int i = 0; i < trustStores.length; i++) {
+            Enumeration aliases = trustStores[i].aliases();
+            while (aliases.hasMoreElements()) {
+                String alias = (String)aliases.nextElement();
+                Certificate cert = trustStores[i].getCertificate(alias);
+
+                //need to preserve the token:alias name format
+                String alias2 = (i < tokens.length - 1)? tokens[i] + ":" + alias : alias;
+
+                String alias3 = alias2;
+                boolean alreadyInStore = false;
+                Certificate aCert;
+                int count = 1;
+                while ((aCert = mergedStore.getCertificate(alias3)) != null) {
+                    if (aCert.equals(cert)) {
+                        alreadyInStore = true;
+                        break;
+                    }
+                    alias3 = alias2 + "__" + count++;
+                }
+                if (!alreadyInStore) {
+                    mergedStore.setCertificateEntry(alias3, cert);
+                }
+            }
+        }
+        return mergedStore;
+     }
+
+    /**
+     * 
+     *
+     * @param alias  the admin key alias
+     * @param protocol the protocol or null, uses "TLS" if this argument is null.
+     * @return the SSLSocketFactory from the initialized SSLContext
+     */
+    public SSLSocketFactory getAdminSocketFactory(String alias, String protocol) {
+        return getAdminSSLContext(alias, protocol).getSocketFactory();
+    }
+
+    /*
+    * @param alias  the admin key alias
+    * @param protocol the protocol or null, uses "TLS" if this argument is null.
+    * @return the initialized SSLContext
+    */
+    public SSLContext getAdminSSLContext(String alias, String protocol) {
+        try {
+            if (protocol == null) {
+                protocol = "TLS";
+            }
+            SSLContext cntxt = SSLContext.getInstance(protocol);
+            KeyManager[] kMgrs = getKeyManagers();
+            if (alias != null && alias.length() > 0 && kMgrs != null) {
+                for (int i = 0; i < kMgrs.length; i++) {
+                    kMgrs[i] = new J2EEKeyManager((X509KeyManager)kMgrs[i], alias);
+                }
+            }
+            cntxt.init(kMgrs, getTrustManagers(), null);
+
+            return cntxt;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/util/IASSecurityException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/util/IASSecurityException.java
new file mode 100644
index 0000000..6e16b92
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/util/IASSecurityException.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.util;
+
+import java.lang.*;
+
+/**
+ * General exception class for iAS security failures.
+ *
+ * <P>This class takes advantage of the JDK1.4 Throwable objects which
+ * can carry the original cause of the exception. This prevents losing
+ * the information on what caused the problem to arise.
+ *
+ * <P>Ideally there should be common top level iAS Exceptions to extend.
+ *
+ */
+
+public class IASSecurityException extends Exception
+{
+  private boolean noMsg;
+  
+  /**
+   * Constructor.
+   *
+   * @param msg The detail message.
+   *
+   */
+  public IASSecurityException(String msg)
+  {
+    super(msg);
+    noMsg=false;
+  }
+
+
+  /**
+   * Constructor.
+   *
+   * @param msg The detail message.
+   * @param cause The cause (which is saved for later retrieval by the
+   *    getCause() method).
+   *
+   */
+  public IASSecurityException(String msg, Throwable cause)
+  {
+    super(msg, cause);
+    noMsg=false;
+  }
+
+
+  /**
+   * Constructor.
+   *
+   * @param cause The cause (which is saved for later retrieval by the
+   *    getCause() method).
+   *
+   */
+  public IASSecurityException(Throwable cause)
+  {
+    super(cause);
+    noMsg=true;
+  }
+
+
+  /**
+   * Returns a description of this exception. If a root cause was included
+   * during construction, its message is also included.
+   *
+   * @return Message containing information about the exception.
+   *
+   */
+  public String getMessage()
+  {
+    StringBuffer sb=new StringBuffer();
+    sb.append(super.getMessage());
+    Throwable cause=getCause();
+
+    if (!noMsg && cause!=null) {
+      sb.append(" [Cause: ");
+      sb.append(cause.toString());
+      sb.append("] ");
+    }
+
+    return sb.toString();
+  }
+
+
+
+
+}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/util/LocalStrings.properties b/nucleus/security/core/src/main/java/com/sun/enterprise/security/util/LocalStrings.properties
new file mode 100644
index 0000000..edf6d9c
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/util/LocalStrings.properties
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+
+#The below two are not used
+#password.badalgorithm=Unknown algorithm {0}.
+#password.badformat=Invalid format: {0}
+ssha.badformat=Invalid format: {0}
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/web/.gitkeep_empty_dir b/nucleus/security/core/src/main/java/com/sun/enterprise/security/web/.gitkeep_empty_dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/web/.gitkeep_empty_dir
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/admin/cli/disable-secure-admin.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/admin/cli/disable-secure-admin.1
new file mode 100644
index 0000000..c4b0ffe
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/admin/cli/disable-secure-admin.1
@@ -0,0 +1,53 @@
+disable-secure-admin(1)   asadmin Utility Subcommands  disable-secure-admin(1)
+
+NAME
+       disable-secure-admin - disables secure admin if it is already enabled.
+
+SYNOPSIS
+           disable-secure-admin [--help]
+
+DESCRIPTION
+       The disable-secure-admin subcommand disables secure admin if it is
+       already enabled.
+
+           Note
+           +----------------------------------------+
+           |           You must restart any running |
+           |           servers in the domain after  |
+           |           you enable or disable secure |
+           |           admin. It is simpler to      |
+           |           enable or disable secure     |
+           |           admin with only the DAS      |
+           |           running, then restart the    |
+           |           DAS, and then start any      |
+           |           other instances.             |
+           +----------------------------------------+
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+EXAMPLES
+       Example 1, Disabling secure admin for a domain
+           The following example shows how to disable secure admin for a
+           domain.
+
+               asadmin> disable-secure-admin
+               server-config
+               default-config
+
+               Command disable-secure-admin executed successfully.
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       enable-secure-admin(1)
+
+       asadmin(1M)
+
+Java EE 8                         25 Jun 2011          disable-secure-admin(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/admin/cli/enable-secure-admin.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/admin/cli/enable-secure-admin.1
new file mode 100644
index 0000000..66c6349
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/admin/cli/enable-secure-admin.1
@@ -0,0 +1,89 @@
+enable-secure-admin(1)    asadmin Utility Subcommands   enable-secure-admin(1)
+
+NAME
+       enable-secure-admin - enables secure admin (if it is not already
+       enabled), optionally changing the alias used for DAS-to-instance admin
+       messages or the alias used for instance-to-DAS admin messages.
+
+SYNOPSIS
+           enable-secure-admin [--help]
+           [--adminalias=alias]
+           [--instancealias=alias]
+
+DESCRIPTION
+       The enable-secure-admin subcommand causes the DAS and the instances in
+       the domain to use SSL certificates for encrypting the messages they
+       send to each other. This subcommand also allows the DAS to accept
+       administration messages from remote admin clients such as the asadmin
+       utility and IDEs.
+
+           Note
+           +----------------------------------------+
+           |           You must restart any running |
+           |           servers in the domain after  |
+           |           you enable or disable secure |
+           |           admin. It is simpler to      |
+           |           enable or disable secure     |
+           |           admin with only the DAS      |
+           |           running, then restart the    |
+           |           DAS, and then start any      |
+           |           other instances.             |
+           +----------------------------------------+
+
+       By default, when secure admin is enabled the DAS and the instances use
+       these SSL certificates to authenticate to each other as security
+       "principals" and to authorize admin access. The --asadminalias value
+       indicates to the DAS which SSL certificate it should use to identify
+       itself to the instances. The --instancealias value determines for
+       instances which SSL certificate they should use to identify themselves
+       to the DAS.
+
+       The enable-secure-admin subcommand fails if any administrative user in
+       the domain has a blank password.
+
+       Alternatively, you can use the enable-secure-admin-internal-user
+       subcommand to cause the servers to identify themselves using a secure
+       admin user name and password.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --adminalias
+           The alias that refers to the SSL/TLS certificate on the DAS. This
+           alias is used by the DAS to identify itself to instances. The
+           default value is s1as.
+
+       --instancealias
+           The alias that refers to the SSL/TLS certificate on the instances.
+           This alias is used by the instances to identify themselves to the
+           DAS. The default value is glassfish-instance.
+
+EXAMPLES
+       Example 1, Enabling secure admin for a domain
+           The following example shows how to enable secure admin for a domain
+           using an admin alias adtest and an instance alias intest
+
+               asadmin> enable-secure-admin --adminalias adtest --instancealias intest
+               server-config
+               default-config
+
+               Command enable-secure-admin executed successfully.
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       disable-secure-admin(1)
+
+       enable-secure-admin-principal(1)
+
+       enable-secure-admin-internal-user(1)
+
+       asadmin(1M)
+
+Java EE 8                         25 Jun 2011           enable-secure-admin(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/configure-ldap-for-admin.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/configure-ldap-for-admin.1
new file mode 100644
index 0000000..ca3f4ca
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/configure-ldap-for-admin.1
@@ -0,0 +1,44 @@
+configure-ldap-for-admin(1)  asadmin Utility Subcommands  configure-ldap-for-admin(1)
+
+NAME
+       configure-ldap-for-admin - configures the authentication realm named
+       admin-realm for the given LDAP
+
+SYNOPSIS
+           configure-ldap-for-admin [--help]
+
+DESCRIPTION
+       The configure-ldap-for-admin subcommand configures the authentication
+       realm named admin-realm for the given LDAP. The
+       configure-ldap-for-admin subcommand is interactive. The subcommand
+       prompts the user for the basedn and ldap-group options.
+
+       This command is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+EXAMPLES
+       Example 1, Configuring the LDAP Authentication Realm
+
+               asadmin> configure-ldap-for-admin
+               Enter the value for the basedn option>
+               Enter the value for the ldap-group option>
+               The LDAP Auth Realm admin-realm was configured correctly
+               in admin server's configuration.
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       change-admin-password(1), create-auth-realm(1)create-auth-realm(1),
+       list-auth-realms(1)
+
+       asadmin(1M)
+
+Java EE 8                  09 Aug 2017           configure-ldap-for-admin(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-audit-module.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-audit-module.1
new file mode 100644
index 0000000..c22a4b9
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-audit-module.1
@@ -0,0 +1,86 @@
+create-audit-module(1)    asadmin Utility Subcommands   create-audit-module(1)
+
+NAME
+       create-audit-module - adds an audit module
+
+SYNOPSIS
+           create-audit-module [--help]
+           --classname classname
+           [--property(name=value)[:name=value]*]
+           [--target target]
+           audit_module_name
+
+DESCRIPTION
+       The create-audit-module subcommand adds the named audit module for the
+       Java class that implements the audit capabilities. Audit modules
+       collect and store information on incoming requests (from, for example,
+       servlets and EJB components) and outgoing responses.
+
+       This subcommand is supported in remote mode only.
+
+OPTIONS
+       --classname
+           The name of the Java class that implements this audit module. If
+           not specified, this option defaults to
+           com.sun.enterprise.security.Audit.
+
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --property
+           Optional keyword-value pairs that specify additional properties for
+           the audit module.
+
+           Audit module properties that are defined by GlassFish Server are as
+           follows:
+
+           auditOn
+               If true, specifies that the audit module is loaded and called
+               by the GlassFish Server audit library at audit points.
+
+           Other available properties are determined by the implementation of
+           the audit module.
+
+       --target
+           Specifies the target on which you are creating the audit module.
+           Valid values are as follows:
+
+           server
+               Creates the audit module for the default server instance server
+               and is the default value.
+
+           configuration_name
+               Creates the audit module for the named configuration.
+
+           cluster_name
+               Creates the audit module for every server instance in the
+               cluster.
+
+           instance_name
+               Creates the audit module for a particular server instance.
+
+OPERANDS
+       audit_module_name
+           The name of this audit module.
+
+EXAMPLES
+       Example 1, Creating an audit module
+
+               asadmin> create-audit-module
+               --classname com.sun.appserv.auditmodule
+               --property defaultuser=admin:Password=admin sampleAuditModule
+               Command create-audit-module executed successfully
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       delete-audit-module(1), list-audit-modules(1)
+
+       asadmin(1M)
+
+Java EE 8                         22 Dec 2010           create-audit-module(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-auth-realm.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-auth-realm.1
new file mode 100644
index 0000000..ecda1da
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-auth-realm.1
@@ -0,0 +1,266 @@
+create-auth-realm(1)      asadmin Utility Subcommands     create-auth-realm(1)
+
+NAME
+       create-auth-realm - adds the named authentication realm
+
+SYNOPSIS
+           create-auth-realm --classname realm_class [--help] [--property(name=value)[:name=value]*]
+           [--target target_name] auth_realm_name
+
+DESCRIPTION
+       The create-auth-realm subcommand adds the named authentication realm.
+
+       This subcommand is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --target
+           Specifies the target on which you are creating the realm. Valid
+           values are
+
+           server
+               Creates the realm on the default server instance. This is the
+               default value.
+
+           configuration_name
+               Creates the realm in the specified configuration.
+
+           cluster_name
+               Creates the realm on all server instances in the specified
+               cluster.
+
+           instance_name
+               Creates the realm on a specified server instance.
+
+       --classname
+           Java class which implements this realm. These include
+           com.sun.enterprise.security.auth.realm.file.FileRealm,
+           com.sun.enterprise.security.auth.realm.certificate.CertificateRealm,
+           com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm,
+           com.sun.enterprise.security.auth.realm.ldap.LDAPRealm,
+           com.sun.enterprise.security.auth.realm.ldap.PamRealm, and
+           com.sun.enterprise.security.auth.realm.solaris.SolarisRealm, or a
+           custom realm.
+
+       --property
+           Optional attribute name-value pairs for configuring the
+           authentication realm. Authentication realms require
+           provider-specific properties, which vary based on implementation.
+
+           The following properties are common to all of the supported realms,
+           which include FileRealm, CertificateRealm, JDBCRealm, LDAPRealm,
+           PamRealm, and SolarisRealm.
+
+           jaas-context
+               Specifies the Java Authentication and Authorization Service
+               (JAAS) context.
+
+           assign-groups
+               (Optional) If this property is set, its value is taken to be a
+               comma-separated list of group names. All clients who present
+               valid certificates are assigned membership to these groups for
+               the purposes of authorization decisions in the web and EJB
+               containers.
+
+           Specific to each realm, you can specify the following properties.
+
+           *   You can specify the following properties for FileRealm:
+
+               file
+                   Specifies the file that stores user names, passwords, and
+                   group names. The default is domain-dir/config/keyfile.
+
+           *   You can specify the following properties for CertificateRealm:
+
+               LoginModule
+                   Specifies the name of a JAAS LoginModule to use for
+                   performing authentication. To use a JAAS LoginModule, you
+                   must first create an implementation of the
+                   javax.security.auth.spi.LoginModule interface, and then
+                   plug the module into a jaas-context. For more information,
+                   see "Custom Authentication of Client Certificate in SSL
+                   Mutual Authentication" in Oracle GlassFish Server Security
+                   Guide.
+
+           *   You can specify the following properties for JDBCRealm:
+
+               datasource-jndi
+                   Specifies the jndi-name of the jdbc-resource for the
+                   database.
+
+               user-table
+                   Specifies the name of the user table in the database.
+
+               user-name-column
+                   Specifies the name of the user name column in the
+                   database's user table.
+
+               password-column
+                   Specifies the name of the password column in the database's
+                   user table.
+
+               group-table
+                   Specifies the name of the group table in the database.
+
+               group-table
+                   Specify the group table for an authentication realm of
+                   class JDBCRealm.
+
+               group-name-column
+                   Specifies the name of the group name column in the
+                   database's group table.
+
+               db-user
+                   (Optional) Allows you to specify the database user name in
+                   the realm instead of the jdbc-connection-pool. This
+                   prevents other applications from looking up the database,
+                   getting a connection, and browsing the user table. By
+                   default, the jdbc-connection-pool configuration is used.
+
+               db-password
+                   (Optional) Allows you to specify the database password in
+                   the realm instead of the jdbc-connection-pool. This
+                   prevents other applications from looking up the database,
+                   getting a connection, and browsing the user table. By
+                   default, the jdbc-connection-pool configuration is used.
+
+               group-table
+                   Specifies the name of the group table in the database.
+
+               digest-algorithm
+                   (Optional) Specifies the digest algorithm. The default is
+                   SHA-256. You can use any algorithm supported in the JDK, or
+                   none.
+
+                       Note
+                       +------------------------------------------------------------------------------------------------------+
+                       |In versions of GlassFish Server prior                                                                 |
+                       |to 4.0, the default algorithm was MD5.                                                                |
+                       |If you have applications that depend on                                                               |
+                       |the MD5 algorithm, you can override the                                                               |
+                       |default SHA-25 algorithm by using the                                                                 |
+                       |asadmin set subcommand:                                                                               |
+                       |                           asadmin> set server.security-service.property.default-digest-algorithm=MD5 |
+                       |                                                                                                      |
+                       |                       You can use the                                                                |
+                       |                       asadmin get                                                                    |
+                       |                       subcommand to                                                                  |
+                       |                       determine what                                                                 |
+                       |                       algorithm is                                                                   |
+                       |                       currently being                                                                |
+                       |                       used:                                                                          |
+                       |                           asadmin> get server.security-service.property.default-digest-algorithm     |
+                       |                                                                                                      |
+                       |                       Also note that,                                                                |
+                       |                       to maintain                                                                    |
+                       |                       backward                                                                       |
+                       |                       compatibility,                                                                 |
+                       |                       if an upgrade is                                                               |
+                       |                       performed from                                                                 |
+                       |                       GlassFish Server                                                               |
+                       |                       v2.x or v3.0.x                                                                 |
+                       |                       to GlassFish                                                                   |
+                       |                       Server 4.0, the                                                                |
+                       |                       default                                                                        |
+                       |                       algorithm is                                                                   |
+                       |                       automatically                                                                  |
+                       |                       set to MD5 in                                                                  |
+                       |                       cases where the                                                                |
+                       |                       digest algorithm                                                               |
+                       |                       had not been                                                                   |
+                       |                       explicitly set                                                                 |
+                       |                       in the older                                                                   |
+                       |                       GlassFish Server                                                               |
+                       |                       version.                                                                       |
+                       +------------------------------------------------------------------------------------------------------+
+
+               digestrealm-password-enc-algorithm
+                   (Optional) Specifies the algorithm for encrypting passwords
+                   stored in the database.
+
+                       Note
+                       +---------------------------------------+
+                       |It is a security risk not to specify a |
+                       |password encryption algorithm.         |
+                       +---------------------------------------+
+
+               encoding
+                   (Optional) Specifies the encoding. Allowed values are Hex
+                   and Base64. If digest-algorithm is specified, the default
+                   is Hex. If digest-algorithm is not specified, by default no
+                   encoding is specified.
+
+               charset
+                   (Optional) Specifies the charset for the digest algorithm.
+
+           *   You can specify the following properties for LDAPRealm:
+
+               directory
+                   Specifies the LDAP URL to your server.
+
+               base-dn
+                   Specifies the LDAP base DN for the location of user data.
+                   This base DN can be at any level above the user data, since
+                   a tree scope search is performed. The smaller the search
+                   tree, the better the performance.
+
+               search-filter
+                   (Optional) Specifies the search filter to use to find the
+                   user. The default is uid=%s (%s expands to the subject
+                   name).
+
+               group-base-dn
+                   (Optional) Specifies the base DN for the location of groups
+                   data. By default, it is same as the base-dn, but it can be
+                   tuned, if necessary.
+
+               group-search-filter
+                   (Optional) Specifies the search filter to find group
+                   memberships for the user. The default is uniquemember=%d
+                   (%d expands to the user elementDN).
+
+               group-target
+                   (Optional) Specifies the LDAP attribute name that contains
+                   group name entries. The default is CN.
+
+               search-bind-dn
+                   (Optional) Specifies an optional DN used to authenticate to
+                   the directory for performing the search-filter lookup. Only
+                   required for directories that do not allow anonymous
+                   search.
+
+               search-bind-password
+                   (Optional) Specifies the LDAP password for the DN given in
+                   search-bind-dn.
+
+OPERANDS
+       auth_realm_name
+           A short name for the realm. This name is used to refer to the realm
+           from, for example, web.xml.
+
+EXAMPLES
+       Example 1, Creating a New Authentication Realm
+           This example creates a new file realm.
+
+               asadmin> create-auth-realm
+               --classname com.sun.enterprise.security.auth.realm.file.FileRealm
+               --property file=${com.sun.aas.instanceRoot}/config/
+               admin-keyfile:jaas-context=fileRealm file
+               Command create-auth-realm executed successfully
+           Where file is the authentication realm created.
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       delete-auth-realm(1), list-auth-realms(1)
+
+       asadmin(1M)
+
+Java EE 8                         20 Sep 2010             create-auth-realm(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-file-user.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-file-user.1
new file mode 100644
index 0000000..937d115
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-file-user.1
@@ -0,0 +1,73 @@
+create-file-user(1)       asadmin Utility Subcommands      create-file-user(1)
+
+NAME
+       create-file-user - creates a new file user
+
+SYNOPSIS
+           create-file-user [--help] [--authrealmnameauth_realm_name]
+           [--target target
+           [--groups user_groups[:user_groups]*] user_name
+
+DESCRIPTION
+       The create-file-user subcommand creates an entry in the keyfile with
+       the specified username, password, and groups. Multiple groups can be
+       created by separating them with a colon (:). If auth_realm_name is not
+       specified, an entry is created in the keyfile for the default realm. If
+       auth_realm_name is specified, an entry is created in the keyfile using
+       the auth_realm_name.
+
+       You can use the --passwordfile option of the asadmin(1M) command to
+       specify the password for the user. The password file entry must be of
+       the form AS_ADMIN_USERPASSWORD=user-password.
+
+       If a password is not provided, this subcommand fails if secure
+       administration is enabled and the user being created is an
+       administrative user.
+
+       This subcommand is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --target
+           This is the name of the target on which the command operates. The
+           valid targets are config, instance, cluster, or server. By default,
+           the target is the server.
+
+       --groups
+           This is the group associated with this file user.
+
+       --authrealmname
+           The name of the realm in which the new user is created. If you do
+           not specify this option, the user is created in the "file" realm.
+
+OPERANDS
+       user_name
+           This is the name of file user to be created.
+
+EXAMPLES
+       Example 1, Creating a User in the File Realm
+           This example creates a file realm user named sample_user. It is
+           assumed that an authentication realm has already been created using
+           the create-auth-realm subcommand.
+
+               asadmin> create-file-user
+               --groups staff:manager
+               --authrealmname auth-realm1 sample_user
+               Command create-file-user executed successfully
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       create-auth-realm(1), delete-file-user(1), list-file-users(1),
+       update-file-user(1), list-file-groups(1)
+
+       asadmin(1M)
+
+Java EE 8                        03 June 2011              create-file-user(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-jacc-provider.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-jacc-provider.1
new file mode 100644
index 0000000..ca6f480
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-jacc-provider.1
@@ -0,0 +1,116 @@
+create-jacc-provider(1)   asadmin Utility Subcommands  create-jacc-provider(1)
+
+NAME
+       create-jacc-provider - enables administrators to create a JACC provider
+       that can be used by third-party authorization modules for applications
+       running in GlassFish Server
+
+SYNOPSIS
+           create-jacc-provider [--help]
+           [--policyproviderclass pol-provider-class]
+           [--policyconfigfactoryclass pc-factory-class]
+           [--property name=value)[:name=value]*]
+           [--target target] jacc-provider-name
+
+DESCRIPTION
+       The create-jacc-provider subcommand creates a JSR-115—compliant Java
+       Authorization Contract for Containers (JACC) provider that can be used
+       for authorization of applications running in GlassFish Server. The JACC
+       provider is created as a jacc-provider element within the
+       security-service element in the domain's domain.xml file.
+
+       The default GlassFish Server installation includes two JACC providers,
+       named default and simple. Any JACC providers created with the
+       create-jacc-provider subcommand are in addition to these two default
+       providers. The default GlassFish Server JACC providers implement a
+       simple, file-based authorization engine that complies with the JACC
+       specification. The create-jacc-provider subcommand makes it possible to
+       specify additional third-party JACC providers.
+
+       You can create any number of JACC providers within the security-service
+       element, but the GlassFish Server runtime uses only one of them at any
+       given time. The jacc-provider element in the security-service element
+       points to the name of the provider that is currently in use by
+       GlassFish Server. If you change this element to point to a different
+       JACC provider, restart GlassFish Server.
+
+       This command is supported in remote mode only.
+
+OPTIONS
+       If an option has a short option name, then the short option precedes
+       the long option name. Short options have one dash whereas long options
+       have two dashes.
+
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --policyproviderclass
+           Specifies the fully qualified class name for the
+           javax.security.jacc.policy.provider that implements the
+           java.security.Policy.
+
+       --policyconfigfactoryclass
+           Specifies the fully qualified class name for the
+           javax.security.jacc.PolicyConfigurationFactory.provider that
+           implements the provider-specific
+           javax.security.jacc.PolicyConfigurationFactory.
+
+       --property
+           Optional attribute name/value pairs for configuring the JACC
+           provider. The following properties are available:
+
+           repository
+               The directory containing the JACC policy file. For the default
+               GlassFish Server JACC provider, the default directory is
+               ${com.sun.aas.instanceRoot}/generated/policy. This property is
+               not defined by default for the simple GlassFish Server JACC
+               provider.
+
+       --target
+           Specifies the target for which you are creating the JACC provider.
+           The following values are valid:
+
+           server
+               Creates the JACC provider on the default server instance. This
+               is the default value.
+
+           configuration_name
+               Creates the JACC provider in the specified configuration.
+
+           cluster_name
+               Creates the JACC provider on all server instances in the
+               specified cluster.
+
+           instance_name
+               Creates the JACC provider on a specified server instance.
+
+OPERANDS
+       jacc-provider-name
+           The name of the provider used to reference the jacc-provider
+           element in domain.xml.
+
+EXAMPLES
+       Example 1, Creating a JACC Provider
+           The following example shows how to create a JACC provider named
+           testJACC on the default server target.
+
+               asadmin> create-jacc-provider
+               --policyproviderclass com.sun.enterprise.security.provider.PolicyWrapper
+               --policyconfigfactoryclass com.sun.enterprise.security.provider.PolicyConfigurationFactoryImpl
+               testJACC
+
+               Command create-jacc-provider executed successfully.
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       delete-jacc-provider(1), list-jacc-providers(1)
+
+       asadmin(1M)
+
+Java EE 8                         14 Jun 2011           create-jacc-provider(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-message-security-provider.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-message-security-provider.1
new file mode 100644
index 0000000..132db5d
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-message-security-provider.1
@@ -0,0 +1,169 @@
+create-message-security-provider(1)  asadmin Utility Subcommands  create-message-security-provider(1)
+
+NAME
+       create-message-security-provider - enables administrators to create a
+       message security provider, which specifies how SOAP messages will be
+       secured.
+
+SYNOPSIS
+           create-message-security-provider [--help]
+           [--target target]
+           --classname provider_class
+           [--layer message_layer] [--providertype provider_type]
+           [--requestauthsource request_auth_source ]
+           [--requestauthrecipient request_auth_recipient ]
+           [--responseauthsource response_auth_source ]
+           [--responseauthrecipient response_auth_recipient ]
+           [--isdefaultprovider] [--property name=value[:name=value]*]
+           provider_name
+
+DESCRIPTION
+       The create-message-security-provider subcommand enables the
+       administrator to create a message security provider for the security
+       service which specifies how SOAP messages will be secured.
+
+       This command is supported in remote mode only.
+
+OPTIONS
+       If an option has a short option name, then the short option precedes
+       the long option name. Short options have one dash whereas long options
+       have two dashes.
+
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --target
+           Specifies the target for which you are creating the message
+           security provider. The following values are valid:
+
+           server
+               Creates the provider for the default server instance server and
+               is the default value.
+
+           domain
+               Creates the provider for the domain.
+
+           cluster_name
+               Creates the provider for every server instance in the cluster.
+
+           instance_name
+               Creates the provider for a particular sever instance.
+
+       --classname
+           Defines the Java implementation class of the provider. Client
+           authentication providers must implement the com.sun.enterprise.
+           security.jauth.ClientAuthModule interface. Server-side providers
+           must implement the com.sun.enterprise.security
+           jauth.ServerAuthModule interface. A provider may implement both
+           interfaces, but it must implement the interface corresponding to
+           its provider type.
+
+       --layer
+           The message-layer entity used to define the value of the auth-layer
+           attribute of message-security-config elements. The default is
+           HttpServlet. Another option is SOAP.
+
+       --providertype
+           Establishes whether the provider is to be used as client
+           authentication provider, server authentication provider, or both.
+           Valid options for this property include client, server, or
+           client-server.
+
+       --requestauthsource
+           The auth-source attribute defines a requirement for message-layer
+           sender authentication (e.g. username password) or content
+           authentication (e.g. digital signature) to be applied to request
+           messages. Possible values are sender or content. When this argument
+           is not specified, source authentication of the request is not
+           required.
+
+       --requestauthrecipient
+           The auth-recipient attribute defines a requirement for
+           message-layer authentication of the receiver of a message to its
+           sender (e.g. by XML encryption). Possible values are before-content
+           or after-content. The default value is after-content.
+
+       --responseauthsource
+           The auth-source attribute defines a requirement for message-layer
+           sender authentication (e.g. username password) or content
+           authentication (e.g. digital signature) to be applied to response
+           messages. Possible values are sender or content. When this option
+           is not specified, source authentication of the response is not
+           required.
+
+       --responseauthrecipient
+           The auth-recipient attribute defines a requirement for
+           message-layer authentication of the receiver of the response
+           message to its sender (e.g. by XML encryption). Possible values are
+           before-content or after-content. The default value is
+           after-content.
+
+       --isdefaultprovider
+           The default-provider attribute is used to designate the provider as
+           the default provider (at the layer) of the type or types identified
+           by the providertype argument. There is no default associated with
+           this option.
+
+       --property
+           Use this property to pass provider-specific property values to the
+           provider when it is initialized. Properties passed in this way
+           might include key aliases to be used by the provider to get keys
+           from keystores, signing, canonicalization, encryption algorithms,
+           etc.
+
+           The following properties may be set:
+
+           security.config
+               Specifies the location of the message security configuration
+               file. To point to a configuration file in the domain-dir/config
+               directory, use the system property
+               ${com.sun.aas.instanceRoot}/config/, for example:
+               ${com.sun.aas.instanceRoot}/config/wss-server-config-1.0.xml.
+               The default is domain-dir/config/ wss-serverconfig-1.0.xml.
+
+           debug
+               If true, enables dumping of server provider debug messages to
+               the server log. The default is false.
+
+           dynamic.username. password
+               If true, signals the provider runtime to collect the user name
+               and password from the CallbackHandler for each request. If
+               false, the user name and password for wsse:UsernameToken(s) is
+               collected once, during module initialization. This property is
+               only applicable for a ClientAuthModule. The default is false.
+
+           encryption.key.alias
+               Specifies the encryption key used by the provider. The key is
+               identified by its keystore alias. The default value is s1as.
+
+           signature.key.alias
+               Specifies the signature key used by the provider. The key is
+               identified by its keystore alias. The default value is s1as.
+
+OPERANDS
+       provider_name
+           The name of the provider used to reference the provider-config
+           element.
+
+EXAMPLES
+       Example 1, Creating a Message Security Provider
+           The following example shows how to create a message security
+           provider for a client.
+
+               asadmin> create-message-security-provider
+               --classname com.sun.enterprise.security.jauth.ClientAuthModule
+               --providertype client mySecurityProvider
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       delete-message-security-provider(1), list-message-security-providers(1)
+
+       asadmin(1M)
+
+Java EE 8              09 Aug 2017       create-message-security-provider(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-password-alias.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-password-alias.1
new file mode 100644
index 0000000..465f32f
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/create-password-alias.1
@@ -0,0 +1,72 @@
+create-password-alias(1)  asadmin Utility Subcommands  create-password-alias(1)
+
+NAME
+       create-password-alias - creates a password alias
+
+SYNOPSIS
+           create-password-alias [--help]
+           aliasname
+
+DESCRIPTION
+       The create-password-alias subcommand creates an alias for a password.
+       An alias is a token of the form ${ALIAS=aliasname}. The password that
+       corresponds to the alias name is stored in an encrypted form.
+
+       The create-password-alias subcommand can be run interactively or
+       noninteractively.
+
+       *   When run interactively, the subcommand prompts the user for the
+           alias password and to confirm the alias password.
+
+       *   When run noninteractively, the subcommand reads the alias password
+           from a file that is passed through the --passwordfile option of the
+           asadmin(1M) utility. The file must contain an entry of the form
+           AS_ADMIN_ALIASPASSWORD=alias-password, where alias-password is the
+           alias password. The noninteractive form of this command is suitable
+           for use in scripts.
+
+       This subcommand is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+OPERANDS
+       aliasname
+           Your choice of name for the password alias.
+
+EXAMPLES
+       Example 1, Creating a Password Alias Interactively
+           This example creates the password alias jmspassword-alias
+           interactively.
+
+               asadmin> create-password-alias jmspassword-alias
+               Enter the alias password>
+               Enter the alias password again>
+               Command create-password-alias executed successfully.
+
+       Example 2, Creating a Password Alias Noninteractively
+           This example uses the --passwordfile option of the asadmin utility
+           to create the password alias winuser noninteractively.
+
+               $ asadmin --passwordfile aspwfile.txt create-password-alias winuser
+               Command create-password-alias executed successfully.
+           The file aspwfile.txt contains the following entry to specify the
+           alias password:
+
+               AS_ADMIN_ALIASPASSWORD=sp@rky
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       delete-password-alias(1), list-password-aliases(1),
+       update-password-alias(1)
+
+       asadmin(1M)
+
+Java EE 8                    09 Aug 2017             create-password-alias(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-audit-module.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-audit-module.1
new file mode 100644
index 0000000..8da40b2
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-audit-module.1
@@ -0,0 +1,59 @@
+delete-audit-module(1)    asadmin Utility Subcommands   delete-audit-module(1)
+
+NAME
+       delete-audit-module - removes the named audit-module
+
+SYNOPSIS
+           delete-audit-module [--help]
+           [--target target]
+           audit_module_name
+
+DESCRIPTION
+       This subcommand removes the named audit module. This subcommand is
+       supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --target
+           Specifies the target on which you are deleting the audit module.
+           Valid values are as follows:
+
+           server
+               Deletes the audit module for the default server instance server
+               and is the default value.
+
+           configuration_name
+               Deletes the audit module for the named configuration.
+
+           cluster_name
+               Deletes the audit module for every server instance in the
+               cluster.
+
+           instance_name
+               Deletes the audit module for a particular server instance.
+
+OPERANDS
+       audit_module_name
+           The name of the audit module to be deleted.
+
+EXAMPLES
+       Example 1, Deleting an audit module
+
+               asadmin> delete-audit-module sampleAuditModule
+               Command delete-audit-module executed successfully
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       create-audit-module(1), list-audit-modules(1)
+
+       asadmin(1M)
+
+Java EE 8                         22 Dec 2010           delete-audit-module(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-auth-realm.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-auth-realm.1
new file mode 100644
index 0000000..9258f93
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-auth-realm.1
@@ -0,0 +1,59 @@
+delete-auth-realm(1)      asadmin Utility Subcommands     delete-auth-realm(1)
+
+NAME
+       delete-auth-realm - removes the named authentication realm
+
+SYNOPSIS
+           delete-auth-realm [--help]
+           [--target target]
+           auth_realm-name
+
+DESCRIPTION
+       The delete-auth-realm subcommand removes the named authentication
+       realm. This subcommand is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --target
+           Specifies the target on which you are deleting the authentication
+           realm. Valid values are
+
+           server
+               Deletes the realm for the default server instance server and is
+               the default value.
+
+           configuration_name
+               Deletes the realm for the named configuration.
+
+           cluster_name
+               Deletes the realm for every server instance in the cluster.
+
+           instance_name
+               Deletes the realm for a particular server instance.
+
+OPERANDS
+       auth_realm_name
+           Name of the realm to be deleted.
+
+EXAMPLES
+       Example 1, Deleting an Authentication Realm
+           This example deletes the authentication realm db.
+
+               asadmin> delete-auth-realm db
+               Command delete-auth-realm executed successfully
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       create-auth-realm(1), list-auth-realms(1)
+
+       asadmin(1M)
+
+Java EE 8                         22 Dec 2010             delete-auth-realm(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-file-user.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-file-user.1
new file mode 100644
index 0000000..68a245f
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-file-user.1
@@ -0,0 +1,67 @@
+delete-file-user(1)       asadmin Utility Subcommands      delete-file-user(1)
+
+NAME
+       delete-file-user - removes the named file user
+
+SYNOPSIS
+           delete-file-user [--help][--authrealmname auth_realm_name]
+           [--target target]
+           username
+
+DESCRIPTION
+       The delete-file-user subcommand deletes the entry in the keyfile for
+       the specified username.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --authrealmname
+           The name of the authentication realm with which the user was
+           created.
+
+       --target
+           This is the name of the target on which the command operates. The
+           valid targets are:
+
+           server
+               Deletes the file user on the default server instance. This is
+               the default value
+
+           domain
+               Deletes the file user in the domain.
+
+           cluster_name
+               Deletes the file user from every server instance in the
+               cluster.
+
+           instance_name
+               Deletes the file user from a particular server instance.
+
+OPERANDS
+       username
+           This is the name of file user to be deleted.
+
+EXAMPLES
+       Example 1, Deleting a User From a File Realm
+           The following example shows how to delete user named sample_user
+           from a file realm.
+
+               asadmin> delete-file-user
+               sample_user
+               Command delete-file-user executed successfully
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       create-file-user(1), list-file-users(1), update-file-user(1),
+       list-file-groups(1)
+
+       asadmin(1M)
+
+Java EE 8                      01 December 2010            delete-file-user(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-jacc-provider.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-jacc-provider.1
new file mode 100644
index 0000000..a32e3e3
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-jacc-provider.1
@@ -0,0 +1,84 @@
+delete-jacc-provider(1)   asadmin Utility Subcommands  delete-jacc-provider(1)
+
+NAME
+       delete-jacc-provider - enables administrators to delete JACC providers
+       defined for a domain
+
+SYNOPSIS
+           delete-jacc-provider [--help]
+           [--target target] jacc-provider-name
+
+DESCRIPTION
+       The delete-jacc-provider subcommand enables administrators to delete
+       JACC providers defined for a domain. JACC providers are defined as
+       jacc-provider elements in the security-service element in the domain's
+       domain.xml file. JACC providers can be created using the GlassFish
+       Server Admin Console or the create-jacc-provider subcommand.
+
+       The default GlassFish Server installation includes two JACC providers,
+       named default and simple. These default providers should not be
+       deleted.
+
+       The JACC provider used byGlassFish Server for authorization is
+       identified by the jacc-provider element of security-service in
+       domain.xml. Therefore, if you delete the jacc-provider provider, make
+       sure you change jacc-provider to the name of some other JACC provider
+       that exists under security-service.
+
+       If you change the jacc-provider element to point to a different JACC
+       provider, you must restart GlassFish Server.
+
+       This subcommand is supported in remote mode only.
+
+OPTIONS
+       If an option has a short option name, then the short option precedes
+       the long option name. Short options have one dash whereas long options
+       have two dashes.
+
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --target
+           Specifies the target from which you are deleting the JACC provider.
+           The following values are valid:
+
+           server
+               Deletes the JACC provider on the default server instance. This
+               is the default value.
+
+           configuration_name
+               Deletes the JACC provider in the specified configuration.
+
+           cluster_name
+               Deletes the JACC provider on all server instances in the
+               specified cluster.
+
+           instance_name
+               Deletes the JACC provider on a specified server instance.
+
+OPERANDS
+       jacc-provider-name
+           The name of the JACC provider to be deleted.
+
+EXAMPLES
+       Example 1, Deleting a JACC provider
+           The following example shows how to delete a JACC provider named
+           testJACC from the default domain.
+
+               asadmin> delete-jacc-provider testJACC
+
+               Command delete-jacc-provider executed successfully.
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       create-jacc-provider(1), list-jacc-providers(1)
+
+       asadmin(1M)
+
+Java EE 8                         14 Jun 2011          delete-jacc-provider(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-message-security-provider.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-message-security-provider.1
new file mode 100644
index 0000000..a8e914b
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-message-security-provider.1
@@ -0,0 +1,85 @@
+delete-message-security-provider(1)  asadmin Utility Subcommands  delete-message-security-provider(1)
+
+NAME
+       delete-message-security-provider - enables administrators to delete a
+       message security provider
+
+SYNOPSIS
+           delete-message-security-provider [--help] [--target target]
+           --layer message_layer
+           provider_name
+
+DESCRIPTION
+       The delete-message-security-provider subcommand enables administrators
+       to delete a message security provider.
+
+       In terms of what happens when this subcommand is run, the
+       provider-config sub-element for the given message layer
+       (message-security-config element of domain.xml is deleted. The
+       domain.xmlfile specifies parameters and properties to the GlassFish
+       Server). The options specified in the list below apply to attributes
+       within the message-security-config and provider-config sub-elements of
+       the domain.xml file.
+
+       If the message-layer (message-security-config attribute) does not
+       exist, it is created, and then the provider-config is created under it.
+
+       This command is supported in remote mode only.
+
+OPTIONS
+       If an option has a short option name, then the short option precedes
+       the long option name. Short options have one dash whereas long options
+       have two dashes.
+
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --target
+           Specifies the target from which you are deleting the message
+           security provider. Valid values are
+
+           server
+               Deletes the message security provider from the default server
+               instance server and is the default value
+
+           domain
+               Deletes the message security provider from the domain.
+
+           cluster_name
+               Deletes the message security provider from every server
+               instance in the cluster.
+
+           instance_name
+               Deletes the message security provider from a particular sever
+               instance.
+
+       --layer
+           The message-layer from which the provider has to be deleted. The
+           default value is HttpServlet.
+
+OPERANDS
+       provider_name
+           The name of the provider used to reference the provider-config
+           element.
+
+EXAMPLES
+       Example 1, Deleting a message security provider
+           The following example shows how to delete a message security
+           provider for a client.
+
+               asadmin> delete-message-security-provider
+               --layer SOAP mySecurityProvider
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       create-message-security-provider(1), list-message-security-providers(1)
+
+       asadmin(1M)
+
+Java EE 8               09 Aug 2017        delete-message-security-provider(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-password-alias.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-password-alias.1
new file mode 100644
index 0000000..0865934
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/delete-password-alias.1
@@ -0,0 +1,42 @@
+delete-password-alias(1)  asadmin Utility Subcommands delete-password-alias(1)
+
+NAME
+       delete-password-alias - deletes a password alias
+
+SYNOPSIS
+           delete-password-alias [--help]
+            aliasname
+
+DESCRIPTION
+       This subcommand deletes a password alias.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+OPERANDS
+       aliasname
+           This is the name of the substitute password as it appears in
+           domain.xml.
+
+EXAMPLES
+       Example 1, Deleting a Password Alias
+
+               asadmin>delete-password-alias
+               jmspassword-alias
+           Command delete-password-alias executed successfully
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       create-password-alias(1), list-password-aliases(1),
+       update-password-alias(1)
+
+       asadmin(1M)
+
+Java EE 8                       28 August 2009        delete-password-alias(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-audit-modules.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-audit-modules.1
new file mode 100644
index 0000000..98cba1f
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-audit-modules.1
@@ -0,0 +1,56 @@
+list-audit-modules(1)     asadmin Utility Subcommands    list-audit-modules(1)
+
+NAME
+       list-audit-modules - gets all audit modules and displays them
+
+SYNOPSIS
+           list-audit-modules [--help] [target]
+
+DESCRIPTION
+       The list-audit-modules subcommand lists all the audit modules. This
+       subcommand is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+OPERANDS
+       target
+           Specifies the target on which you are listing the audit modules.
+           Valid values are as follows:
+
+           server
+               Lists the audit modules for the default server instance server
+               and is the default value.
+
+           configuration_name
+               Lists the audit modules for the named configuration.
+
+           cluster_name
+               Lists the audit modules for every server instance in the
+               cluster.
+
+           instance_name
+               Lists the audit modules for a particular server instance.
+
+EXAMPLES
+       Example 1, Listing Audit Modules
+
+               asadmin> list-audit-modules
+               sampleAuditModule1
+               sampleAuditModule2
+               Command list-audit-modules executed successfully
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       create-audit-module(1), delete-audit-module(1)
+
+       asadmin(1M)
+
+Java EE 8                         22 Dec 2010            list-audit-modules(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-auth-realms.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-auth-realms.1
new file mode 100644
index 0000000..9f47df6
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-auth-realms.1
@@ -0,0 +1,59 @@
+list-auth-realms(1)       asadmin Utility Subcommands      list-auth-realms(1)
+
+NAME
+       list-auth-realms - lists the authentication realms
+
+SYNOPSIS
+           list-auth-realms [--help] [target]
+
+DESCRIPTION
+       The list-auth-realms subcommand lists the authentication realms. This
+       subcommand is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+OPERANDS
+       target
+           The name of the target for which you want to list the
+           authentication realms.
+
+           server
+               Lists the realms for the default server instance server and is
+               the default value.
+
+           configuration_name
+               Lists the realms for the named configuration.
+
+           cluster_name
+               Lists the realms for every server instance in the cluster.
+
+           instance_name
+               Lists the realms for a particular server instance.
+
+EXAMPLES
+       Example 1, Listing authentication realms
+
+               asadmin> list-auth-realms
+               file
+               ldap
+               certificate
+               db
+               Command list-auth-realms executed successfully
+           Where file, ldap, certificate, and db are the available
+           authentication realms.
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       create-auth-realm(1), delete-auth-realm(1)
+
+       asadmin(1M)
+
+Java EE 8                         22 Dec 2010              list-auth-realms(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-file-groups.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-file-groups.1
new file mode 100644
index 0000000..4b2f840
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-file-groups.1
@@ -0,0 +1,66 @@
+list-file-groups(1)       asadmin Utility Subcommands      list-file-groups(1)
+
+NAME
+       list-file-groups - lists file groups
+
+SYNOPSIS
+           list-file-groups [--help] [--name username] [--authrealmname auth_realm_name]
+           [--target target]
+
+DESCRIPTION
+       The list-file-groups subcommand lists the file users and groups
+       supported by the file realm authentication. This subcommand lists
+       available groups in the file user. If the --name option is not
+       specified, all groups are listed.
+
+       This subcommand is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --name
+           Identifies the name of the file user for whom the groups will be
+           listed.
+
+       --authrealmname
+           The name of the authentication realm for which to list available
+           groups.
+
+       --target
+           This option specifies which configurations you can list. Valid
+           targets are:
+
+           server
+               Lists the file groups in the current server. This is the
+               default value.
+
+           cluster_name
+               Lists the file groups in a cluster.
+
+           instance_name
+               Lists the file groups for a particular instance.
+
+EXAMPLES
+       Example 1, Listing Groups in all File Realms
+           This example list all file realm groups defined for the server.
+
+               asadmin> list-file-groups
+               staff
+               manager
+               Command list-file-groups executed successfully
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       delete-file-user(1), update-file-user(1), create-file-user(1),
+       list-file-users(1)
+
+       asadmin(1M)
+
+Java EE 8                      01 December 2010            list-file-groups(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-file-users.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-file-users.1
new file mode 100644
index 0000000..b09c42c
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-file-users.1
@@ -0,0 +1,63 @@
+list-file-users(1)        asadmin Utility Subcommands       list-file-users(1)
+
+NAME
+       list-file-users - lists the file users
+
+SYNOPSIS
+           list-file-users [--help] [--authrealmname auth_realm_name] [target]
+
+DESCRIPTION
+       The list-file-users subcommand displays a list of file users supported
+       by file realm authentication.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --authrealmname
+           Lists only the users in the specified authentication realm.
+
+OPERANDS
+       target
+           Specifies the target for which you want to list file users. The
+           following values are valid:
+
+           server
+               Lists the file users on the default server instance. This is
+               the default value.
+
+           configuration_name
+               Lists the file users in the specified configuration.
+
+           cluster_name
+               Lists the file users on all server instances in the specified
+               cluster.
+
+           instance_name
+               Lists the file users on a specified server instance.
+
+EXAMPLES
+       Example 1, Listing Users in a Specific File Realm
+           The following example lists the users in the file realm named
+           sample_file_realm.
+
+               asadmin> list-file-users --authrealmname sample_file_realm
+               sample_user05
+               sample_user08
+               sample_user12
+               Command list-file-users executed successfully
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       create-file-user(1), delete-file-user(1), update-file-user(1),
+       list-file-groups(1)
+
+       asadmin(1M)
+
+Java EE 8                         21 Jun 2011               list-file-users(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-jacc-providers.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-jacc-providers.1
new file mode 100644
index 0000000..1331c7e
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-jacc-providers.1
@@ -0,0 +1,66 @@
+list-jacc-providers(1)    asadmin Utility Subcommands   list-jacc-providers(1)
+
+NAME
+       list-jacc-providers - enables administrators to list JACC providers
+       defined for a domain
+
+SYNOPSIS
+           list-jacc-providers [--help] [target]
+
+DESCRIPTION
+       The list-jacc-providers subcommand enables administrators to list the
+       JACC providers defined for a domain. JACC providers are defined as
+       jacc-provider elements in the security-service element in the domain's
+       domain.xml file. JACC providers can be created using the GlassFish
+       Server Admin Console or the create-jacc-provider subcommand.
+
+       This subcommand is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+OPERANDS
+       target
+           Specifies the target for which you want to list JACC providers. The
+           following values are valid:
+
+           server
+               Lists the JACC providers on the default server instance. This
+               is the default value.
+
+           configuration_name
+               Lists the JACC providers in the specified configuration.
+
+           cluster_name
+               Lists the JACC providers on all server instances in the
+               specified cluster.
+
+           instance_name
+               Lists the JACC providers on a specified server instance.
+
+EXAMPLES
+       Example 1, Listing JACC providers
+           The following example shows how to list JACC providers for the
+           default domain.
+
+               asadmin> list-jacc-providers
+               default
+               simple
+               testJACC
+
+               Command list-jacc-providers executed successfully.
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       create-jacc-provider(1), delete-jacc-provider(1)
+
+       asadmin(1M)
+
+Java EE 8                         21 Jun 2011           list-jacc-providers(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-message-security-providers.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-message-security-providers.1
new file mode 100644
index 0000000..9d065ab
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-message-security-providers.1
@@ -0,0 +1,72 @@
+list-message-security-providers(1)  asadmin Utility Subcommands  list-message-security-providers(1)
+
+NAME
+       list-message-security-providers - lists all security message providers
+       for the given message layer
+
+SYNOPSIS
+           list-message-security-providers [--help]
+           --layer message_layer
+           [target]
+
+DESCRIPTION
+       The list-message-security-providers subcommand enables administrators
+       to list all security message providers (provider-config sub-elements)
+       for the given message layer (message-security-config element of
+       domain.xml).
+
+       This subcommand is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --layer
+           The message-layer for which the provider has to be listed. The
+           default value is HttpServlet.
+
+OPERANDS
+       target
+           Restricts the listing to message security providers for a specific
+           target. Valid values include:
+
+           server
+               Lists providers for the default server instance server and is
+               the default value.
+
+           domain
+               Lists providers for the domain.
+
+           cluster
+               Lists providers for the server instances in the cluster.
+
+           instance
+               Lists providers for a particular server instance.
+
+EXAMPLES
+       Example 1, Listing message security providers
+           The following example shows how to list message security providers
+           for a message layer.
+
+               asadmin> list-message-security-providers
+               --layer SOAP
+               XWS_ClientProvider
+               ClientProvider
+               XWS_ServerProvider
+               ServerProvider
+               Command list-message-security-providers executed successfully.
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       create-message-security-provider(1),
+       delete-message-security-provider(1)
+
+       asadmin(1M)
+
+Java EE 8               09 Aug 2017        list-message-security-providers(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-password-aliases.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-password-aliases.1
new file mode 100644
index 0000000..19057ba
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-password-aliases.1
@@ -0,0 +1,36 @@
+list-password-aliases(1)  asadmin Utility Subcommands list-password-aliases(1)
+
+NAME
+       list-password-aliases - lists all password aliases
+
+SYNOPSIS
+           list-password-aliases [--help]
+
+DESCRIPTION
+       Thissubcommand lists all of the password aliases.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+EXAMPLES
+       Example 1, Listing all password aliases
+
+               asadmin> list-password-aliases
+               jmspassword-alias
+               Command list-password-aliases executed successfully
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       delete-password-alias(1), update-password-alias(1),
+       create-password-alias(1)
+
+       asadmin(1M)
+
+Java EE 8                       28 August 2009        list-password-aliases(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-supported-cipher-suites.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-supported-cipher-suites.1
new file mode 100644
index 0000000..33b4803
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/list-supported-cipher-suites.1
@@ -0,0 +1,85 @@
+list-supported-cipher-suites(1)  asadmin Utility Subcommands  list-supported-cipher-suites(1)
+
+NAME
+       list-supported-cipher-suites - enables administrators to list the
+       cipher suites that are supported and available to a specified GlassFish
+       Server target
+
+SYNOPSIS
+           list-supported-cipher-suites [--help] [--target target]
+
+DESCRIPTION
+       The list-supported-cipher-suites subcommand enables administrators to
+       list the cipher suites that are supported and available to a specified
+       GlassFish Server target. The cipher suites that may be available in
+       addition to the default SSL/TLS providers that are bundled with
+       GlassFish Server packages will vary depending on the third-party
+       provider.
+
+       This subcommand is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --target
+           Specifies the target for which you want to list cipher suites. The
+           following values are valid:
+
+           server
+               Lists the cipher suites for the default server instance. This
+               is the default value.
+
+           configuration_name
+               Lists the cipher suites for the specified configuration.
+
+           cluster_name
+               Lists the cipher suites for all server instances in the
+               specified cluster.
+
+           instance_name
+               Lists the cipher suites for a specified server instance.
+
+EXAMPLES
+       Example 1, Listing cipher suites
+           The following example shows how to list cipher suites for the
+           default domain.
+
+               asadmin> list-supported-cipher-suites
+               SSL_RSA_WITH_RC4_128_MD5
+               SSL_RSA_WITH_RC4_128_SHA
+               TLS_RSA_WITH_AES_128_CBC_SHA
+               TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+               TLS_DHE_DSS_WITH_AES_128_CBC_SHA
+               SSL_RSA_WITH_3DES_EDE_CBC_SHA
+               SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+               SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
+               SSL_RSA_WITH_DES_CBC_SHA
+               SSL_DHE_RSA_WITH_DES_CBC_SHA
+               SSL_DHE_DSS_WITH_DES_CBC_SHA
+               SSL_RSA_EXPORT_WITH_RC4_40_MD5
+               SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
+               SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
+               SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
+               SSL_RSA_WITH_NULL_MD5
+               SSL_RSA_WITH_NULL_SHA
+               SSL_DH_anon_WITH_RC4_128_MD5
+               TLS_DH_anon_WITH_AES_128_CBC_SHA
+               SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
+               SSL_DH_anon_WITH_DES_CBC_SHA
+               SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
+               SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
+
+               Command list-supported-cipher-suites executed successfully.
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       asadmin(1M)
+
+Java EE 8                09 Aug 2017         list-supported-cipher-suites(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/update-file-user.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/update-file-user.1
new file mode 100644
index 0000000..72b51e1
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/update-file-user.1
@@ -0,0 +1,72 @@
+update-file-user(1)       asadmin Utility Subcommands      update-file-user(1)
+
+NAME
+       update-file-user - updates a current file user as specified
+
+SYNOPSIS
+           update-file-user [--help] [--groups user_groups[:user_groups]*]
+           [--target target
+           [--authrealmname authrealm_name]
+           username
+
+DESCRIPTION
+       Th update-file-user subcommand updates an existing entry in the keyfile
+       using the specified user name, password and groups. Multiple groups can
+       be entered by separating them, with a colon (:).
+
+       If a new password is not provided, this subcommand fails if secure
+       administration is enabled and the user being updated is an
+       administrative user.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+       --groups
+           This is the name of the group to which the file user belongs.
+
+       --authrealmname
+           Name of the authentication realm where the user to be updated can
+           be found.
+
+       --target
+           This option helps specify the target on which you are updating a
+           file user. Valid values are:
+
+           server
+               Updates the file user in the default server instance. This is
+               the default value.
+
+           cluster_name
+               Updates the file user on every server instance in the cluster.
+
+           instance_name
+               Updates the file user on a specified sever instance.
+
+OPERANDS
+       username
+           This is the name of the file user to be updated.
+
+EXAMPLES
+       Example 1, Updating a User's Information in a File Realm
+           The following example updates information for a file realm user
+           named sample_user.
+
+               asadmin> update-file-user
+               --groups staff:manager:engineer sample_user
+               Command update-file-user executed successfully
+
+EXIT STATUS
+       0
+           subcommand executed successfully
+
+       1
+           error in executing the subcommand
+
+SEE ALSO
+       delete-file-user(1), list-file-users(1), create-file-user(1),
+       list-file-groups(1)
+
+       asadmin(1M)
+
+Java EE 8                      01 December 2010            update-file-user(1)
diff --git a/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/update-password-alias.1 b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/update-password-alias.1
new file mode 100644
index 0000000..5102e7e
--- /dev/null
+++ b/nucleus/security/core/src/main/manpages/com/sun/enterprise/security/cli/update-password-alias.1
@@ -0,0 +1,50 @@
+update-password-alias(1)  asadmin Utility Subcommands  update-password-alias(1)
+
+NAME
+       update-password-alias - updates a password alias
+
+SYNOPSIS
+           update-password-alias [--help]
+            aliasname
+
+DESCRIPTION
+       This subcommand updates the password alias IDs in the named target. An
+       alias is a token of the form ${ALIAS=password-alias-password}. The
+       password corresponding to the alias name is stored in an encrypted
+       form. The update-password-alias subcommand takes both a secure
+       interactive form (in which the user is prompted for all information)
+       and a more script-friendly form, in which the password is propagated on
+       the command line.
+
+       This subcommand is supported in remote mode only.
+
+OPTIONS
+       --help, -?
+           Displays the help text for the subcommand.
+
+OPERANDS
+       aliasname
+           This is the name of the password as it appears in domain.xml.
+
+EXAMPLES
+       Example 1, Updating a Password Alias
+
+               asadmin> update-password-alias jmspassword-alias
+               Please enter the alias password>
+               Please enter the alias password again>
+               Command update-password-alias executed successfully.
+
+EXIT STATUS
+       0
+           command executed successfully
+
+       1
+           error in executing the command
+
+SEE ALSO
+       delete-password-alias(1), list-password-aliases(1),
+       create-password-alias(1)
+
+       asadmin(1M)
+
+Java EE 8                  09 Aug 2017             update-password-alias(1)
diff --git a/nucleus/security/core/src/main/resources/com/sun/enterprise/security/admin/cli/LocalStrings.properties b/nucleus/security/core/src/main/resources/com/sun/enterprise/security/admin/cli/LocalStrings.properties
new file mode 100644
index 0000000..e5c48ec
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/com/sun/enterprise/security/admin/cli/LocalStrings.properties
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+
+
+enable.secure.admin.command=Enable domain-wide secure administration
+enable.secure.admin.errenable=Error enabling secure admin
+disable.secure.admin.command=Disable domain-wide secure administration
+disable.secure.admin.errdisable=Error disabling secure admin
+enable.secure.admin.badAlias=Error enabling secure admin; the keystore does not contain the specified {0,choice,1#alias|1<aliases} {1}
+
+noKeyStore=Could not access key store
+noAlias=Could not find the alias {0} in the key store
+certNotX509Certificate=Certificate in the key store with alias {0} is not an X509 certificate, as expected
+errVal=Error validating username and password alias
+notAdminUser=The username {0} is not a valid admin user
+adminsWithEmptyPW=At least one admin user has an empty password, which secure admin does not permit. Use the change-admin-password command or the admin console to create non-empty passwords for admin accounts.
+restartReq=You must restart all running servers for the change in secure admin to take effect.
diff --git a/nucleus/security/core/src/main/resources/com/sun/enterprise/security/audit/LocalStrings.properties b/nucleus/security/core/src/main/resources/com/sun/enterprise/security/audit/LocalStrings.properties
new file mode 100644
index 0000000..2fc941b
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/com/sun/enterprise/security/audit/LocalStrings.properties
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+auditmgr.admininvocation=Audit: Audit Module {0} threw the following exception during admin invocation :
+auditmgr.authentication=Audit: Audit Module {0} threw the following exception during authentication:
+auditmgr.logout=Audit: Audit Module {0} threw the following exception during logout:
+auditmgr.loaderror=Audit: Cannot load AuditModule = {0}
+auditmgr.badinit=Audit: Cannot load Audit Module Initialization information. AuditModules will not be loaded.
+auditmgr.serverStartup=Audit: Audit Module {0} threw the following exception during server startup :
+auditmgr.serverShutdown=Audit: Audit Module {0} threw the following exception during server shutdown :
diff --git a/nucleus/security/core/src/main/resources/com/sun/enterprise/security/cli/.gitkeep_empty_dir b/nucleus/security/core/src/main/resources/com/sun/enterprise/security/cli/.gitkeep_empty_dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/com/sun/enterprise/security/cli/.gitkeep_empty_dir
diff --git a/nucleus/security/core/src/main/resources/com/sun/logging/enterprise/system/core/security/LogStrings.properties b/nucleus/security/core/src/main/resources/com/sun/logging/enterprise/system/core/security/LogStrings.properties
new file mode 100644
index 0000000..28ca946
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/com/sun/logging/enterprise/system/core/security/LogStrings.properties
@@ -0,0 +1,238 @@
+#
+# Copyright (c) 2004, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+
+# Common iAS security messages.
+security.exception=SEC1000: Caught exception.
+security.secmgron=SEC1001: Security Manager is ON.
+security.secmgroff=SEC1002: Security Manager is OFF.
+security.secmgr.could.not.override=SEC1003: Could not override SecurityManager.
+
+#Security Service messages
+sec.service.startup.enter=SEC1010: Entering Security Startup Service
+sec.service.startup.exit=SEC1011: Security Service(s) Started Successfully
+
+# General login processing messages: start 1050
+certlogin.badrealm=SEC1050: Certificate authentication requires certificate realm. Check server configuration.
+
+
+# Realms and Login Modules: start at 1100
+
+realmconfig.disable=SEC1100: Disabled realm [{0}] due to errors.
+realmconfig.nogood=SEC1101: No realms available. Authentication services disabled.
+realmconfig.noctx=SEC1102: Incomplete configuration, login module not specified.
+iasrealm.noauth=SEC1103: No AuthenticationHandler available for this realm.
+passwordlm.nocreds=SEC1104: Error while obtaining private subject credentials.
+passwordlm.nopwdcred=SEC1105: A PasswordCredential was required but not provided.
+ldaprealm.searcherror=SEC1106: Error during LDAP search with filter [{0}].
+filerealm.readerror=SEC1109: Error reading file realm data.
+certrealm.nojaas=SEC1110: JAAS context requested from certificate realm. Configuration error is likely.
+jdbcrealm.grouperror=SEC1111: Cannot load group for JDBC realm user [{0}].
+jdbcrealm.invaliduser=SEC1112: Cannot validate user [{0}] for JDBC realm.
+ldaprealm.exception=SEC1113: Exception in LdapRealm when trying to authenticate user.
+ldaprealm.groupsearcherror=SEC1114: Exception in LdapRealm when trying to locate groups for user.
+realm.loaded.successfully=SEC1115: Realm [{0}] of classtype [{1}] successfully created.
+realm.updated.successfully=SEC1117: Realm [{0}] successfully updated.
+ldaprealm.pwd.dealiasing.failed=SEC1118: Error while de-aliasing the aliased password
+
+# Audit: start at 1120
+audit.badinit=SEC1120: Error reading audit configuration.
+audit.enabled=SEC1122: Audit enabled.
+audit.string_private_audit=SEC1123: Audit: principal=
+# Note- these are partial strings, no message code.
+audit.denied= DENIED
+audit.ok= OK
+audit.methodname= method=
+audit.session= session=
+
+# Programmatic Login: start at 1130
+proglogin.noperm=SEC1130: Code does not have permission to invoke programmatic login mechanism.
+prologout.noperm=SEC1131: Code does not have permission to invoke programmatic logout mechanism.
+
+# JACC and policy: start at 1140
+policy.propoverride=SEC1140: Policy provider configuration overridden by property {0} with value {1}
+policy.nosuchname=SEC1141: Requested jacc-provider [{0}] is not configured in domain.xml.
+policy.errorreading=SEC1142: Error while reading policy-provider in domain.xml.
+policy.loading=SEC1143: Loading policy provider {0}.
+policy.installerror=SEC1144: Error while installing policy provider: 
+policy.notloading=SEC1145: No policy provider defined. Will use the default JDK Policy implementation.
+policy.factoryoverride=SEC1146: Policy configuration factory overridden by property {0} with value {1}
+policy.nofactory=SEC1147: Policy configuration factory not defined.
+policy.configure=SEC1148: Cannot load policy file for Application.
+# JMAC: start at 1200 : The JASPIC Provider Framework has some of these, need to cleanup
+jmac.unexpandedproperty=SEC1200: Unable to expand provider property value, unexpanded value passed to provider.
+jmac.loginfail=SEC1201: Login failed for user: {0}
+jmac.unsupportreadprinciple=SEC1202: No support to read Principals in SecretKeyCallback.
+jmac.factory_unable_to_load_provider=SEC1203: GFAuthConfigFactory unable to load Provider: {0}, reason: {1}
+jmac.factory_auth_config_loader_failure=SEC1204: GFAuthConfigFactory loader failure.
+jmac.factory_cannot_write_file=SEC1205: Cannot write to file {0}. Updated provider list will not be persisted.
+jmac.factory_could_not_persist=SEC1206: Could not persist updated provider list due to {0},  Will use default providers when reloaded.
+jmac.factory_could_not_read=SEC1207: Could not read auth configuration file due to {0} Will use default providers.
+jmac.factory_file_not_found=SEC1208: Configuration file does not exist at {0}. Will use default providers.
+
+# WS Security: start at 2000
+ws.error_validate_request=SEC2002: Container-auth: wss: Error validating request 
+ws.error_secure_response=SEC2003: Container-auth: wss: Error securing response 
+ws.error_secure_request=SEC2004: Container-auth: wss: Error securing request
+ws.error_validate_response=SEC2005: Container-auth: wss: Error validating response
+ws.error_not_soap=SEC2006: Container-auth: wss: Not a SOAP message context.
+
+# Existing RI: start at 5001
+java_security.unknown_credential=SEC5019:ERROR: Unknown credential provided. Class: [{0}]
+java_security.anonymous_role_reading_exception=SEC5022: Error reading anonymous role.
+java_security.gen_security_context=SEC5026: Exception generating security context 
+java_security.KeyStore_load_exception=SEC5028: Exception loading keystore
+java_security.KeyStore_store_exception=SEC5029: Exception storing keystore
+java_security.provider_exception=SEC5030: Exception loading security provider
+java_security.getName_exception=SEC5031: Exception getting security provider name 
+java_security.main_exception=SEC5032: Security main exception
+java_security.security_context_exception=SEC5036: Exception in getting security context
+java_security.default_user_login_Exception=SEC5038: Default user login exception.
+java_security.name_password_entry_exception=SEC5039: Exception entering name and password for security
+java_security.accesscontroller_action_exception=SEC5043: Exception in security accesscontroller action
+java_security.audit_auth_refused=SEC5046: Audit: Authentication refused for [{0}].
+java_security.security_context_permission_exception=SEC5048: doAsPrivileged AuthPermission required to set SecurityContext.
+java_security.security_context_unexpected_exception=SEC5049: Unexpected exception while attempting to set SecurityContext.
+java_security.security_context_nochange=SEC5050: Current Context unchanged.
+java_security.null_subject=SEC5052: null Subject used in SecurityContext construction.
+java_security.role_mapping_conflict=SEC5055: Role mapping conflicts found in application {0}. Some roles may not be mapped.
+
+java_security.init_securitylifecycle_fail=SEC5101: Fail to instantiate the SecurityLifecycle.
+
+
+# EE specific: start at 8001
+
+#ACC specific: start at 9001
+main.jmac_default_factory=SEC9001: ACC: Error in initializing JSR 196 Default Factory
+acc.secmgron=SEC9002: ACC: Security Manager is ON
+acc.secmgroff=SEC9003: ACC: Security Manager is OFF
+
+#programmatic login specific
+prog.login.failed=SEC9050: Programmatic login failed
+prog.logout.failed=SEC9051: Programmatic logout failed
+
+#ejb.security log messages
+iiop.createcontextsec_exception=IIOP1000: Exception creating ASContext
+iiop.user_password_exception=IIOP1001: Exception getting username and password
+iiop.principal_error=IIOP1002: Principal propagation: Cannot find principal information in subject
+iiop.credential_error=IIOP1003: Principal propagation: Cannot find credential information in subject.
+iiop.cannot_find_keyalias=IIOP1004: Key alias {0} not found in keystore
+iiop.Exception=IIOP1005: An exception has occured in the ejb security initialization.
+
+
+#Diagnostic messages for security/core
+
+SEC1105.diag.cause.1=PasswordCredential was required, but not supplied.
+SEC1105.diag.check.1=Please check if the password is provided
+SEC1104.diag.cause.1=Private Credentials of Subject not available
+SEC1104.diag.check.1=Please check if the private credentials are available
+SEC5028.diag.cause.1=There was an exception while loading keystore
+SEC5028.diag.check.1=Please check the if the file path and password are correct
+SEC5029.diag.cause.1=There was an exception while storing the keystore
+SEC5029.diag.check.1=Please check the if the file path and password are correct
+SEC5030.diag.cause.1=There was an exception while loading the security provider
+SEC5030.diag.check.1=Please check the if the Provider classname is correct.
+SEC5031.diag.cause.1=There was an exception while obtaining the name of the Provider.
+SEC5031.diag.check.1=Please check the if the Provider name is correct.
+SEC1114.diag.cause.1=There was an exception while installing the Policy Provider.
+SEC1114.diag.check.1=Please check the if the Policy Provider is correct
+SEC1118.diag.cause.1=There was an exception while de-aliasing the aliased password provided as the ldaprealm property.
+SEC1118.diag.check.1=Please check the if the alias and the password configured are correct
+SEC1146.diag.cause.1=Policy Configuration Factory overridden
+SEC1146.diag.check.1=Please check if the system property javax.security.jacc.PolicyConfigurationFactory.provider has not been set.
+SEC1147.diag.cause.1=Policy Configuration Factory not defined
+SEC1147.diag.check.1=Please check if the Policy Configuration Factory has been defined.
+SEC1145.diag.cause.1=No policy provider defined. Will use the default JDK Policy implementation.
+SEC1145.diag.check.1=No policy provider defined. Will use the default JDK Policy implementation.
+SEC1142.diag.cause.1=Error while reading policy-provider in domain.xml.
+SEC1142.diag.check.1=Please check if the policy provider defined is correct.
+SEC1140.diag.cause.1=Policy Provider Configuration Property is overridden by property javax.security.jacc.auth.policy.provider.
+SEC1140.diag.check.1=Policy Provider Configuration Property is overridden by property javax.security.jacc.auth.policy.provider.
+SEC1141.diag.cause.1=JaccProvider class not found for name defined.
+SEC1141.diag.check.1=Please check if the name of the Jacc provider is defined correctly.
+SEC5038.diag.cause.1=There was an exception while authenticating the default caller principal
+SEC5038.diag.check.1=There was an exception while authenticating the default caller principal
+SEC5036.diag.cause.1=There was an exception obtaining the default security context.
+SEC5036.diag.check.1=There was an exception obtaining the default security context.
+SEC5048.diag.cause.1=AuthPermission required to set SecurityContext,
+SEC5048.diag.check.1=AuthPermission required to set SecurityContext,
+SEC5049.diag.cause.1=There was an unexpected exception while setting the security context
+SEC5049.diag.check.1=There was an unexpected exception while setting the security context
+SEC5039.diag.cause.1=An exception occurred while processing username and password for security
+SEC5039.diag.check.1=An exception occurred while processing username and password for security
+SEC5055.diag.cause.1=Principal-Group-Role Mapping conflicts in the application
+SEC5055.diag.check.1=Please check if the roles have been mapped to the same principals/groups consistently in all the descriptors.
+SEC1103.diag.cause.1=The Realm configured is not an instance of CertificateRealm, Certificate authentication requires certificate realm. 
+SEC1103.diag.check.1=Please check if the realm class is an instance of CertificateRealm
+SEC1112.diag.cause.1=Cannot obtain the password for the user provided.
+SEC1112.diag.check.1=Please check the JDBC configuration, encoding algorithm and the password for the user.
+SEC1111.diag.cause.1=Exception while obtaining groups for the users.
+SEC1111.diag.check.1=Please check the JDBC configuration, encoding algorithm and the groups for the user.
+SEC5043.diag.cause.1=Exception while extracting username and realm from the subject post login
+SEC5043.diag.check.1=Exception while extracting username and realm from the subject post login
+SEC1130.diag.cause.1=Code does not have permission to invoke programmatic login mechanism.
+SEC1130.diag.check.1=Code does not have permission to invoke programmatic login mechanism.
+SEC1103.diag.cause.1=No AuthenticationHandler available for this realm.
+SEC1103.diag.check.1=Check of the Realm has been configured correctly. This is the base class method that has to be overridden
+SEC1110.diag.cause.1=JAAS context requested from certificate realm. 
+SEC1110.diag.check.1=Certificate Realm does not have a JAAS context. Please check the configuration
+SEC1109.diag.cause.1=Error reading keyfile of filerealm
+SEC1109.diag.check.1=Please check if the keyfile for the filerealm is configured correctly and is in place.
+SEC1000.diag.cause.1=A Security Exception has been  thrown
+SEC1000.diag.check.1=A Security Exception has been  thrown
+SEC1106.diag.cause.1=Error during LDAP search
+SEC1106.diag.check.1=Please check the LDAP configuration
+SEC1102.diag.cause.1=Error during SolarisRealm initialization. LoginModule not specified
+SEC1102.diag.check.1=Please provide the jaas-context in the SolarisRealm configuration
+SEC1203.diag.cause.1=Error while loading ConfigProvider.
+SEC1203.diag.check.1=Please check if the configprovider has been configured correctly.
+SEC1204.diag.cause.1=Error while loading the persisted entries of GFAuthConfigFactory
+SEC1204.diag.check.1=Error while loading the persisted entries of GFAuthConfigFactory
+SEC1207.diag.cause.1=Could not read auth configuration file. The default provider will be used.
+SEC1207.diag.check.1=Could not read auth configuration file. The default provider will be used.
+SEC1206.diag.cause.1=Could not persist updated provider list due to {0}. Will use default providers when reloaded.
+SEC1206.diag.check.1=Could not persist updated provider list due to {0}. Will use default providers when reloaded.
+SEC1205.diag.cause.1=Cannot write to file. Updated provider list will not be persisted.
+SEC1205.diag.check.1=Cannot write to file. Updated provider list will not be persisted.
+SEC1003.diag.cause.1=Could not override SecurityManager.
+SEC1003.diag.check.1=Could not override SecurityManager.
+SEC9001.diag.cause.1=GFAuthConfigFactory not in classpath or not enough permissions to call Security.setProperty
+SEC9001.diag.check.1=Please check if appclient classpath has GFAuthConfigFactory class and ensure required permissions are given.
+SEC1114.diag.cause.1=Invalid user or improper LDAPRealm configuration
+SEC1114.diag.check.1=Check the LDAPRealm Configuration in GlassFish.
+
+SEC9050.diag.cause.1=Check the exception stack-trace for more details
+SEC9050.diag.check.1=Check if the credential username/password/certificate was a valid one
+SEC9051.diag.cause.1=Check the exception stack-trace for more details
+SEC9051.diag.check.1=Check the exception stack-trace, could be an internal server error or a bug.
+
+
+#ejb.security Diagnostic messages
+
+IIOP1000.diag.cause.1=An error occured while creating the ASContext or SASContext
+IIOP1000.diag.check.1=Please check the values provided in the descriptor for the IOR security config
+IIOP1001.diag.cause.1=An exception occured while obtaining the username and password
+IIOP1001.diag.check.1=Please check the username and password provided
+IIOP1002.diag.cause.1=The principal information is not found in the subject
+IIOP1002.diag.check.1=Please check the config settings for identity propagation
+IIOP1003.diag.cause.1=Credential information is not found in the subject
+IIOP1003.diag.check.1=Please check the config settings for identity propogation
+IIOP1004.diag.cause.1=Alias key is not found in the keystore
+IIOP1004.diag.check.1=Please check the if the name of the alias is right and of the keystore contains the key of the alias
+IIOP1005.diag.cause.1=An Exception has occured in the ejb security initialization
+IIOP1005.diag.check.1=Please check the if the IOR security configuration of the ejb is correct
+
+
diff --git a/nucleus/security/core/src/main/resources/config/admin-keyfile b/nucleus/security/core/src/main/resources/config/admin-keyfile
new file mode 100644
index 0000000..785d8c5
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/config/admin-keyfile
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+
+anonymous;{SSHA}w9WBMj/jphXlgDWPgozFSSzUgy5Fd/ONd7nPtw==;asadmin
+
+# Domain User and Password - Do Not Delete Entry Above
diff --git a/nucleus/security/core/src/main/resources/config/cacerts.jks b/nucleus/security/core/src/main/resources/config/cacerts.jks
new file mode 100644
index 0000000..5349943
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/config/cacerts.jks
Binary files differ
diff --git a/nucleus/security/core/src/main/resources/config/javaee.server.policy b/nucleus/security/core/src/main/resources/config/javaee.server.policy
new file mode 100644
index 0000000..5834a07
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/config/javaee.server.policy
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+// App-client EE permissions
+grant codebase "file:/module/Car" {
+
+    permission java.awt.AWTPermission "accessClipboard";
+    permission java.awt.AWTPermission "accessEventQueue";
+    permission java.awt.AWTPermission "showWindowWithoutWarningBanner";
+
+    permission java.lang.RuntimePermission "loadLibrary.*";
+    permission java.lang.RuntimePermission "exitVM";
+    permission java.lang.RuntimePermission "queuePrintJob";
+
+    permission java.net.SocketPermission "*", "connect"; 
+    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.io.FilePermission "<<ALL FILES>>", "read,write";
+    permission java.util.PropertyPermission "*", "read";
+
+};
+
+// Applet-client EE permissions
+grant codebase "file:/module/Applet-Client" {
+
+    permission java.net.SocketPermission "*", "connect"; 
+    permission java.util.PropertyPermission "*", "read";
+  
+};
+
+
+// EJB EE permissions
+grant codebase "file:/module/Ejb" {
+    permission java.lang.RuntimePermission "loadLibrary"; 
+    permission java.lang.RuntimePermission "queuePrintJob"; 
+    permission java.net.SocketPermission "*", "connect"; 
+    permission java.io.FilePermission "*", "read,write";
+    permission java.util.PropertyPermission "*", "read";
+};
+
+
+// Web EE permissions
+grant codebase "file:/module/Web" {
+    permission java.lang.RuntimePermission "loadLibrary"; 
+    permission java.lang.RuntimePermission "queuePrintJob"; 
+    permission java.net.SocketPermission "*", "connect";
+    permission java.io.FilePermission "*", "read,write"; 
+    permission java.io.FilePermission "SERVLET-CONTEXT-TEMPDIR", "read,write";
+    permission java.util.PropertyPermission "*", "read";
+};
+
+// Resource adapter EE permissions
+grant codebase "file:/module/Rar" {
+    permission java.lang.RuntimePermission "loadLibrary"; 
+    permission java.lang.RuntimePermission "queuePrintJob"; 
+    permission java.net.SocketPermission "*", "connect"; 
+    permission java.io.FilePermission "*", "read,write";
+    permission java.util.PropertyPermission "*", "read";
+};
diff --git a/nucleus/security/core/src/main/resources/config/keyfile b/nucleus/security/core/src/main/resources/config/keyfile
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/config/keyfile
diff --git a/nucleus/security/core/src/main/resources/config/keystore.jks b/nucleus/security/core/src/main/resources/config/keystore.jks
new file mode 100644
index 0000000..33a95a0
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/config/keystore.jks
Binary files differ
diff --git a/nucleus/security/core/src/main/resources/config/login.conf b/nucleus/security/core/src/main/resources/config/login.conf
new file mode 100644
index 0000000..c81d5ba
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/config/login.conf
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2004, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+fileRealm {
+	com.sun.enterprise.security.auth.login.FileLoginModule required;
+};
+
+ldapRealm {
+	com.sun.enterprise.security.auth.login.LDAPLoginModule required;
+};
+
+solarisRealm {
+	com.sun.enterprise.security.auth.login.SolarisLoginModule required;
+};
+
+jdbcRealm {
+	com.sun.enterprise.security.ee.auth.login.JDBCLoginModule required;
+};
+jdbcDigestRealm {
+       com.sun.enterprise.security.ee.auth.login.JDBCDigestLoginModule required;
+};
+pamRealm {
+        com.sun.enterprise.security.auth.login.PamLoginModule required;
+};
+ 
diff --git a/nucleus/security/core/src/main/resources/config/restrict.server.policy b/nucleus/security/core/src/main/resources/config/restrict.server.policy
new file mode 100644
index 0000000..6d103f4
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/config/restrict.server.policy
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+// EJB default restricted permissions
+grant codebase "file:/module/Ejb" {
+    //following restricts the use of 'java.security.AllPermission' in permissions.xml
+    permission com.sun.enterprise.security.perms.VoidPermission;
+};
+
+// Web App default restricted permissions
+grant codebase "file:/module/Web" {
+    //following restricts the use of 'java.security.AllPermission' in permissions.xml
+    permission com.sun.enterprise.security.perms.VoidPermission;
+};
+
+// Connector default restricted permissions
+grant codebase "file:/module/Rar" {
+    //following restricts the use of 'java.security.AllPermission' in permissions.xml
+    permission com.sun.enterprise.security.perms.VoidPermission;
+};
+
+
+// App client default restricted permissions
+grant codebase "file:/module/Car" {
+    //following restricts the use of 'java.security.AllPermission' in permissions.xml
+    permission com.sun.enterprise.security.perms.VoidPermission;
+};
+
+
diff --git a/nucleus/security/core/src/main/resources/config/server.policy b/nucleus/security/core/src/main/resources/config/server.policy
new file mode 100644
index 0000000..4bceff9
--- /dev/null
+++ b/nucleus/security/core/src/main/resources/config/server.policy
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2004, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+// classes in lib get all permissions by default
+grant codeBase "file:${com.sun.aas.installRoot}/lib/-" {
+    permission java.security.AllPermission;
+};
+
+// Core server classes get all permissions by default
+grant codeBase "file:${com.sun.aas.installRoot}/modules/-" {
+    permission java.security.AllPermission;
+};
+
+// Felix classes get all permissions by default
+grant codeBase "file:${com.sun.aas.installRoot}/osgi/felix/bin/-" {
+    permission java.security.AllPermission;
+};
+
+// iMQ classes get all permissions by default
+grant codeBase "file:${com.sun.aas.imqLib}/-" {
+    permission java.security.AllPermission;
+};
+
+// Derby driver classes get all permissions by default
+grant codeBase "file:${com.sun.aas.derbyRoot}/lib/-" {
+    permission java.lang.RuntimePermission "createClassLoader";
+    permission java.io.FilePermission       "<<ALL FILES>>", "read,write";
+}; 
+
+
+// permission for JDK's tools.jar to enable webservice annotation processing
+// at runtime by wsgen tool: 
+//       permission java.lang.RuntimePermission "createClassLoader";
+//
+// permission for JDK's tools.jar to sign JARs at runtime for 
+// Java Web Start support:
+//       permissions java.security.AllPermission;
+// on the advice of the JDK tools folks.  Should be refined later.
+//Bug Glassfish-21012 - changing to the right location of tools.jar
+grant codeBase "file:${com.sun.aas.javaRoot}/../lib/tools.jar" {
+    permission java.security.AllPermission;
+};
+
+//Loading MBeans from anywhere, to take care of side effects of 6235678.
+grant {
+    permission javax.management.MBeanTrustPermission "register" ;
+};
+//Loading MBeans from anywhere, to take care of side effects of 6235678.
+
+
+// Basic set of required permissions granted to all remaining code
+// The permission FilePermission "<<ALL FILES>>", "read,write"
+// allows all applications to read and write any file in the filesystem.
+// It should be changed based on real deployment needs. If you know your
+// applications just need to read/write a few directories consider removing
+// this permission and adding grants indicating those specific directories.
+// against the codebase of your application(s).
+grant {
+    //Workaround for bugs #6484935, 6513799
+    permission java.lang.RuntimePermission "getProtectionDomain";
+    permission com.sun.corba.ee.impl.presentation.rmi.DynamicAccessPermission "access";
+    permission java.util.PropertyPermission "*", "read,write";
+
+    permission java.lang.RuntimePermission  "loadLibrary.*";
+    permission java.lang.RuntimePermission  "queuePrintJob";
+    permission java.net.SocketPermission    "*", "connect";
+
+        // work-around for pointbase bug 4864405      
+        permission java.io.FilePermission "${com.sun.aas.instanceRoot}${/}lib${/}databases${/}-", "delete";
+        permission java.io.FilePermission "${java.io.tmpdir}${/}-", "delete";
+
+    permission java.util.PropertyPermission "*", "read";
+
+    permission java.lang.RuntimePermission    "modifyThreadGroup";
+    permission java.lang.RuntimePermission    "getClassLoader";
+    permission java.lang.RuntimePermission    "setContextClassLoader";
+        permission javax.management.MBeanPermission "[com.sun.messaging.jms.*:*]", "*"; 
+
+    // Following needed for CTS to pass with SM on, bug 16344201
+    permission java.lang.RuntimePermission "closeClassLoader";
+    permission java.io.SerializablePermission "enableSubstitution";
+    permission java.security.SecurityPermission "getProperty.package.definition";
+
+};
+
+
+// Following grant block is only required by Connectors. If Connectors
+// are not in use the recommendation is to remove this grant.
+grant {
+        permission javax.security.auth.PrivateCredentialPermission "javax.resource.spi.security.PasswordCredential * \"*\"","read";
+};
+
+// Following grant block is only required for Reflection. If Reflection
+// is not in use the recommendation is to remove this section.
+grant {
+    permission java.lang.RuntimePermission "accessDeclaredMembers";
+};
+
+// Permissions to invoke CORBA objects in server
+grant {
+    permission com.sun.enterprise.security.CORBAObjectPermission "*", "*";
+};
+
+    // GLASSFISH-21011
+grant {
+    permission java.io.SerializablePermission "enableSubclassImplementation";
+};
+
+grant  codeBase "file:${com.sun.aas.instanceRoot}/applications/-"{
+    permission java.io.FilePermission       "<<ALL FILES>>", "read,write";
+}; 
diff --git a/nucleus/security/pom.xml b/nucleus/security/pom.xml
new file mode 100644
index 0000000..00ffac6
--- /dev/null
+++ b/nucleus/security/pom.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.glassfish.main</groupId>
+        <artifactId>glassfish-nucleus-parent</artifactId>
+        <version>5.0.1-SNAPSHOT</version>
+    </parent>
+    <groupId>org.glassfish.main.security</groupId>
+    <artifactId>nucleus-security</artifactId>
+    <packaging>pom</packaging>
+    <name>Nucleus Security Parent</name>
+    <description>Security Infrastructure and Technology Integration Modules</description>  
+    <modules>
+        <module>core</module>
+        <module>ssl-impl</module>
+        <module>services</module>
+  </modules>
+</project>
diff --git a/nucleus/security/services/osgi.bundle b/nucleus/security/services/osgi.bundle
new file mode 100644
index 0000000..4c88d91
--- /dev/null
+++ b/nucleus/security/services/osgi.bundle
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+-exportcontents: \
+                        org.glassfish.security.services.api; \
+                        org.glassfish.security.services.api.authentication; \
+                        org.glassfish.security.services.api.authorization; \
+                        org.glassfish.security.services.api.common; \
+                        org.glassfish.security.services.api.context; \
+                        org.glassfish.security.services.spi; \
+                        org.glassfish.security.services.spi.authentication; \
+                        org.glassfish.security.services.spi.authorization; \
+                        org.glassfish.security.services.common; \
+                        org.glassfish.security.services.commands; \
+                        org.glassfish.security.services.impl; \
+                        org.glassfish.security.services.impl.common; \
+                        org.glassfish.security.services.impl.authorization; \
+                        org.glassfish.security.services.provider.authorization; \
+                        org.glassfish.security.services.config; version=${project.osgi.version}
diff --git a/nucleus/security/services/pom.xml b/nucleus/security/services/pom.xml
new file mode 100644
index 0000000..9a9030c
--- /dev/null
+++ b/nucleus/security/services/pom.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.glassfish.main.security</groupId>
+        <artifactId>nucleus-security</artifactId>
+        <version>5.0.1-SNAPSHOT</version>
+    </parent>
+    <artifactId>security-services</artifactId>
+    <packaging>glassfish-jar</packaging>
+    
+    <name>Security Services and SPI</name>
+
+    <build>
+        <plugins>
+            <!-- JDK 8u171+, PasswordAliasTest fails due to serialization issue
+                 Using forked process helps the tests to pass -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <forkMode>always</forkMode>
+                </configuration>
+            </plugin>
+          </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.hk2</groupId>
+            <artifactId>hk2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.hk2</groupId>
+            <artifactId>hk2-junitrunner</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.admin</groupId>
+            <artifactId>config-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>common-util</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>internal-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>glassfish-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.security</groupId>
+            <artifactId>security</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.annotations</groupId>
+            <artifactId>logging-annotation-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/SecurityService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/SecurityService.java
new file mode 100644
index 0000000..7b409eb
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/SecurityService.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api;
+
+import org.glassfish.security.services.config.SecurityConfiguration;
+
+/**
+ * Base interface used by all security services.
+ */
+public interface SecurityService {
+    /**
+     * Initialize the security service instance with the specific security service configuration.
+     */
+    public void initialize(SecurityConfiguration securityServiceConfiguration);
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authentication/AbstractInternalSystemAdministrator.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authentication/AbstractInternalSystemAdministrator.java
new file mode 100644
index 0000000..ff0b1df
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authentication/AbstractInternalSystemAdministrator.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authentication;
+
+import javax.inject.Inject;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+import org.glassfish.hk2.api.PostConstruct;
+import org.glassfish.internal.api.InternalSystemAdministrator;
+
+/**
+ * Implements most of the internal system administrator.
+ * <p>
+ * Different concrete subclasses implement {@link #getAdminGroupName() }
+ * and {@link #getInternalUsername() } and {@link #createSubject() } differently.
+ * 
+ * @author tjquinn
+ */
+public abstract class AbstractInternalSystemAdministrator implements InternalSystemAdministrator, PostConstruct {
+    
+    private Subject subject;
+    
+    @Inject
+    private AuthenticationService authService;
+    
+    @Override
+    public void postConstruct() {
+        subject = createSubject();
+    }
+
+    @Override
+    public Subject getSubject() {
+        return subject;
+    }
+    
+    /**
+     * Creates a subject using the impersonate method on the authentication
+     * service.
+     * 
+     * @return the Subject to use for the internal system administrator.
+     */
+    protected Subject createSubject() {
+        Subject s;
+        try {
+            s = authService.impersonate(
+                    getInternalUsername(), 
+                    new String[] {getAdminGroupName()}, 
+                    null /* no pre-existing subject */,
+                    true /* isVirtual */);
+            return s;
+        } catch (LoginException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+    
+    abstract protected String getInternalUsername();
+    
+    abstract protected String getAdminGroupName();
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authentication/AuthenticationService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authentication/AuthenticationService.java
new file mode 100644
index 0000000..cd4dd9e
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authentication/AuthenticationService.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authentication;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+
+import org.jvnet.hk2.annotations.Contract;
+
+import org.glassfish.security.services.api.SecurityService;
+
+/**
+ * The AuthenticationService provides basic authentication functions.
+ * Consumers of the service must establish Subjects in any security context.
+ */
+@Contract
+public interface AuthenticationService extends SecurityService {
+    /**
+     * Log in a user with username and password.
+     * 
+     * @param username The username.
+     * @param password The password.
+     * @param subject An optional Subject to receive principals and credentials for the logged in user.
+     * If provided, it will be returned as the return value; if not, a new Subject will be returned.
+     * 
+     * @return A Subject representing the logged in user.
+     * 
+     * @throws LoginException
+     */
+    public Subject login(String username, char[] password, Subject subject)
+            throws LoginException;
+
+    /**
+     * Authenticate using a CallbackHandler to provider username/password, X.509 certificate, or
+     * Secure Admin token.
+     * 
+     * @param cbh  The CallbackHandler.
+     * @param subject An optional Subject to receive principals and credentials for the logged in user.
+     * If provided, it will be returned as the return value; if not, a new Subject will be returned.
+     * 
+     * @return A Subject representing the logged in user.
+     * 
+     * @throws LoginException
+     */
+    public Subject login(CallbackHandler cbh, Subject subject) throws LoginException;
+
+    /**
+     * Impersonate a user, specifying the user and group principal names that
+     * should be established in the resulting Subject.
+     * 
+     * Note that, that this method always behaves as if <bold>virtual</bold> were true in the case
+     * that the underlying user store provider does not support user lookup.
+     * 
+     * @param user The username.
+     * @param groups An array of group names.  If <bold>virtual</bold> is true, group principals will be created
+     * using this array.  If <bold>virtual</bold> is false and groups is non-null, it will be used to filter the
+     * groups returned by the configured UserStoreProvider.
+     * @param subject An optional Subject to receive principals and credentials for the logged in user.
+     * If provided, it will be returned as the return value; if not, a new Subject will be returned.
+     * @param virtual  If true, simply create a subject with the given user and group names.  If false, configured
+     * UserStoreProvider will be queried for the given username and a Subject created only if the user exists.  Groups
+     * will be populated with the intersection of the groups parameter and the groups returned by the UserStoreProvider.
+     * 
+     * @return A Subject representing the impersonated user.
+     * 
+     * @throws LoginException
+     */
+    public Subject impersonate(String user, String[] groups, Subject subject, boolean virtual)
+            throws LoginException;
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authentication/ImpersonationService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authentication/ImpersonationService.java
new file mode 100644
index 0000000..6625d93
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authentication/ImpersonationService.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authentication;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
+import org.jvnet.hk2.annotations.Contract;
+
+/**
+ * The Impersonation Service
+ */
+@Contract
+public interface ImpersonationService {
+    /**
+     * Impersonate a user, specifying the user and group principal names that
+     * should be established in the resulting Subject.
+     * 
+     * Note that, that this method always behaves as if <bold>virtual</bold> were true in the case
+     * that the underlying user store provider does not support user lookup.
+     * 
+     * @param user The username.
+     * @param groups An array of group names.  If <bold>virtual</bold> is true, group principals will be created
+     * using this array.  If <bold>virtual</bold> is false and groups is non-null, it will be used to filter the
+     * groups returned by the configured UserStoreProvider.
+     * @param subject An optional Subject to receive principals and credentials for the logged in user.
+     * If provided, it will be returned as the return value; if not, a new Subject will be returned.
+     * @param virtual  If true, simply create a subject with the given user and group names.  If false, configured
+     * UserStoreProvider will be queried for the given username and a Subject created only if the user exists.  Groups
+     * will be populated with the intersection of the groups parameter and the groups returned by the UserStoreProvider.
+     * 
+     * @return A Subject representing the impersonated user.
+     * 
+     * @throws LoginException
+     */
+    public Subject impersonate(String user, String[] groups, Subject subject, boolean virtual)
+            throws LoginException;
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AuthorizationAdminConstants.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AuthorizationAdminConstants.java
new file mode 100644
index 0000000..1e21993
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AuthorizationAdminConstants.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Common attribute names, used in authorization and set by code using
+ * the authorization service.
+ * 
+ * @author tjquinn
+ */
+public interface AuthorizationAdminConstants {
+    public final static String ISDAS_ATTRIBUTE = "isDAS";
+    
+    public final static String ADMIN_TOKEN = "adminToken";
+    public final static String REST_TOKEN = "restToken";
+    public final static String LOCAL_PASSWORD = "localPassword";
+    public final static String SERVER = "server";
+    
+    /*
+     * The presence of either of these attributes means the associated
+     * subject is not linked to a specific admin user but was authenticated
+     * as trustworthy in some other way.
+     */
+    public final static Set<String> TRUSTED_FOR_DAS_OR_INSTANCE =
+            Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(LOCAL_PASSWORD, SERVER)));
+    
+    public final static String ADMIN_GROUP = "asadmin"; // must match with value in admin/util module's AdminConstants class
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AuthorizationService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AuthorizationService.java
new file mode 100755
index 0000000..2feb85a
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AuthorizationService.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+
+import java.net.URI;
+import java.security.Permission;
+import java.util.List;
+import javax.security.auth.Subject;
+
+import org.glassfish.security.services.api.SecurityService;
+import org.jvnet.hk2.annotations.Contract;
+
+/**
+ * The <code>AuthorizationService</code> interface provides methods that allow server and container
+ * to determine whether access should be allowed to a particular resource.  It is intended for
+ * internal use, not for use by applications.
+ */
+@Contract
+public interface AuthorizationService extends SecurityService {
+	
+	/**
+	 * Determines whether the given Subject has been granted the specified Permission
+	 * by delegating to the configured java.security.Policy object.  This method is
+	 * a high-level convenience method that tests for a Subject-based permission
+	 * grant without reference to the AccessControlContext of the caller.
+	 * 
+	 * In addition, this method isolates the query from the underlying Policy configuration
+	 * model.  It could, for example, multiplex queries across multiple instances of Policy
+	 * configured in an implementation-specific way such that different threads, or different
+	 * applications, query different Policy objects.  The initial implementation simply
+	 * delegates to the configured Policy as defined by Java SE.
+	 * 
+	 * @param subject The Subject for which permission is being tested.
+	 * @param permission The Permission being queried.
+	 * @return True or false, depending on whether the specified Permission
+	 * is granted to the Subject by the configured Policy.
+     * @throws IllegalArgumentException Given null or illegal subject or permission
+	 */
+	public boolean isPermissionGranted(Subject subject, Permission permission);
+	
+	/**
+	 * Determines whether the given Subject is authorized to access the given resource,
+	 * specified by a URI.
+	 * 
+	 * @param subject The Subject being tested.
+	 * @param resource URI of the resource being tested.
+	 * @return True or false, depending on whether the access is authorized.
+     * @throws IllegalArgumentException Given null or illegal subject or resource
+     * @throws IllegalStateException Service was not initialized.
+     */
+	public boolean isAuthorized(Subject subject, URI resource);
+	
+	/**
+	 * Determines whether the given Subject is authorized to access the given resource,
+	 * specified by a URI.
+	 * 
+	 * @param subject The Subject being tested.
+	 * @param resource URI of the resource being tested.
+	 * @param action The action, with respect to the resource parameter,
+	 * for which authorization is desired. To check authorization for all actions,
+     * action is represented by null or "*".
+	 * @return True or false, depending on whether the access is authorized.
+     * @throws IllegalArgumentException Given null or illegal subject or resource
+     * @throws IllegalStateException Service was not initialized.
+     */
+	public boolean isAuthorized(Subject subject, URI resource, String action);
+
+	/**
+	 * The primary authorization method.  The isAuthorized() methods call this method
+	 * after converting their arguments into the appropriate attribute collection type.
+	 * It returns a full AzResult, including authorization status, decision, and
+	 * obligations.
+	 * 
+	 * This method performs two steps prior to invoking the configured AuthorizationProvider
+	 * to evaluate the request:  First, it acquires the current AzEnvironment attributes by
+	 * calling the Security Context service.  Second, it calls the Role Mapping service to
+	 * determine which roles the subject has, and adds the resulting role attributes into
+	 * the AzSubject.
+	 * 
+	 * @param subject The attributes collection representing the Subject for which an authorization
+	 * decision is requested.
+	 * @param resource The attributes collection representing the resource for which access is
+	 * being requested.
+	 * @param action  The attributes collection representing the action, with respect to the resource,
+	 * for which access is being requested.  A null action is interpreted as all
+     * actions, however all actions may also be represented by the AzAction instance.
+     * See <code>{@link org.glassfish.security.services.api.authorization.AzAction}</code>.
+	 * @return The AzResult indicating the result of the access decision.
+     * @throws IllegalArgumentException Given null or illegal subject or resource
+     * @throws IllegalStateException Service was not initialized.
+     */
+	public AzResult getAuthorizationDecision(AzSubject subject, AzResource resource, AzAction action);
+	
+	/**
+	 * Converts a Java Subject into a typed attributes collection.
+	 * 
+	 * @param subject The Subject to convert.
+	 * @return The resulting AzSubject.
+     * @throws IllegalArgumentException Given null or illegal subject
+     */
+	public AzSubject makeAzSubject(Subject subject);
+
+    /**
+     * Converts a resource, expressed as a URI, into a typed attributes collection.
+     * <p>
+     * Query parameters in the given URI are appended to this
+     * <code>AzResource</code> instance attributes collection.
+     *
+     * @param resource The URI to convert.
+     * @return The resulting AzResource.
+     * @throws IllegalArgumentException Given null or illegal resource
+     */
+	public AzResource makeAzResource(URI resource);
+	
+	/**
+	 * Converts an action, expressed as a String, into a typed attributes collection.
+	 * 
+	 * @param action The action to convert. null or "*" represents all actions.
+	 * @return The resulting AzAction.
+	 */
+	public AzAction makeAzAction(String action);
+
+    // TODO: What if multiple providers? Rollback/closeWithoutChange? Would delete remove an existing PolicyDeploymentContext?
+    /**
+	 * Finds an existing PolicyDeploymentContext, or create a new one if one does not
+	 * already exist for the specified appContext.  The context will be returned in
+	 * an "open" state, and will stay that way until commit() or delete() is called.
+	 * 
+	 * @param appContext The application context for which the PolicyDeploymentContext
+	 * is desired.
+	 * @return The resulting PolicyDeploymentContext,
+     * null if the configured providers do not support this feature.
+     * @throws IllegalStateException Service was not initialized.
+     */
+	public PolicyDeploymentContext findOrCreateDeploymentContext(String appContext);
+	
+	/**
+	 * This interface represents a PolicyDeploymentContext as returned by the Authorization
+	 * Service's findOrCreateDeploymentContext() method.  The PolicyDeploymentContext is used
+	 * to configure authorization policy for an application (or server administration) context.
+	 * It represents the body of policy that applies to the given context.
+	 * 
+	 * A PolicyDeploymentContext is always in one of three states: open, closed/inService,
+	 * or deleted.  When returned by the Authorization service, a context is in an open state.
+	 * Policies can be added or deleted while in the open state, but the context is not
+	 * in service.  Upon calling commit(), the context is closed and the policies are place
+	 * in service.  Upon calling delete(), the context is taken out of service and the policies
+	 * are deleted from the Authorization Provider.
+	 */
+	public interface PolicyDeploymentContext {
+		
+		public void addRolePolicy(String role, String resource, String action);
+
+		public void addUncheckedPolicy(String resource, String action);
+
+		public void addExcludedPolicy(String resource, String action);
+		
+		public void removeRolePolicy(String role);
+		
+		public void removeRolePolicies();
+		
+		public void removeUncheckedPolicies();
+		
+		public void removeExcludedPolicies();
+		
+		public void commit();
+		
+		public void delete();
+	}
+
+
+    /**
+     * Appends the given <code>{@link org.glassfish.security.services.api.authorization.AzAttributeResolver}</code>
+     * instance to the internal ordered list of <code>AzAttributeResolver</code> instances,
+     * if not currently in the list based on
+     * <code>{@link org.glassfish.security.services.api.authorization.AzAttributeResolver#equals}</code>.
+     *
+     * @param resolver The <code>AzAttributeResolver</code> instance to append.
+     * @return true if the <code>AzAttributeResolver</code> was added,
+     * false if the <code>AzAttributeResolver</code> was already in the list.
+     * @throws IllegalArgumentException Given AzAttributeResolver was null.
+     */
+    public boolean appendAttributeResolver(AzAttributeResolver resolver);
+
+
+    /**
+     * Replaces the internal list of <code>AttributeResolver</code> instances
+     * with the given list. If multiple equivalent instances exist in the given list,
+     * only the first such instance will be inserted.
+     *
+     * @param resolverList Replacement list of <code>AzAttributeResolver</code> instances
+     * @throws IllegalArgumentException Given AzAttributeResolver list was null.
+     */
+    public void setAttributeResolvers(List<AzAttributeResolver> resolverList);
+
+
+    /**
+     * Determines the current list of <code>AttributeResolver</code> instances,
+     * in execution order.
+     *
+     * @return  The current list of AttributeResolver instances,
+     * in execution order.
+     */
+    public List<AzAttributeResolver> getAttributeResolvers();
+
+
+    /**
+     * Removes all <code>AttributeResolver</code> instances from the current
+     * internal list of <code>AttributeResolver</code> instances.
+     *
+     * @return true if any <code>AttributeResolver</code> instances were removed,
+     * false if the list was empty.
+     */
+    public boolean removeAllAttributeResolvers();
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzAction.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzAction.java
new file mode 100755
index 0000000..b033580
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzAction.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+
+/**
+ * Extends the AzAttributes interface to provide a type-safe interface for Action attributes.
+ */
+public interface AzAction extends AzAttributes {
+
+    /**
+     * The name of this collection. For example, this name may be used to
+     * qualify attributes by collection type in XACML.
+     */
+    String NAME = "ACTION";
+
+    /**
+     * Determines the action represented as a string.
+     * @return The represented action, null represents all actions
+     */
+    String getAction();
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzAttributeResolver.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzAttributeResolver.java
new file mode 100755
index 0000000..55f8545
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzAttributeResolver.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+
+import org.glassfish.security.services.api.common.Attribute;
+
+
+/**
+ * <code>AzAttributeResolver</code> provides runtime resolution of attributes.
+ * <p>
+ * This is used to obtain attribute values which are not available in the
+ * corresponding AzAttributes collection. Implementations may obtain
+ * the attribute values from arbitrary sources, including
+ * calculation or from remote servers. Since
+ * an <code>AzAttributeResolver</code> may be called frequently during time-
+ * sensitive operations, caching and other performance-enhancing techniques
+ * should be used by the implementation.
+ */
+
+public interface AzAttributeResolver {
+
+    /**
+     * Resolves the specified attribute.
+     *
+     * @param attributeName The attribute to resolve.
+     * @param collection The read-only collection within which the attribute resides.
+     * @param environment The read-only operational context
+     * @return The resolved attribute, null if unresolvable.
+     */
+    public Attribute resolve(
+        String attributeName,
+        AzAttributes collection,
+        AzEnvironment environment );
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzAttributes.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzAttributes.java
new file mode 100755
index 0000000..f8d27ee
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzAttributes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+
+import org.glassfish.security.services.api.common.Attributes;
+
+/**
+ * Extends the Attributes interface to provide an abstract layer
+ * specifically for Authorization attributes.
+ */
+public interface AzAttributes extends Attributes {
+
+    /**
+     * Determines a name to denote this collection of attributes.
+     * <p>
+     * For example, this name may be used to qualify attributes by collection
+     * type in XACML.
+     *
+     * @return The collection name
+     */
+    String getName();
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzEnvironment.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzEnvironment.java
new file mode 100755
index 0000000..790ae98
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzEnvironment.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+
+/**
+ * Extends the AzAttributes interface to provide a type-safe interface for Environment attributes.
+ */
+public interface AzEnvironment extends AzAttributes {
+
+    /**
+     * The name of this collection. For example, this name may be used to
+     * qualify attributes by collection type in XACML.
+     */
+    String NAME = "ENVIRONMENT";
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzObligations.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzObligations.java
new file mode 100755
index 0000000..de2784e
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzObligations.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+
+/**
+ * Extends the AzAttributes interface to provide a type-safe interface for Obligations attributes.
+ */
+public interface AzObligations extends AzAttributes {
+
+    /**
+     * The name of this collection. For example, this name may be used to
+     * qualify attributes by collection type in XACML.
+     */
+    String NAME = "OBLIGATIONS";
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzResource.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzResource.java
new file mode 100755
index 0000000..e5ad1d0
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzResource.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+
+import java.net.URI;
+
+/**
+ * Extends the AzAttributes interface to provide a type-safe interface for Resource attributes.
+ */
+public interface AzResource extends AzAttributes {
+
+    /**
+     * The name of this collection. For example, this name may be used to
+     * qualify attributes by collection type in XACML.
+     */
+    String NAME = "RESOURCE";
+
+
+    /**
+     * Determines the URI representing this resource.
+     * @return The URI representing this resource, never null.
+     */
+    public URI getUri();
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzResult.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzResult.java
new file mode 100755
index 0000000..d844493
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzResult.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+
+/**
+ * The AzResult class represents the result of an authorization decision.  The result includes three distinct results:
+ * A result status, which indicates whether the call was successful or not, and may indicate a reason for a failed call;
+ * an authorization decision, which is valid only if the status is "OK", and obligations, which represent actions the
+ * calling code must take if it proceeds to access the resource in question.  Obligations are expressed as attributes;
+ * the meaning of any specific obligation is established by an out-of-band agreement between the PDP and the PEP.
+ */
+public interface AzResult {
+	
+	/**
+	 * The possible authorization decision values.  These carry the same meaning as the corresponding
+	 * decision values defined by XACML 2.0 and later.
+	 */
+	public enum Decision { PERMIT, DENY, INDETERMINATE, NOT_APPLICABLE };
+	/**
+	 * The possible authorization status values.  These carry the same meaning as the corresponding
+	 * status values defined by XACML 2.0 and later.
+	 */
+	public enum Status { OK, MISSING_ATTRIBUTE, PROCESSING_ERROR, SYNTAX_ERROR };
+	
+	/**
+	 * Get the authorization decision value for this AzResult.
+	 * 
+	 * @return The Decision value.
+	 */
+	public Decision getDecision();
+	
+	/**
+	 * Get the authorization status value for this AzResult.
+	 * 
+	 * @return The Status value.
+	 */
+	public Status getStatus();
+	
+	/**
+	 * Return the obligations that apply to this result.
+	 * 
+	 * @return The AzObligations.
+	 */
+	public AzObligations getObligations();
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzSubject.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzSubject.java
new file mode 100755
index 0000000..30080fa
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/AzSubject.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+
+import javax.security.auth.Subject;
+
+/**
+ * Extends the AzAttributes interface to provide a type-safe interface for Subject attributes.
+ */
+public interface AzSubject extends AzAttributes {
+
+    /**
+     * The name of this collection. For example, this name may be used to
+     * qualify attributes by collection type in XACML.
+     */
+    String NAME = "SUBJECT";
+
+
+    /**
+     * Determines the <code>{@link javax.security.auth.Subject}</code>
+     * represented by this AzSubject.
+     * @return The represented Subject
+     */
+    Subject getSubject() ;
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/RoleMappingService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/RoleMappingService.java
new file mode 100755
index 0000000..4fb76ab
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/authorization/RoleMappingService.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+import java.net.URI;
+import javax.security.auth.Subject;
+
+import org.glassfish.security.services.api.SecurityService;
+import org.jvnet.hk2.annotations.Contract;
+
+/**
+ * The <code>RoleMappingService</code> provides functions that determine a user's role.
+ */
+@Contract
+public interface RoleMappingService extends SecurityService {
+
+	/**
+	 * Determine whether the user (<code>Subject</code>) has the indicated role
+	 * for a given resource (<code>URI</code>) and application context.
+	 *
+	 * @param appContext The application context for the query (can be null).
+	 * @param subject The target <code>Subject</code>.
+	 * @param resource The <code>URI</code> resource for the query.
+	 * @param role The target role.
+	 * @return true if the user has the specified role.
+	 *
+	 * @throws IllegalArgumentException for a <code>null</code> subject or resource
+	 * @throws IllegalStateException if the service was not initialized.
+	 */
+	public boolean isUserInRole(String appContext, Subject subject, URI resource, String role);
+
+	/**
+	 * Determine whether the user (<code>AzSubject</code>) has the indicated role
+	 * for a given resource (<code>AzResource</code>) and application context.
+	 *
+	 * @param appContext The application context for the query (can be null).
+	 * @param subject The target <code>{@link org.glassfish.security.services.api.authorization.AzSubject}</code>.
+	 * @param resource The <code>{@link org.glassfish.security.services.api.authorization.AzResource}</code> for the query.
+	 * @param role The target role.
+	 * @return true if the user has the specified role.
+	 *
+	 * @throws IllegalArgumentException for a <code>null</code> subject or resource
+	 * @throws IllegalStateException if the service was not initialized.
+	 */
+	public boolean isUserInRole(String appContext, AzSubject subject, AzResource resource, String role);
+
+	/**
+	 * Find an existing <code>RoleDeploymentContext</code>, or create a new one if one does not
+	 * already exist for the specified application context.  The role deployment context will be
+	 * returned in an "open" state, and will stay that way until commit() or delete() is called.
+	 *
+	 * @param appContext The application context for which the <code>RoleDeploymentContext</code> is desired.
+	 * @return The resulting <code>RoleDeploymentContext</code> or <code>null</code> if the configured providers
+	 * do not support this feature.
+	 * 
+	 * @throws IllegalStateException if the service was not initialized.
+	 */
+	public RoleDeploymentContext findOrCreateDeploymentContext(String appContext);
+
+	/**
+	 * This interface represents a <code>RoleDeploymentContext</code> as returned by the Role Mapping
+	 * Service's findOrCreateDeploymentContext() method.  The <code>RoleDeploymentContext</code> is used
+	 * to configure role mapping policy for an application (or server administration) context.
+	 * It represents the body of policy that applies to the given context.
+	 *
+	 * A <code>RoleDeploymentContext</code> is always in one of three states: open, closed/inService,
+	 * or deleted.  When returned by the Role Mapping service, a context is in an open state.
+	 * Policies can be added or deleted while in the open state, but the context is not
+	 * in service.  Upon calling commit(), the context is closed and the policies are place
+	 * in service.  Upon calling delete(), the context is taken out of service and the policies
+	 * are deleted from the Role Mapping Provider.
+	 */
+	public interface RoleDeploymentContext {
+
+		public void addMapping(String role, String[] users, String[] groups);
+
+		public void removeMapping(String role, String[] users, String[] groups);
+
+		public void removeRole(String role);
+
+		public void commit();
+
+		public void delete();
+	}
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/common/Attribute.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/common/Attribute.java
new file mode 100755
index 0000000..800c91f
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/common/Attribute.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.common;
+
+
+import java.util.Set;
+
+/**
+ * The Attribute interface defines an interface for interacting with individual Attributes.  It is a read-only interface.
+ * <br>
+ * Note that, because the collection used to hold attribute values is a Set, the attribute can be multi-valued.  Each value
+ * must be distinct, however -- it is not a bag that can contain multiple instances of the same value.
+ */
+public interface Attribute {
+	
+	/**
+	 * Get the name of this attribute.
+	 * 
+	 * @return The name.
+	 */
+	public String getName();
+	
+	/**
+	 * Get a count of the number of values this attribute has (0-n).
+	 * 
+	 * @return The value count.
+	 */
+	public int getValueCount();
+	
+	/**
+	 * Get the first value from the Set of attribute values, or null if the attribute has no values.
+	 * This is a shorthand method that should be useful for single-valued attributes, but note that
+	 * there are no guarantees about which value is returned in the case that there are multiple values.
+	 * The value returned will be whichever value the underlying Set implementation returns first.
+	 * 
+	 * @return The attribute value.
+	 */
+	public String getValue();
+	
+	/**
+	 * Get the Set of values for this attribute.  The Set returned is a copy of the original; changes
+	 * to this Set will not affect the original.
+	 * 
+	 * @return The attribute values Set.
+	 */
+	public Set<String> getValues();
+	
+	/**
+	 * Return the attributes values as a String array.  Note that this array can be zero-length
+	 * in the case that there are no values.
+	 * 
+	 * @return The attribute values array.
+	 */
+	public String[] getValuesAsArray();
+	
+	public void addValue(String value);
+	public void addValues(Set<String> values);
+	public void addValues(String[] values);
+	
+	public void removeValue(String value);
+	public void removeValues(Set<String> values);
+	public void removeValues(String[] values);
+	
+	public void clear();
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/common/Attributes.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/common/Attributes.java
new file mode 100755
index 0000000..322b8f8
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/common/Attributes.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.common;
+
+
+import java.util.Set;
+
+/**
+ * An interface that represents a collectoin of Attributes.  Unlike the Attribute interface, this interface
+ * is not read-only.  Methods are provided to update the underlying collection by adding, removing, or updating
+ * the attributes it holds.
+ * 
+ * There is no factory method on this interface; instead, services that take Attributes parameters have
+ * methods for generating instances of Attributes appropriate to the purpose at hand.
+ */
+public interface Attributes {
+
+	/**
+	 * Get a count of the number of Attributes (not attribute values) in this Attributes object.
+	 * 
+	 * @return The attribute count.
+	 */
+	public int getAttributeCount();
+	
+	/**
+	 * Get the attribute names, as a Set.  This set is read-only; updating it will not change the
+	 * underlying attributes collection.
+	 * 
+	 * @return The attribute names Set.
+	 */
+	public Set<String> getAttributeNames();
+	
+	/**
+	 * Get the Attribute object for the named attribute, if present.
+	 * 
+	 * @param name The name of the Attribute to get.
+	 * @return The Attribute, or null if an attribute by that name is not present.
+	 */
+	public Attribute getAttribute(String name);
+	
+	/**
+	 * Get the value of the specified attribute, if present.  Note that, for multi-valued attributes,
+	 * The value returned is whichever value is returned first by the underlying Set implementation;
+	 * there are no ordering guarantees.  As such, this method is primarily useful as a shorthand
+	 * method for attributes known (or expected) by the caller to be single-valued.
+	 * 
+	 * Note also that it is not possible, using this method, to distinguish between a missing attribute
+	 * and an attribute that is present but has no values.  In both cases, null is returned.
+	 * 
+	 * @param name The name of the attribute whose value is wanted.
+	 * @return The attribute value, or null if the attribute is missing or has no values.
+	 */
+	public String getAttributeValue(String name);
+	
+	/**
+	 * Get the Set of values for the specified attribute, if present.
+	 * 
+	 * @param name The name of the attribute whose values are wanted.
+	 * @return The Set of values, or null if the attribute is not present in the collection.  If the
+	 * attribute is present but has no values, an empty Set is returned.
+	 */
+	public Set<String> getAttributeValues(String name);
+	
+	/**
+	 * Get the set of values for the specified attribute as a String array.
+	 * 
+	 * @param name The name of the attribute whose values are wanted.
+	 * @return The array of values, or null if the attribute is not present in the collection.  If the
+	 * attribute is present but has no values, a zero-length array is returned.
+	 */
+	public String[] getAttributeValuesAsArray(String name);
+	
+	/**
+	 * Add the specified attribute to the attributes collection.  Remove any existing values
+	 * if the replace parameter is true, otherwise add the new value to the existing values.
+	 * Duplicate values are silently dropped.
+	 * 
+	 * @param name The name of the attribute to add.
+	 * @param value The single attribute value to add.
+	 * @param replace If true, replace the existing attribute and any existing values.  If false,
+	 * add the new value to those that are already present.
+	 */
+	public void addAttribute(String name, String value, boolean replace);
+	
+	/**
+	 * Add the specified attribute to the attributes collection.  Remove any existing values
+	 * if the replace parameter is true, otherwise add the new values to the existing values.
+	 * Duplicate values are silently dropped.
+	 * 
+	 * @param name The name of the attribute to add.
+	 * @param value The Set of values to add.
+	 * @param replace If true, replace the existing attribute and any existing values.  If false,
+	 * add the new values to those that are already present.
+	 */
+	public void addAttribute(String name, Set<String> values, boolean replace);
+	
+	/**
+	 * Add the specified attribute to the attributes collection.  Remove any existing values
+	 * if the replace parameter is true, otherwise add the new values to the existing values.
+	 * Duplicate values are silently dropped.
+	 * 
+	 * @param name The name of the attribute to add.
+	 * @param value The array of values to add.
+	 * @param replace If true, replace the existing attribute and any existing values.  If false,
+	 * add the new values to those that are already present.
+	 */
+	public void addAttribute(String name, String[] values, boolean replace);
+	
+	/**
+	 * Remove the specified attribute from the collection.
+	 * 
+	 * @param name The name of the attribute to remove.
+	 */
+	public void removeAttribute(String name);
+	
+	/**
+	 * Remove the specified value from the named attribute.
+	 * 
+	 * @param name The name of the attribute from which to remove a value.
+	 * @param value The value to remove.  A value will be removed only if it exactly matches this parameter.
+	 */
+	public void removeAttributeValue(String name, String value);
+	
+	/**
+	 * Remove the specified values from the named attribute.
+	 * 
+	 * @param name The name of the attribute from which to remove the values.
+	 * @param value The Set of values to remove.  Only values that exactly match values in this Set will be removed.
+	 */
+	public void removeAttributeValues(String name, Set<String> values);
+	
+	/**
+	 * Remove the specified values from the named attribute.
+	 * 
+	 * @param name The name of the attribute from which to remove the values.
+	 * @param value The array of values to remove.  Only values that exactly match values in this array will be removed.
+	 */
+	public void removeAttributeValues(String name, String[] values);
+	
+	/**
+	 * Remove all values associated with the named attribute, but do not remove
+	 * the attribute from the collection.
+	 * 
+	 * @param name The name of the attribute whose values should be removed.
+	 */
+	public void removeAllAttributeValues(String name);
+	
+	/**
+	 * Removes all attributes from the collection.
+	 */
+	public void clear();
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/api/context/SecurityContextService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/context/SecurityContextService.java
new file mode 100755
index 0000000..9b8088e
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/api/context/SecurityContextService.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.context;
+
+
+import org.glassfish.security.services.api.common.Attributes;
+
+import org.jvnet.hk2.annotations.Contract;
+
+/**
+ * The Security Context Service maintains context needed by various security
+ * services.  It is scoped per-thread (though this does not preclude it from
+ * providing access to context that has different scope).
+ */
+
+@Contract
+public interface SecurityContextService {
+	
+	/**
+	 * Return the Environment attributes collection associated with the current thread.
+	 * 
+	 * @return The environment attributes.
+	 */
+	public Attributes getEnvironmentAttributes();
+	
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CLIUtil.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CLIUtil.java
new file mode 100644
index 0000000..4e71fef
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CLIUtil.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.commands;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import org.glassfish.api.ActionReport;
+import org.glassfish.security.services.config.SecurityConfiguration;
+import org.glassfish.security.services.config.SecurityConfigurations;
+import org.glassfish.security.services.config.SecurityProvider;
+
+/**
+ *
+ * @author tjquinn
+ */
+public class CLIUtil {
+    
+    public static SecurityConfiguration findSecurityConfiguration(
+            final Domain domain,
+            final String serviceName,
+            final ActionReport report) {
+        // Lookup the security configurations
+        SecurityConfigurations secConfigs = domain.getExtensionByType(SecurityConfigurations.class);
+        if (secConfigs == null) {
+            report.setMessage("Unable to locate security configurations");
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return null;
+        }
+
+        // Get the security service
+        SecurityConfiguration ssc = secConfigs.getSecurityServiceByName(serviceName);
+        if (ssc == null) {
+            report.setMessage("Unable to locate security service: " + serviceName);
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return null;
+        }
+        return ssc;
+    }
+    
+    public static SecurityProvider findSecurityProvider(
+            final Domain domain,
+            final String serviceName,
+            final String providerName,
+            final ActionReport report) {
+        // Get the security provider config
+        final SecurityConfiguration sc = findSecurityConfiguration(domain, serviceName, report);
+        if (sc == null) {
+            return null;
+        }
+        SecurityProvider provider = sc.getSecurityProviderByName(providerName);
+        if (provider == null) {
+            report.setMessage("Unable to locate security provider: " + providerName);
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return null;
+        }
+        return provider;
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CreateLoginModuleConfig.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CreateLoginModuleConfig.java
new file mode 100644
index 0000000..ad427e9
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CreateLoginModuleConfig.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.commands;
+
+import java.beans.PropertyVetoException;
+import java.util.Properties;
+
+import javax.inject.Inject;
+
+import org.glassfish.security.services.config.SecurityConfiguration;
+
+import org.jvnet.hk2.annotations.Service;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+import org.jvnet.hk2.config.types.Property;
+
+import org.glassfish.api.ActionReport;
+import org.glassfish.api.Param;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import org.glassfish.hk2.api.PerLookup;
+
+import org.glassfish.security.services.config.LoginModuleConfig;
+import org.glassfish.security.services.config.SecurityConfigurations;
+import org.glassfish.security.services.config.SecurityProvider;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+
+/**
+ * General create LoginModule config command.
+ */
+@Service(name="_create-login-module-config")
+@PerLookup
+@ExecuteOn(RuntimeType.DAS)
+@TargetType(CommandTarget.DAS)
+public class CreateLoginModuleConfig implements AdminCommand, AdminCommandSecurity.Preauthorization {
+
+    @Param(optional = false)
+    private String serviceName;
+
+    @Param(optional = false)
+    private String providerName;
+
+    @Param(optional = false)
+    private String moduleClass;
+
+    @Param(optional = false)
+    private String controlFlag;
+
+    @Param(optional = true, separator = ':')
+    private Properties configuration;
+
+    @Param(primary = true)
+    private String name;
+
+    @Inject
+    private Domain domain;
+    
+    @AccessRequired.NewChild(type=LoginModuleConfig.class)
+    private SecurityProvider provider;
+
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        SecurityProvider provider = CLIUtil.findSecurityProvider(domain, serviceName, providerName, context.getActionReport());
+        return (provider != null);
+    }
+
+    
+	/**
+	 * Execute the create-login-module-config admin command.
+	 */
+	@Override
+	public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+
+        // Add LoginModule configuration to the security provider setup
+        // TODO - Add validation logic of the LoginModule config attributes
+        LoginModuleConfig config = null;
+        try {
+            config = (LoginModuleConfig) ConfigSupport.apply(new SingleConfigCode<SecurityProvider>() {
+                @Override
+                public Object run(SecurityProvider param) throws PropertyVetoException, TransactionFailure {
+                	LoginModuleConfig lmConfig = param.createChild(LoginModuleConfig.class);
+                	lmConfig.setName(name);
+                	lmConfig.setModuleClass(moduleClass);
+                	lmConfig.setControlFlag(controlFlag);
+                    // TODO - Should prevent multiple security provider config entries
+                	param.getSecurityProviderConfig().add(lmConfig);
+                    return lmConfig;
+                }
+            }, provider);
+        } catch (TransactionFailure transactionFailure) {
+            report.setMessage("Unable to create login module config: " + transactionFailure.getMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(transactionFailure);
+            return;
+        }
+
+        // Setup LoginModule configuration options
+        if ((config != null) && (configuration != null) && (!configuration.isEmpty())) {
+	        try {
+	            ConfigSupport.apply(new SingleConfigCode<LoginModuleConfig>() {
+	                @Override
+	                public Object run(LoginModuleConfig param) throws PropertyVetoException, TransactionFailure {
+	                    for (Object configPropName: configuration.keySet()) {
+		                	Property prop = param.createChild(Property.class);
+		                	String propName = (String) configPropName; 
+	                        prop.setName(propName);
+	                        prop.setValue(configuration.getProperty(propName));            
+	                        param.getProperty().add(prop);    
+	                    }
+	                    return param;
+	                }
+	            }, config);
+	        } catch (TransactionFailure transactionFailure) {
+	            report.setMessage("Unable to create login module options: " + transactionFailure.getMessage());
+	            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+	            report.setFailureCause(transactionFailure);
+	        }
+        }
+	}
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CreateSecurityProvider.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CreateSecurityProvider.java
new file mode 100644
index 0000000..481bfe3
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CreateSecurityProvider.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.commands;
+
+import java.beans.PropertyVetoException;
+
+import javax.inject.Inject;
+
+import org.glassfish.security.services.config.SecurityConfiguration;
+
+import org.jvnet.hk2.annotations.Service;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+
+import org.glassfish.api.ActionReport;
+import org.glassfish.api.Param;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+import org.glassfish.hk2.api.PerLookup;
+
+import org.glassfish.security.services.config.SecurityConfigurations;
+import org.glassfish.security.services.config.SecurityProvider;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+
+/**
+ * General create security provider command.
+ */
+@Service(name="_create-security-provider")
+@PerLookup
+@ExecuteOn(RuntimeType.DAS)
+@TargetType(CommandTarget.DAS)
+public class CreateSecurityProvider implements AdminCommand, AdminCommandSecurity.Preauthorization {
+
+    @Param(optional = false)
+    private String serviceName;
+
+    @Param(optional = false)
+    private String providerName;
+
+    @Param(optional = false)
+    private String providerType;
+
+    @Param(primary = true)
+    private String name;
+
+    @Inject
+    private Domain domain;
+
+    @AccessRequired.NewChild(type=SecurityProvider.class)
+    private SecurityConfiguration securityServiceConfiguration;
+    
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        securityServiceConfiguration = CLIUtil.findSecurityConfiguration(domain,
+                serviceName, context.getActionReport());
+        return (securityServiceConfiguration != null);
+    }
+
+	/**
+	 * Execute the create-security-provider admin command.
+	 */
+	@Override
+	public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+
+                // Add security provider configuration to the service
+        // TODO - Add validation logic required for security provider attributes
+        try {
+            ConfigSupport.apply(new SingleConfigCode<SecurityConfiguration>() {
+                @Override
+                public Object run(SecurityConfiguration param) throws PropertyVetoException, TransactionFailure {
+                	SecurityProvider providerConfig = param.createChild(SecurityProvider.class);
+                	providerConfig.setName(name);
+                	providerConfig.setType(providerType);
+                	providerConfig.setProviderName(providerName);
+                    param.getSecurityProviders().add(providerConfig);
+                    return providerConfig;
+                }
+            }, securityServiceConfiguration);
+        } catch (TransactionFailure transactionFailure) {
+            report.setMessage("Unable to create security provider: " + transactionFailure.getMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(transactionFailure);
+        }
+	}
+        
+    
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CreateSecurityService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CreateSecurityService.java
new file mode 100644
index 0000000..0c9bf64
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/CreateSecurityService.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.commands;
+
+import java.beans.PropertyVetoException;
+import java.util.Properties;
+
+import javax.inject.Inject;
+
+import org.glassfish.security.services.config.SecurityConfiguration;
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+
+import org.glassfish.api.ActionReport;
+import org.glassfish.api.Param;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.api.admin.ExecuteOn;
+import org.glassfish.api.admin.RuntimeType;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+
+import org.glassfish.security.services.config.AuthenticationService;
+import org.glassfish.security.services.config.SecurityConfigurations;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import org.glassfish.api.admin.AccessRequired;
+import org.glassfish.api.admin.AdminCommandSecurity;
+
+/**
+ * General create security service command.
+ */
+@Service(name="_create-security-service")
+@PerLookup
+@ExecuteOn(RuntimeType.DAS)
+@TargetType(CommandTarget.DAS)
+public class CreateSecurityService implements AdminCommand, AdminCommandSecurity.Preauthorization {
+    private static final String AUTHENTICATION = "authentication";
+
+    @Param(optional = false)
+    private String serviceType;
+
+    @Param(defaultValue = "false", optional = true)
+    private Boolean enableDefault;
+
+    @Param(optional = true, separator = ':')
+    private Properties configuration;
+
+    @Param(primary = true)
+    private String serviceName;
+
+    @Inject
+    private Domain domain;
+
+    // Service configuration type and handler
+    private Class<? extends SecurityConfiguration> clazzServiceType;
+    private ServiceConfigHandler<? extends SecurityConfiguration> serviceConfigHandler;
+
+    @AccessRequired.To("create")
+    private SecurityConfigurations secConfigs;
+    
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+        secConfigs = getSecurityConfigurations(report);
+        return secConfigs != null;
+    }
+
+	/**
+	 * Execute the create-security-service admin command.
+	 */
+	@Override
+	public void execute(AdminCommandContext context) {
+        final ActionReport report = context.getActionReport();
+
+        // Setup the service type and configuration handler
+        if (AUTHENTICATION.equalsIgnoreCase(serviceType)) {
+            clazzServiceType = AuthenticationService.class;
+            serviceConfigHandler = new AuthenticationConfigHandler();
+        }
+        else {
+            report.setMessage("Invalid security service type specified: " + serviceType);
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;
+        }
+        
+        // Add service configuration to the security configurations
+        // TODO - Add validation logic required for base service configuration
+        SecurityConfiguration config = null;
+        try {
+            config = (SecurityConfiguration) ConfigSupport.apply(new SingleConfigCode<SecurityConfigurations>() {
+                @Override
+                public Object run(SecurityConfigurations param) throws PropertyVetoException, TransactionFailure {
+                    SecurityConfiguration svcConfig = param.createChild(clazzServiceType);
+                    svcConfig.setName(serviceName);
+                    svcConfig.setDefault(enableDefault);
+                    param.getSecurityServices().add(svcConfig);
+                    return svcConfig;
+                }
+            }, secConfigs);
+        } catch (TransactionFailure transactionFailure) {
+            report.setMessage("Unable to create security service: " + transactionFailure.getMessage());
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            report.setFailureCause(transactionFailure);
+            return;
+        }
+
+        // Configure the specific service type settings
+        // TODO - Add validation logic required for specific service configuration
+        if ((config != null) && (configuration != null) && (!configuration.isEmpty())) {
+            serviceConfigHandler.setupConfiguration(report, config);
+        }
+	}
+
+	/**
+	 * Base class for service type configuration handling
+	 */
+	private abstract class ServiceConfigHandler<T extends SecurityConfiguration> {
+		abstract T setupConfiguration(ActionReport report, SecurityConfiguration securityServiceConfig);
+	}
+
+	/**
+	 * Handle the authentication service configuration
+	 */
+	private class AuthenticationConfigHandler extends ServiceConfigHandler<AuthenticationService> {
+		@Override
+		public AuthenticationService setupConfiguration(ActionReport report, SecurityConfiguration securityServiceConfig) {
+		    // TODO - Additional type checking needed?
+		    AuthenticationService config = (AuthenticationService) securityServiceConfig;
+		    try {
+		        config = (AuthenticationService) ConfigSupport.apply(new SingleConfigCode<AuthenticationService>() {
+		            @Override
+		            public Object run(AuthenticationService param) throws PropertyVetoException, TransactionFailure {
+		            	// Look at the use password credential setting
+		            	Boolean usePassCred = Boolean.valueOf(configuration.getProperty("use-password-credential"));
+		            	param.setUsePasswordCredential(usePassCred.booleanValue());
+		            	return param;
+		            }
+		        }, config);
+		    } catch (TransactionFailure transactionFailure) {
+		    	report.setMessage("Unable to configure authentication service: " + transactionFailure.getMessage());
+		    	report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+		    	report.setFailureCause(transactionFailure);
+		    	return null;
+		    }
+
+		    // Return the updated configuration object
+		    return config;
+		}
+	}
+        
+        private SecurityConfigurations getSecurityConfigurations(final ActionReport report) {
+            // Lookup or Create the security configurations
+            SecurityConfigurations result = domain.getExtensionByType(SecurityConfigurations.class);
+            if (result == null) {
+                try {
+                    result = (SecurityConfigurations) ConfigSupport.apply(new SingleConfigCode<Domain>() {
+                        @Override
+                        public Object run(Domain wDomain) throws PropertyVetoException, TransactionFailure {
+                            SecurityConfigurations s = wDomain.createChild(SecurityConfigurations.class);
+                            wDomain.getExtensions().add(s);
+                            return s;
+                        }
+                    }, domain);
+                } catch (TransactionFailure transactionFailure)  {
+                    report.setMessage("Unable to create security configurations: " + transactionFailure.getMessage());
+                    report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+                    report.setFailureCause(transactionFailure);
+                }
+            }
+            return result;
+        }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/LDAPAdminAccessConfigurator.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/LDAPAdminAccessConfigurator.java
new file mode 100644
index 0000000..4b7452d
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/commands/LDAPAdminAccessConfigurator.java
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.commands;
+
+//import com.sun.enterprise.config.serverbeans.*;
+import com.sun.enterprise.config.serverbeans.*;
+import com.sun.enterprise.security.auth.realm.Realm;
+import com.sun.enterprise.security.auth.realm.ldap.LDAPRealm;
+import com.sun.enterprise.util.i18n.StringManager;
+import com.sun.enterprise.util.StringUtils;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import org.glassfish.security.services.impl.ServiceLogging;
+import java.beans.PropertyChangeEvent;
+import org.glassfish.api.ActionReport;
+import org.glassfish.api.Param;
+import org.glassfish.api.admin.AdminCommand;
+import org.glassfish.api.admin.AdminCommandContext;
+import org.glassfish.internal.api.Target;
+import javax.inject.Inject;
+import org.jvnet.hk2.annotations.Service;
+import org.jvnet.hk2.config.ConfigSupport;
+import org.jvnet.hk2.config.SingleConfigCode;
+import org.jvnet.hk2.config.TransactionFailure;
+import org.jvnet.hk2.config.types.Property;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import java.beans.PropertyVetoException;
+import java.util.List;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.naming.AuthenticationNotSupportedException;
+import org.glassfish.api.admin.*;
+import org.glassfish.config.support.CommandTarget;
+import org.glassfish.config.support.TargetType;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.glassfish.security.services.config.AuthenticationService;
+import org.glassfish.security.services.config.LoginModuleConfig;
+import org.glassfish.security.services.config.SecurityConfigurations;
+import org.glassfish.security.services.config.SecurityProvider;
+import org.glassfish.security.services.config.SecurityProviderConfig;
+import com.sun.enterprise.security.auth.login.LDAPLoginModule;
+import org.jvnet.hk2.config.RetryableException;
+import org.jvnet.hk2.config.Transaction;
+
+/**  A convenience command to configure LDAP for administration. There are several properties and attributes that
+ *   user needs to remember and that's rather user unfriendly. That's why this command is being developed.
+ * @author &#2325;&#2375;&#2342;&#2366;&#2352 (km@dev.java.net)
+ * @since GlassFish V3
+ */
+@Service(name="configure-ldap-for-admin")
+@PerLookup
+@ExecuteOn({RuntimeType.DAS, RuntimeType.INSTANCE})
+@TargetType({CommandTarget.DAS,CommandTarget.STANDALONE_INSTANCE,CommandTarget.CLUSTER, CommandTarget.CONFIG})
+@RestEndpoints({
+    @RestEndpoint(configBean=Domain.class,
+        opType=RestEndpoint.OpType.POST, 
+        path="configure-ldap-for-admin", 
+        description="configure-ldap-for-admin")
+})
+public class LDAPAdminAccessConfigurator implements AdminCommand, AdminCommandSecurity.Preauthorization {
+
+    @Param (name="basedn", shortName="b", optional=false)
+    public volatile String basedn;
+
+    @Param(name="url", optional=true)
+    public volatile String url = "ldap://localhost:389"; // the default port for LDAP on localhost
+
+
+    @Param(name="ldap-group", shortName="g", optional=true)
+    public volatile String ldapGroupName;
+    
+    @Inject
+    Target targetService;
+    
+    @Inject
+    private ConfigBeansUtilities configBeansUtilities;
+
+    //TODO: not sure what to do with --target here
+    @Param(name = "target", optional = true, defaultValue =
+    SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME)
+    private String target;
+
+    private final static String ADMIN_SERVER = "server"; //this needs to be at central place, oh well
+    private static final StringManager lsm = StringManager.getManager(LDAPAdminAccessConfigurator.class);
+    private static final String DIR_P    = "directory";
+    private static final String BASEDN_P = "base-dn";
+    private static final String JAAS_P   = "jaas-context";
+    private static final String JAAS_V   = "ldapRealm";
+    public static final String LDAP_SOCKET_FACTORY = "java.naming.ldap.factory.socket";
+    public static final String DEFAULT_SSL_LDAP_SOCKET_FACTORY = "com.sun.enterprise.security.auth.realm.ldap.CustomSocketFactory";
+    public static final String LDAPS_URL = "ldaps://";
+
+    private static final Logger logger = Logger.getLogger(ServiceLogging.SEC_COMMANDS_LOGGER, ServiceLogging.SHARED_LOGMESSAGE_RESOURCE);
+    
+    private static final String AUTHENTICATION_SERVICE_PROVIDER_NAME = "adminAuth";
+    private static final String FILE_REALM_SECURITY_PROVIDER_NAME = "adminFile";
+    private static final String ADMIN_FILE_LM_NAME = "adminFileLM";
+
+    private Config asc;
+    
+    @AccessRequired.To("update")
+    private AuthRealm adminAuthRealm;
+    
+    @AccessRequired.To("update")
+    private AdminService adminService;
+    
+    @AccessRequired.To("update")
+    private SecurityProvider fileRealmProvider;
+    
+    @Inject
+    private SecurityConfigurations securityConfigs;
+    
+    @Override
+    public boolean preAuthorization(AdminCommandContext context) {
+        asc = chooseConfig();
+        final SecurityService ss = asc.getSecurityService();
+        adminAuthRealm = getAdminRealm(ss);
+        adminService = asc.getAdminService();
+        final AuthenticationService adminAuthService = (AuthenticationService) 
+                securityConfigs.getSecurityServiceByName(AUTHENTICATION_SERVICE_PROVIDER_NAME);
+        final ActionReport report = context.getActionReport();
+        if (adminAuthService == null) {
+            report.setMessage(lsm.getString("ldap.noExistingAtnService", AUTHENTICATION_SERVICE_PROVIDER_NAME));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;
+        }
+        fileRealmProvider = adminAuthService.getSecurityProviderByName(FILE_REALM_SECURITY_PROVIDER_NAME);
+        if (fileRealmProvider == null) {
+            report.setMessage(lsm.getString("ldap.noExistingAtnProvider", FILE_REALM_SECURITY_PROVIDER_NAME));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;
+        }
+        if ( ! "LoginModule".equals(fileRealmProvider.getType())) {
+            report.setMessage(lsm.getString("ldap.fileRealmProviderNotLoginModuleType", 
+                    FILE_REALM_SECURITY_PROVIDER_NAME,
+                    adminAuthService.getName(),
+                    fileRealmProvider.getType()));
+            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return false;
+        }
+        return true;
+    }
+
+    
+
+    /** Field denoting the name of the realm used for administration. This is fixed in entire of v3. Note that
+     *  the same name is used in admin GUI's web.xml and sun-web.xml. The name of the realm is the key, the
+     *  underlying backend (LDAP, File, Database) can change.
+     */
+    public static final String FIXED_ADMIN_REALM_NAME = "admin-realm";
+    public static final String ORIG_ADMIN_REALM_NAME  = "admin-realm-original";
+
+    @Override
+    public void execute(AdminCommandContext context) {
+        ActionReport rep = context.getActionReport();
+        StringBuilder sb = new StringBuilder();
+        if(url != null) {
+            if (!url.startsWith("ldap://") && !url.startsWith("ldaps://")) {
+                url = "ldap://" + url;        //it's ok to accept just host:port
+            }
+        }
+        if (!pingLDAP(sb)) {
+            rep.setMessage(sb.toString());
+            rep.setActionExitCode(ActionReport.ExitCode.FAILURE);
+            return;
+        }
+        try {
+            configure(sb);
+            //Realm.getInstance(FIXED_ADMIN_REALM_NAME).refresh();
+            rep.setMessage(sb.toString());
+            rep.setActionExitCode(ActionReport.ExitCode.SUCCESS);
+        } catch(TransactionFailure tf) {
+            rep.setMessage(tf.getMessage());
+            rep.setActionExitCode(ActionReport.ExitCode.FAILURE);
+        } catch (PropertyVetoException e) {
+            rep.setMessage(e.getMessage());
+            rep.setActionExitCode(ActionReport.ExitCode.FAILURE);
+        } catch (RetryableException re) {
+            rep.setMessage(re.getMessage());
+            rep.setActionExitCode(ActionReport.ExitCode.FAILURE);
+        }
+/*
+        catch (NoSuchRealmException e) {
+            ActionReport ar = rep.addSubActionsReport();
+            ar.setMessage(lsm.getString("realm.not.refreshed"));
+            ar.setActionExitCode(ActionReport.ExitCode.WARNING);
+        } catch (BadRealmException e) {
+            ActionReport ar = rep.addSubActionsReport();
+            ar.setMessage(lsm.getString("realm.not.refreshed"));
+            ar.setActionExitCode(ActionReport.ExitCode.WARNING);
+        }
+*/
+    }
+
+    private void configure(StringBuilder sb) throws TransactionFailure, PropertyVetoException, RetryableException {
+        
+        //createBackupRealm(sb, getAdminRealm(asc.getSecurityService()), getNewRealmName(asc.getSecurityService()));
+        
+        Transaction t = new Transaction();
+        final SecurityService w_asc = t.enroll(asc.getSecurityService());
+        AdminService w_adminSvc = t.enroll(asc.getAdminService());
+        deleteRealm(w_asc, sb);
+        createRealm(w_asc, sb);
+        configureAdminService(w_adminSvc);
+        updateSecurityProvider(t, fileRealmProvider, sb);
+        t.commit();
+    }
+
+/*    private String getNewRealmName(SecurityService ss) {
+        List<AuthRealm> realms = ss.getAuthRealm();
+        String pref = ORIG_ADMIN_REALM_NAME + "-";
+        int index = 0;  //last one
+        for (AuthRealm realm : realms) {
+            if (realm.getName().indexOf(pref) >= 0) {
+                index = Integer.parseInt(realm.getName().substring(pref.length()));
+            }
+        }
+        return pref + (index+1);
+    }*/
+
+    private void updateSecurityProvider(final Transaction t, final SecurityProvider w_sp,
+            final StringBuilder sb) throws TransactionFailure, PropertyVetoException {
+        for (SecurityProviderConfig spc : w_sp.getSecurityProviderConfig()) {
+            if ((spc instanceof LoginModuleConfig) && spc.getName().equals(ADMIN_FILE_LM_NAME)) {
+                final LoginModuleConfig w_lmConfig = t.enroll((LoginModuleConfig) spc);
+                w_lmConfig.setModuleClass(LDAPLoginModule.class.getName());
+                sb.append(lsm.getString("ldap.authProviderConfigOK", w_sp.getName()));
+                return;
+            }
+        }
+        throw new TransactionFailure(
+                lsm.getString("ldap.noAuthProviderConfig", w_sp.getName(), ADMIN_FILE_LM_NAME));
+    }
+    
+    private AuthRealm getAdminRealm(SecurityService ss) {
+        List<AuthRealm> realms = ss.getAuthRealm();
+        for (AuthRealm realm : realms) {
+            if (FIXED_ADMIN_REALM_NAME.equals(realm.getName()))
+                return realm;
+        }
+        return null;  //unlikely - represents an assertion
+    }
+
+    private void configureAdminService(AdminService as) throws PropertyVetoException, TransactionFailure {
+        as.setAuthRealmName(FIXED_ADMIN_REALM_NAME);  //just in case ...
+    }
+
+    private void createRealm(SecurityService w_ss, final StringBuilder sb) throws TransactionFailure, PropertyVetoException {
+        AuthRealm ldapr = createLDAPRealm(w_ss);
+        w_ss.getAuthRealm().add(ldapr);
+        appendNL(sb,lsm.getString("ldap.realm.setup", FIXED_ADMIN_REALM_NAME));
+    }
+
+    // delete and create a new realm to replace it in a single transaction
+    private void deleteRealm(SecurityService w_ss, final StringBuilder sb) throws TransactionFailure {
+        
+        
+        AuthRealm oldAdminRealm = getAdminRealm(w_ss);
+        w_ss.getAuthRealm().remove(oldAdminRealm);
+        appendNL(sb,"...");
+        //AuthRealm ldapr = createLDAPRealm(ss);
+        //ss.getAuthRealm().add(ldapr);
+        //appendNL(sb,lsm.getString("ldap.realm.setup", FIXED_ADMIN_REALM_NAME));
+    }
+
+    // this had been called renameRealm, but in the SecurityConfigListener, the method authRealmUpdated actually does a create...
+/*    private void createBackupRealm(final StringBuilder sb, AuthRealm realm, final String to) throws PropertyVetoException, TransactionFailure {
+        SingleConfigCode<AuthRealm> scc = new SingleConfigCode<AuthRealm>() {
+            @Override
+            public Object run(AuthRealm realm) throws PropertyVetoException, TransactionFailure {
+                appendNL(sb, lsm.getString("config.to.ldap", FIXED_ADMIN_REALM_NAME, to));
+                realm.setName(to);
+                return realm;
+            }
+        };
+        ConfigSupport.apply(scc, realm);
+    }*/
+
+    private AuthRealm createLDAPRealm(SecurityService ss) throws TransactionFailure, PropertyVetoException {
+        AuthRealm ar = ss.createChild(AuthRealm.class);
+        ar.setClassname(LDAPRealm.class.getName());
+        ar.setName(FIXED_ADMIN_REALM_NAME);
+        List<Property> props = ar.getProperty();
+
+        Property p = ar.createChild(Property.class);
+        p.setName(DIR_P);
+        p.setValue(url);
+        props.add(p);
+
+        p = ar.createChild(Property.class);
+        p.setName(BASEDN_P);
+        p.setValue(basedn);
+        props.add(p);
+
+        p = ar.createChild(Property.class);
+        p.setName(JAAS_P);
+        p.setValue(JAAS_V);
+        props.add(p);
+
+        if (ldapGroupName!= null) {
+            p = ar.createChild(Property.class);
+            p.setName(Realm.PARAM_GROUP_MAPPING);
+            p.setValue(ldapGroupName +"->asadmin"); //appears as gfdomain1->asadmin in domain.xml
+            props.add(p);
+        }
+        
+        return ar;
+    }
+
+    private boolean pingLDAP(StringBuilder sb) {
+        Properties env = new Properties();
+        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+        env.put(Context.PROVIDER_URL, url);
+        
+        if (url != null && url.startsWith(LDAPS_URL)) {
+            env.put(LDAP_SOCKET_FACTORY,
+                    DEFAULT_SSL_LDAP_SOCKET_FACTORY);
+        }
+        try {
+            new InitialContext(env);
+            appendNL(sb,lsm.getString("ldap.ok", url));
+            return true;
+        } catch (AuthenticationNotSupportedException anse) {
+            //CR 6944776
+            //If the server throws this error, it is up
+            //and is configured with Anonymous bind disabled.
+            //Ignore this error while configuring ldap for admin
+            appendNL(sb,lsm.getString("ldap.ok", url));
+            return true;
+        } catch(Exception e) {
+            appendNL(sb,lsm.getString("ldap.na", url, e.getClass().getName(), e.getMessage()));
+            if (logger.isLoggable(Level.FINE)) {
+                logger.log(Level.FINE, StringUtils.getStackTrace(e));
+            }
+            return false;
+        }
+    }
+
+    private static void appendNL(StringBuilder sb, String s) {
+        sb.append(s).append("%%%EOL%%%");
+    }
+    
+    private Config chooseConfig() {
+        Server s = configBeansUtilities.getServerNamed(ADMIN_SERVER);
+        String ac = s.getConfigRef();
+        return targetService.getConfig(ac);
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/common/PrivilededLookup.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/PrivilededLookup.java
new file mode 100644
index 0000000..dd973d6
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/PrivilededLookup.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import java.security.PrivilegedAction;
+
+import org.glassfish.hk2.api.ServiceLocator;
+
+public class PrivilededLookup<T> implements PrivilegedAction<T> {
+        
+    private ServiceLocator serviceLocator;
+    private Class<T> serviceClass;
+    private String serviceName;
+    
+    /**
+     * 
+     * @param serviceLocator   the HK2 service locator
+     * @param serviceClass   the protected HK2 service to be looked up
+     * @param serviceName    the name of the service to be looked
+     */
+    public PrivilededLookup(ServiceLocator serviceLocator,
+            Class<T> serviceClass, String serviceName) {
+        this.serviceLocator = serviceLocator;
+        this.serviceClass = serviceClass;
+        this.serviceName = serviceName;
+    }
+
+    /**
+     * 
+     * @param serviceLocator   the HK2 service locator
+     * @param serviceClass   the protected HK2 service to be looked up
+     */
+    public PrivilededLookup(ServiceLocator serviceLocator, Class<T> serviceClass) {
+        this(serviceLocator, serviceClass, null);
+    }
+
+    public T run() {
+        if (serviceName != null)
+            return serviceLocator.getService(serviceClass, serviceName);
+        else
+            return serviceLocator.getService(serviceClass);
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/common/PrivilegedLookup.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/PrivilegedLookup.java
new file mode 100644
index 0000000..64394bc
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/PrivilegedLookup.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import java.security.PrivilegedAction;
+
+import org.glassfish.hk2.api.ServiceLocator;
+
+public class PrivilegedLookup<T> implements PrivilegedAction<T> {
+        
+    private ServiceLocator serviceLocator;
+    private Class<T> serviceClass;
+    private String serviceName;
+    
+    /**
+     * 
+     * @param serviceLocator   the HK2 service locator
+     * @param serviceClass   the protected HK2 service to be looked up
+     * @param serviceName    the name of the service to be looked
+     */
+    public PrivilegedLookup(ServiceLocator serviceLocator,
+            Class<T> serviceClass, String serviceName) {
+        this.serviceLocator = serviceLocator;
+        this.serviceClass = serviceClass;
+        this.serviceName = serviceName;
+    }
+
+    /**
+     * 
+     * @param serviceLocator   the HK2 service locator
+     * @param serviceClass   the protected HK2 service to be looked up
+     */
+    public PrivilegedLookup(ServiceLocator serviceLocator, Class<T> serviceClass) {
+        this(serviceLocator, serviceClass, null);
+    }
+
+    public T run() {
+        if (serviceName != null)
+            return serviceLocator.getService(serviceClass, serviceName);
+        else
+            return serviceLocator.getService(serviceClass);
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/common/Secure.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/Secure.java
new file mode 100644
index 0000000..609d74c
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/Secure.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+import org.glassfish.hk2.api.Metadata;
+
+/**
+ * Qualifier used to enable a security check at the point of service injection or lookup.
+ * Security Services, which are to protected against unqualified injection/look-up, should be annotated as something below
+ *   e.g.,   @Secure(accessPermissionName = "security/service/<service-type>/<some-specific-name>")
+ *   
+ * Any caller which injects or looks up the protected security service, the caller's jar/class should be granted the following policy
+ *   e.g.,  
+ *     grant codeBase "file:<path>/<to>/<caller-jar>" {
+ *         permission org.glassfish.security.services.common.SecureServiceAccessPermission "security/service/<service-type>/<some-specific-name>";
+ *     };
+ *
+ */
+@Retention(RUNTIME)
+@Qualifier
+@Inherited
+@Target({ TYPE })
+public @interface Secure {
+	
+	public static final String NAME = "accessPermissionName";
+	
+	public static final String PERMISSION_NAME_PREFIX = "security/service/";
+	
+    public static final String DEFAULT_PERM_NAME = PERMISSION_NAME_PREFIX + "default";
+
+	/**
+	 * the permission name to be protected
+	 * if the accessPermissionName is not specified, a default value of "security/service/default" is used.
+	 * @return name of the protected HK2 service
+	 */	
+	@Metadata(NAME)
+	public String accessPermissionName();
+
+	
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecureServiceAccessPermission.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecureServiceAccessPermission.java
new file mode 100644
index 0000000..14bdf7e
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecureServiceAccessPermission.java
@@ -0,0 +1,606 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.sun.enterprise.util.LocalStringManagerImpl;
+
+
+public class SecureServiceAccessPermission extends BasicPermission {
+
+    private static final long serialVersionUID = -274181305911341984L;
+        
+    public static final String RW_ACTION = "read,write";
+    public static final String READ_ACTION = "read";
+    public static final String WRITE_ACTION = "write";
+
+    private static final Logger _log =
+            Logger.getLogger("org.glassfish.security.services");
+    private static LocalStringManagerImpl localStrings =
+            new LocalStringManagerImpl(SecureServiceAccessPermission.class);
+
+    /**
+     * Read action.
+     */
+    private final static int READ    = 0x1;
+
+    /**
+     * Write action.
+     */
+    private final static int WRITE   = 0x2;
+    /**
+     * All actions (read,write);
+     */
+    private final static int ALL     = READ|WRITE;
+
+    private final static int NONE    = 0x0;
+
+    private transient int mask;
+
+    private transient boolean wildcard;
+
+    private transient String path;
+        
+    private String target;  //not used for now
+    private String actions; //not used for now
+
+    /**
+     * 
+     * @param accessPermissionName  the permission name used inside the 'Secure' annotation of the protected service
+     */
+    public SecureServiceAccessPermission(String accessPermissionName) {
+        this(accessPermissionName, null);
+    }
+
+    
+    /**
+     * 
+     * @param accessPermissionName the permission name used inside the 'Secure' annotation of the protected service
+     * @param actions  use null (not used for now) 
+     */
+    public SecureServiceAccessPermission(String accessPermissionName, String actions) {
+        super(accessPermissionName, actions);
+        this.actions = actions;
+        initWildCardPath(accessPermissionName);
+        init(getMask(actions));
+    }
+
+    /**
+     * 
+     * @param accessPermissionName the permission name used inside the 'Secure' annotation of the protected service
+     * @param actions use null (not used for now)
+     * @param targetName use null (not used for now)
+     */
+    public SecureServiceAccessPermission(String accessPermissionName, String actions,
+            String targetName) {
+        this(accessPermissionName, actions);
+        this.target = targetName;
+    }
+        
+    private void init(int mask)
+    {
+
+        if ((mask & ALL) != mask)
+            throw new IllegalArgumentException(
+                localStrings.getLocalString("perm.invalid.action", "invalid actions mask"));
+
+        if (getName() == null)
+            throw new NullPointerException(
+                localStrings.getLocalString("perm.null.name", "name can't be null"));
+
+        this.mask = mask;
+    }
+
+    //base on J2SE implementation
+    private static int getMask(String actions) {
+
+        int mask = NONE;
+
+        if (actions == null) {
+            return mask;
+        }
+
+        // Check against use of constants (used heavily within the JDK)
+        if (actions.equalsIgnoreCase(READ_ACTION)) {
+            return READ;
+        } if (actions.equalsIgnoreCase(WRITE_ACTION)) {
+            return WRITE;
+        } else if (actions.equalsIgnoreCase(RW_ACTION)) {
+            return READ|WRITE;
+        }
+
+        char[] a = actions.toCharArray();
+
+        int i = a.length - 1;
+        if (i < 0)
+            return mask;
+
+        while (i != -1) {
+            char c;
+
+            // skip whitespace
+            while ((i!=-1) && ((c = a[i]) == ' ' ||
+                               c == '\r' ||
+                               c == '\n' ||
+                               c == '\f' ||
+                               c == '\t'))
+                i--;
+
+            // check for the known strings
+            int matchlen;
+
+            if (i >= 3 && (a[i-3] == 'r' || a[i-3] == 'R') &&
+                          (a[i-2] == 'e' || a[i-2] == 'E') &&
+                          (a[i-1] == 'a' || a[i-1] == 'A') &&
+                          (a[i] == 'd' || a[i] == 'D'))
+            {
+                matchlen = 4;
+                mask |= READ;
+
+            } else if (i >= 4 && (a[i-4] == 'w' || a[i-4] == 'W') &&
+                                 (a[i-3] == 'r' || a[i-3] == 'R') &&
+                                 (a[i-2] == 'i' || a[i-2] == 'I') &&
+                                 (a[i-1] == 't' || a[i-1] == 'T') &&
+                                 (a[i] == 'e' || a[i] == 'E'))
+            {
+                matchlen = 5;
+                mask |= WRITE;
+
+            } else {
+                // parse error
+                throw new IllegalArgumentException(
+                                localStrings.getLocalString(
+                                                "perm.invalid.action", "invalid actions: {0}", actions));
+            }
+
+            // make sure we didn't just match the tail of a word
+            // like "ackbarfaccept".  Also, skip to the comma.
+            boolean seencomma = false;
+            while (i >= matchlen && !seencomma) {
+                switch(a[i-matchlen]) {
+                case ',':
+                    seencomma = true;
+                    /*FALLTHROUGH*/
+                case ' ': case '\r': case '\n':
+                case '\f': case '\t':
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                        localStrings.getLocalString(
+                                        "perm.invalid.actions", "invalid actions: {0}", actions));
+                }
+                i--;
+            }
+
+            // point i at the location of the comma minus one (or -1).
+            i -= matchlen;
+        }
+
+        return mask;
+    }
+
+    @Override
+    public String getActions() {
+            return actions;
+    }
+        
+    int getActionMask() {
+        return mask;
+    }
+
+        
+    public String getTarget() {
+            return target;
+    }
+        
+        @Override
+    public boolean equals(Object obj) {
+        if (obj == this)
+            return true;
+
+        if ((obj == null) || (obj.getClass() != getClass()))
+            return false;
+
+        SecureServiceAccessPermission sp = (SecureServiceAccessPermission)obj;
+        
+        return twoStringEq(getName(), sp.getName()) &&
+                   mask == sp.getActionMask() &&
+                   twoStringEq(this.getTarget(), sp.getTarget());
+    }
+
+    //compare two strings
+    private static boolean twoStringEq(String s1, String s2) {
+            
+            if (s1 == null && s2 == null)
+                return true;
+            
+            if (s1 == null) {
+                //s2 not null, s1 is null
+                return false;
+            } else 
+                //s1 not null, 
+                return s1.equals(s2);
+    }
+    
+    @Override
+    public int hashCode() {
+        return getName().hashCode(); 
+    }
+        
+        
+    @Override
+    public boolean implies(Permission p) {
+        if ((p == null) || (p.getClass() != getClass()))
+            return false;
+
+        if (!(p instanceof SecureServiceAccessPermission))
+            return false;
+        
+        SecureServiceAccessPermission that = (SecureServiceAccessPermission) p;
+
+        
+        boolean result = ((this.mask & that.mask) == that.mask) && nameImplies(that);
+        
+        if (_log.isLoggable(Level.FINE)) {
+                _log.log(Level.FINE, "Implies for permission " + p + " return " + result);
+        }
+        
+        return result;
+    }
+    
+    private boolean nameImplies(SecureServiceAccessPermission that) {
+        
+        if (this.wildcard) {
+            if (that.wildcard) {
+                // one wildcard can imply another
+                return that.path.startsWith(path);
+            } else {
+                // make sure ap.path is longer so a/b/* doesn't imply a/b
+                return (that.path.length() > this.path.length()) &&
+                    that.path.startsWith(this.path);
+            }
+        } else {
+            if (that.wildcard) {
+                // a non-wildcard can't imply a wildcard
+                return false;
+            }
+            else {
+                return this.path.equals(that.path);
+            }
+        }
+    }
+    
+
+    private void initWildCardPath(String name)
+    {
+        if (name == null)
+            throw new NullPointerException(
+                        localStrings.getLocalString("perm.null.name", "name can't be null"));
+
+        int len = name.length();
+
+        if (len == 0) {
+            throw new IllegalArgumentException(
+                        localStrings.getLocalString("perm.empty.name", "name can't be empty"));
+        }
+
+        char last = name.charAt(len - 1);
+
+        // Is wildcard or ends with "/*"?
+        if (last == '*' && (len == 1 || name.charAt(len - 2) == '/')) {
+            wildcard = true;
+            if (len == 1) {
+                path = "";
+            } else {
+                path = name.substring(0, len - 1);
+            }
+        } else {
+            path = name;
+        }
+    }
+    
+
+    final String getCanonicalName() {
+        return  getName();
+    }
+
+    public PermissionCollection newPermissionCollection() {
+        return new SecurityAccessPermissionCollection(this.getClass(), _log, localStrings);
+    }
+
+}
+
+
+
+final class SecurityAccessPermissionCollection extends PermissionCollection  {
+
+        private static final long serialVersionUID = 2568719859057815986L;
+
+        /**
+         * Key is name, value is permission. All permission objects in collection
+         * must be of the same type. Not serialized; see serialization section at
+         * end of class.
+         */
+        private transient Map<String, Permission> perms;
+
+        /**
+         * This is set to <code>true</code> if this SecurityAccessPermissionCollection
+         * contains a BasicPermission with '*' as its permission name.
+         * 
+         * @see #serialPersistentFields
+         */
+        private boolean all_allowed;
+
+        /**
+         * The class to which all BasicPermissions in this SecurityAccessPermissionCollection
+         * belongs.
+         * 
+         * @see #serialPersistentFields
+         */
+        private Class permClass;
+
+        
+        private Logger log;
+        private LocalStringManagerImpl localStrings;
+
+        public SecurityAccessPermissionCollection(Class clazz, Logger log, LocalStringManagerImpl localStrings) {
+                perms = new HashMap<String, Permission>(11);
+                all_allowed = false;
+                permClass = clazz;
+                this.log = log;
+                this.localStrings = localStrings;
+        }
+
+        /**
+         * Adds a permission to the BasicPermissions. The key for the hash is
+         * permission.path.
+         * 
+         * @param permission
+         *            the Permission object to add.
+         * 
+         * @exception IllegalArgumentException
+         *                - if the permission is not a BasicPermission, or if the
+         *                permission is not of the same Class as the other
+         *                permissions in this collection.
+         * 
+         * @exception SecurityException
+         *                - if this SecurityAccessPermissionCollection object has been marked
+         *                readonly
+         */
+
+        public void add(Permission permission) {
+                if (!(permission instanceof SecureServiceAccessPermission))
+                        throw new IllegalArgumentException("invalid permission: "
+                                        + permission);
+                if (isReadOnly())
+                        throw new SecurityException(
+                                        localStrings.getLocalString("perm.readonly",
+                                        "attempt to add a Permission to a readonly PermissionCollection"));
+
+                SecureServiceAccessPermission bp = (SecureServiceAccessPermission) permission;
+
+                // make sure we only add new SecureServiceAccessPermissions of the same class
+                // Also check null for compatibility with deserialized form from
+                // previous versions.
+                if (permClass == null) {
+                        // adding first permission
+                        permClass = bp.getClass();
+                } else {
+                        if (bp.getClass() != permClass)
+                                throw new IllegalArgumentException(
+                        localStrings.getLocalString(                                            
+                                        "perm.invalid.perm", "invalid permission: {0}", permission));
+                                                 
+                }
+
+                synchronized (this) {
+                        perms.put(bp.getCanonicalName(), permission);
+                }
+
+                // No sync on all_allowed; staleness OK
+                if (!all_allowed) {
+                        if (bp.getCanonicalName().equals("*"))
+                                all_allowed = true;
+                }
+        }
+
+        /**
+         * Check and see if this set of permissions implies the permissions
+         * expressed in "permission".
+         * 
+         * @param p
+         *            the Permission object to compare
+         * 
+         * @return true if "permission" is a proper subset of a permission in the
+         *         set, false if not.
+         */
+
+        public boolean implies(Permission permission) {
+                if (!(permission instanceof SecureServiceAccessPermission))
+                        return false;
+
+                SecureServiceAccessPermission bp = (SecureServiceAccessPermission) permission;
+
+                // random subclasses of SecureServiceAccessPermission do not imply each other
+                if (bp.getClass() != permClass)
+                        return false;
+
+                // short circuit if the "*" Permission was added
+                if (all_allowed)
+                        return true;
+
+                // strategy:
+                // Check for full match first. Then work our way up the
+                // path looking for matches on a.b..*
+
+                String path = bp.getCanonicalName();
+                // System.out.println("check "+path);
+
+                Permission x;
+
+                synchronized (this) {
+                        x = perms.get(path);
+                }
+
+                if (x != null) {
+                        // we have a direct hit!
+                        return x.implies(permission);
+                }
+
+                // work our way up the tree...
+                int last, offset;
+
+                offset = path.length() - 1;
+
+                while ((last = path.lastIndexOf("/", offset)) != -1) {
+
+                        path = path.substring(0, last + 1) + "*";
+                        // System.out.println("check "+path);
+
+                        synchronized (this) {
+                                x = perms.get(path);
+                        }
+
+                        if (x != null) {
+                                return x.implies(permission);
+                        }
+                        offset = last - 1;
+                }
+
+                if (log.isLoggable(Level.FINE))
+                        log.log(Level.FINE, "pemission collection returns false");
+                
+                // we don't have to check for "*" as it was already checked
+                // at the top (all_allowed), so we just return false
+                return false;
+        }
+
+        /**
+         * Returns an enumeration of all the SecureServiceAccessPermission objects in the
+         * container.
+         * 
+         * @return an enumeration of all the SecureServiceAccessPermission objects.
+         */
+
+        public Enumeration<Permission> elements() {
+                // Convert Iterator of Map values into an Enumeration
+                synchronized (this) {
+                        return Collections.enumeration(perms.values());
+                }
+        }
+
+        // Need to maintain serialization interoperability with earlier releases,
+        // which had the serializable field:
+        //
+        // @serial the Hashtable is indexed by the SecureServiceAccessPermission name
+        //
+        // private Hashtable permissions;
+        /**
+         * @serialField
+         *                  permissions java.util.Hashtable The SecureServiceAccessPermissions in
+         *                  this SecurityAccessPermissionCollection. All SecureServiceAccessPermissions in
+         *                  the collection must belong to the same class. The
+         *                  Hashtable is indexed by the SecureServiceAccessPermission name; the
+         *                  value of the Hashtable entry is the permission.
+         * @serialField
+         *                  all_allowed boolean This is set to <code>true</code> if
+         *                  this SecurityAccessPermissionCollection contains a
+         *                  SecureServiceAccessPermission with '*' as its permission name.
+         * @serialField
+         *                  permClass java.lang.Class The class to which all
+         *                  SecureServiceAccessPermissions in this SecurityAccessPermissionCollection
+         *                  belongs.
+         */
+        private static final ObjectStreamField[] serialPersistentFields = {
+                        new ObjectStreamField("permissions", Hashtable.class),
+                        new ObjectStreamField("all_allowed", Boolean.TYPE),
+                        new ObjectStreamField("permClass", Class.class), };
+
+        /**
+         * @serialData Default fields.
+         */
+        /*
+         * Writes the contents of the perms field out as a Hashtable for
+         * serialization compatibility with earlier releases. all_allowed and
+         * permClass unchanged.
+         */
+        private void writeObject(ObjectOutputStream out) throws IOException {
+            // Don't call out.defaultWriteObject()
+    
+            // Copy perms into a Hashtable
+            Hashtable<String, Permission> permissions =
+                    new Hashtable<String, Permission>(perms.size()*2);
+    
+            synchronized (this) {
+                permissions.putAll(perms);
+            }
+    
+            // Write out serializable fields
+            ObjectOutputStream.PutField pfields = out.putFields();
+            pfields.put("all_allowed", all_allowed);
+            pfields.put("permissions", permissions);
+            pfields.put("permClass", permClass);
+            out.writeFields();
+        }
+
+        /**
+         * readObject is called to restore the state of the
+         * SecurityAccessPermissionCollection from a stream.
+         */
+        private void readObject(java.io.ObjectInputStream in) throws IOException,
+                        ClassNotFoundException {
+            // Don't call defaultReadObject()
+
+            // Read in serialized fields
+            ObjectInputStream.GetField gfields = in.readFields();
+
+            // Get permissions
+            Hashtable<String, Permission> permissions = (Hashtable<String, Permission>) gfields
+                            .get("permissions", null);
+            perms = new HashMap<String, Permission>(permissions.size() * 2);
+            perms.putAll(permissions);
+
+            // Get all_allowed
+            all_allowed = gfields.get("all_allowed", false);
+
+            // Get permClass
+            permClass = (Class) gfields.get("permClass", null);
+
+            if (permClass == null) {
+                    // set permClass
+                    Enumeration<Permission> e = permissions.elements();
+                    if (e.hasMoreElements()) {
+                            Permission p = e.nextElement();
+                            permClass = p.getClass();
+                    }
+            }
+        }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityAccessFilter.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityAccessFilter.java
new file mode 100644
index 0000000..69e2062
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityAccessFilter.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.glassfish.hk2.api.Descriptor;
+import org.glassfish.hk2.api.Filter;
+
+public class SecurityAccessFilter implements Filter {
+
+    private static final String SYS_PROP_JAVA_SEC_POLICY = "java.security.policy";
+    private static final Logger LOG = SecurityAccessValidationService._theLog;
+
+    private static boolean javaPolicySet =
+        AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+
+            @Override
+            public Boolean run() {
+                Boolean rtn = Boolean.FALSE;
+                
+                String wlsName = System.getProperty(SYS_PROP_JAVA_SEC_POLICY);
+                
+                if ( wlsName != null && !wlsName.isEmpty() )
+                        rtn = Boolean.TRUE;
+                
+                return rtn;
+            }
+        });
+    
+    
+    @Override
+    public boolean matches(Descriptor d) {
+
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Descripter: " + d );
+        }
+
+        if (!javaPolicySet) {
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("java security policy is not set, so no validation for security servies.");
+            }
+
+            return false;
+        }
+        
+        if (d == null)
+            return false;
+
+        Set<String> qualifiers = d.getQualifiers();
+        if (qualifiers != null && qualifiers.size() != 0) {
+            for (String s : qualifiers) {
+                if (Secure.class.getCanonicalName().equals(s)) {
+                    if (LOG.isLoggable(Level.FINE)) {
+                        LOG.fine("The instance is annotated with \'Secure\': " + s);                                
+                    }
+                    return true;
+                }
+            }
+        }
+
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("The instance has no \'Secure\' annotated ");
+        }
+
+        return false;
+    }
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityAccessValidationService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityAccessValidationService.java
new file mode 100644
index 0000000..b27f6a8
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityAccessValidationService.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import java.util.logging.Logger;
+
+import javax.inject.Singleton;
+
+import org.glassfish.hk2.api.Filter;
+import org.glassfish.hk2.api.ValidationService;
+import org.glassfish.hk2.api.Validator;
+import org.jvnet.hk2.annotations.Service;
+
+
+@Service 
+@Singleton
+public class SecurityAccessValidationService implements ValidationService {
+
+    
+    private SecurityAccessValidator commValidator = new SecurityAccessValidator();
+
+    private SecurityAccessFilter flt = new SecurityAccessFilter();
+
+    static final Logger _theLog = Logger.getLogger("org.glassfish.security.services"); 
+        
+    
+    @Override
+    public Filter getLookupFilter() {
+        return flt;
+    }
+
+    @Override
+    public Validator getValidator() {
+        return commValidator;
+    }
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityAccessValidator.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityAccessValidator.java
new file mode 100644
index 0000000..4391cb8
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityAccessValidator.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.Iterator;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+
+import org.glassfish.hk2.api.ValidationInformation;
+import org.glassfish.hk2.api.Validator;
+import org.glassfish.hk2.api.ActiveDescriptor;
+import org.glassfish.hk2.api.Injectee;
+import org.glassfish.hk2.api.Descriptor;
+
+import com.sun.enterprise.util.LocalStringManagerImpl;
+
+
+public class SecurityAccessValidator implements Validator {
+
+    private static final Logger LOG = SecurityAccessValidationService._theLog;
+    private static LocalStringManagerImpl localStrings =
+        new LocalStringManagerImpl(SecurityAccessValidator.class);
+
+    
+    @Override
+    public boolean validate(ValidationInformation info) {
+
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("ValidationInformation info= " + info);
+        }
+
+        switch (info.getOperation()) {
+        case BIND:
+        case UNBIND:
+            return validateBindAndUnbind(info);
+        case LOOKUP:
+            return validateLookup(info.getCandidate(), info.getInjectee());
+        default:
+            return false;
+        }
+
+    }
+
+    private boolean isSecureAnnotated(ValidationInformation info) {
+
+        Descriptor d = info.getCandidate();
+
+        Set<String> qualifiers = d.getQualifiers();
+        if (qualifiers != null && qualifiers.size() != 0) {
+            for (String s : qualifiers) {
+                if (Secure.class.getCanonicalName().equals(s)) {
+                    if (LOG.isLoggable(Level.FINE)) {
+                        LOG.fine("The instance is annotated with \'Secure\': "
+                                + info);
+                    }
+                    return true;
+                }
+            }
+        }
+
+        return false;
+
+    }
+
+    private boolean validateBindAndUnbind(ValidationInformation info) {
+
+        // do nothing if the instance is not annotated with 'Secure'
+        if (!isSecureAnnotated(info))
+            return true;
+
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("validateBindAndUnbind," + " injectee= "
+                    + info.getInjectee());
+        }
+
+        return validateLookup(info.getCandidate(), info.getInjectee());
+    }
+
+    private boolean validateLookup(ActiveDescriptor<?> candidate,
+            Injectee injectee) {
+
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Lookup candiate =" + candidate + ", injectee= "
+                    + injectee);
+        }
+
+        if (!candidate.isReified()) {
+            // not yet really injected yet, so not to check perm
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Lookup candiate is not reified yet");
+            }
+            return true;
+        } else {
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Lookup candiate is reified, candidate = " + candidate);
+            }
+        }        
+        
+        Set<String> contracts = candidate.getAdvertisedContracts();
+
+        if (contracts == null)
+            return true;
+
+        Map<String, List<String>> md = candidate.getMetadata();
+        
+        if (LOG.isLoggable(Level.FINE)) {            
+            Iterator<Map.Entry<String, List<String>>> itr = md.entrySet().iterator();
+            while (itr.hasNext()) {
+                Map.Entry<String, List<String>> entry = itr.next();
+                String k = entry.getKey();
+                for (String v : entry.getValue()) {
+                    LOG.fine("$$ key= " + k + ", value= " + v);
+                }                                
+            }
+        }
+        
+        Permission perm = null;
+        List<String> names = md.get(Secure.NAME);
+        if (names == null || names.isEmpty()) {
+
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Perm name is empty, will use default value");
+            }
+            
+            //the 'Secure' annotation did not specify a accessPermissionName, use default accessPermissionName name
+            perm = getAccessPermision(Secure.DEFAULT_PERM_NAME, null);
+            
+        } else {
+            String permName = names.get(0);
+            perm = getAccessPermision(permName, null);
+        }
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("The permission to be protected = " + perm);
+        }
+
+        boolean check_result = false;
+        if (injectee == null) {
+            // lookup style check
+            
+            Class caller = getServiceLookupCaller();
+            
+            check_result = checkPerm(perm, caller);
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Lookup, checked perm for = " + perm + ", result= "
+                        + check_result);
+            }
+        } else {
+            // injection style check
+            check_result = validateInjection(candidate, injectee, perm);
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Injection, checked perm for = " + perm + ", result= "
+                        + check_result);
+            }
+        }
+
+        return check_result;
+    }
+    
+    
+    //temporary alternative fixing to JIRA-HK2:116
+    private Class getServiceLookupCaller() {
+/*
+        StackTraceElement[] steArr = new Exception().getStackTrace();
+        
+        for (int i = 0; i < steArr.length; i++ ) {
+            StackTraceElement elm = steArr[i];
+            
+            if (elm.getClassName().equals("org.jvnet.hk2.internal.ServiceLocatorImpl") &&
+                    (elm.getMethodName().equals("getService") ||
+                     elm.getMethodName().equals("getAllServices") ||
+                     elm.getMethodName().equals("getServiceHandle") ||
+                     elm.getMethodName().equals("getAllServiceHandles") ||
+                     elm.getMethodName().equals("create") ||
+                     elm.getMethodName().equals("createAndInitialize") ||
+                     elm.getMethodName().equals("shutdown")
+                     
+               )) {
+
+                if (LOG.isLoggable(Level.FINE)) {
+                    LOG.fine("Found the service locator, classname= " 
+                            + steArr[i+1].getClassName() + ", ste =" + steArr[i+1]);
+                }
+
+                //after finding the 1st service locator, then look for the class which is not ServiceLocatorImpl
+                System.out.println("%%%%found the locator");
+                for (int j = i+1; j < steArr.length; j++ ) {
+                    StackTraceElement elmj = steArr[j];
+                    if (elmj.getClassName().startsWith("org.jvnet.hk2.internal."))  //by pass all hk2 classes to find the caller
+                        continue;
+                    else {
+                        StackTraceElement caller = elmj;
+                        //found the caller class which is not ServiceLocatorImpl
+                        System.out.println("%%%caller Class name= " + caller.getClassName() + ", caller ste =" + caller + 
+                                ", method=" + caller.getMethodName());                
+                        try {
+                            return Class.forName(caller.getClassName(), true, Thread.currentThread().getContextClassLoader());
+                        } catch (ClassNotFoundException e) {
+
+                            try {
+                                return Class.forName(caller.getClassName());
+                            } catch (ClassNotFoundException e1) {
+                                // TODO Auto-generated catch block
+                                //e1.printStackTrace();
+                                LOG.warning(localStrings.getLocalString("sec.validate.lookup.noclass",
+                                        "Lookup Class not found in classpath: {0}", caller.getClassName()));
+                                throw new RuntimeException(e);
+                            }
+                            
+                        }
+                    }
+                }
+            }
+        }
+
+        System.out.println("%%%caller Class= null");
+        LOG.warning(localStrings.getLocalString("sec.validate.lookup.fail", "Cannot find the looup caller class"));
+*/
+        return null;
+        
+    }
+
+    private boolean checkPerm(Permission p, Class caller) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Checked perm for = " + p);
+        }
+
+        
+        try {
+            if (caller != null) {
+                ProtectionDomain pd = this.getCallerProtDomain(caller);
+                pd.implies(p);
+            } else
+                AccessController.checkPermission(p);
+            
+        } catch (SecurityException e) {
+            
+            LOG.warning(localStrings.getLocalString(
+                    "sec.validate.lookup.deny", "Check Permission failed in lookup for permission = {0}",  p));
+
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Check Permission failed, perm= " + p + ", message = "
+                        + e.getMessage());
+            }
+            throw e;
+        }
+
+        return true;
+    }
+
+
+    private boolean validateInjection(ActiveDescriptor<?> candidate,
+            Injectee injectee, Permission p) {
+
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Injectee =" + injectee + ", permission= " + p);
+        }
+
+        // If this is an Inject, get the protection domain of the injectee
+        Class<?> injecteeClass = injectee.getInjecteeClass();
+
+        ProtectionDomain pd = getCallerProtDomain(injecteeClass);
+
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Protection domain code src= " + pd.getCodeSource());
+        }
+
+        if (!pd.implies(p)) {
+            
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("permission check failed for " + injectee + ", to get perm " + p + ", for candidate "
+                        + candidate);
+            }
+
+            throw new AccessControlException(localStrings.getLocalString("sec.validate.injection.deny",   
+                    "Access denied for injectee {0} to get permission {1}.", injectee, p));
+                    
+        } else {
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("permission check success for " + injectee
+                        + " to get " + candidate);
+            }
+        }
+
+        return true;
+    }
+
+    private ProtectionDomain getCallerProtDomain(final Class caller) {
+        ProtectionDomain pd = AccessController
+                .doPrivileged(new PrivilegedAction<ProtectionDomain>() {
+                    @Override
+                    public ProtectionDomain run() {
+                        return caller.getProtectionDomain();
+                    }
+                });
+
+        return pd;
+    }
+
+
+    /**
+     * The permission to be checked
+     * 
+     * @return permission to be checked
+     */
+    private Permission getAccessPermision(String protectName, String action) {
+        return new SecureServiceAccessPermission(protectName, action);
+    }
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityScope.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityScope.java
new file mode 100644
index 0000000..df67c82
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityScope.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import javax.inject.Scope;
+
+import org.glassfish.hk2.api.Proxiable;
+
+/**
+ * Scope used by security services that enables a flexible binding to service instances.
+ */
+@Retention(RUNTIME)
+@Scope
+// @Proxiable MUST be added back in later once we understand why cglib is having problems
+@Target({ TYPE, METHOD })
+public @interface SecurityScope {
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityScopeContext.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityScopeContext.java
new file mode 100644
index 0000000..722ec14
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SecurityScopeContext.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.glassfish.hk2.api.ActiveDescriptor;
+import org.glassfish.hk2.api.Context;
+import org.glassfish.hk2.api.ServiceHandle;
+import org.jvnet.hk2.annotations.Service;
+
+/**
+ * The security context used to enable the scoping of security service instances.
+ */
+@Service
+@Singleton
+public class SecurityScopeContext implements Context<SecurityScope> {
+    private final HashMap<String, HashMap<ActiveDescriptor<?>, Object>> contexts =
+        new HashMap<String, HashMap<ActiveDescriptor<?>, Object>>();
+    
+    @Inject
+    private StateManager manager;
+
+    @Override
+    public Class<? extends Annotation> getScope() {
+        return SecurityScope.class;
+    }
+
+    @SuppressWarnings("unchecked")
+	@Override
+    public <T> T findOrCreate(ActiveDescriptor<T> activeDescriptor, ServiceHandle<?> root) {
+        HashMap<ActiveDescriptor<?>, Object> mappings = getCurrentContext();
+        
+        Object retVal = mappings.get(activeDescriptor);
+        if (retVal == null) {
+            retVal = activeDescriptor.create(root);
+            
+            mappings.put(activeDescriptor, retVal);
+        }
+        return (T) retVal;
+    }
+
+    @SuppressWarnings("unchecked")
+	@Override
+    public boolean containsKey(ActiveDescriptor<?> descriptor) {
+        HashMap<ActiveDescriptor<?>, Object> mappings = getCurrentContext();
+        
+        return mappings.containsKey(descriptor);
+    }
+
+    @Override
+    public boolean isActive() {
+        return manager.getCurrent() != null;
+    }
+    
+    private HashMap<ActiveDescriptor<?>, Object> getCurrentContext() {
+        if (manager.getCurrent() == null) throw new IllegalStateException("Not In Active State");
+        
+        HashMap<ActiveDescriptor<?>, Object> retVal = contexts.get(manager.getCurrent());
+        if (retVal == null) {
+            retVal = new HashMap<ActiveDescriptor<?>, Object>();
+            
+            contexts.put(manager.getCurrent(), retVal);
+        }
+        
+        return retVal;
+    }
+
+    /* (non-Javadoc)
+     * @see org.glassfish.hk2.api.Context#supportsNullCreation()
+     */
+    @Override
+    public boolean supportsNullCreation() {
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.glassfish.hk2.api.Context#shutdown()
+     */
+    @Override
+    public void shutdown() {
+        // Do nothing
+        
+    }
+
+    @Override
+    public void destroyOne(ActiveDescriptor<?> descriptor) {
+        // TODO Auto-generated method stub
+        
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/common/StateManager.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/StateManager.java
new file mode 100644
index 0000000..7f11326
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/StateManager.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import javax.inject.Singleton;
+
+import org.jvnet.hk2.annotations.Service;
+
+/**
+ * The StateManager determines the security service instance selection.
+ */
+@Service
+@Singleton
+public class StateManager {
+    // private String current;
+    private String current = "default";
+    
+    public void setCurrent(String current) {
+        this.current = current;
+    }
+    
+    public String getCurrent() {
+        return current;
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SubjectUtil.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SubjectUtil.java
new file mode 100644
index 0000000..dc232eb
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/common/SubjectUtil.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+
+import javax.security.auth.Subject;
+import java.security.Principal;
+
+import org.glassfish.security.common.PrincipalImpl;
+import org.glassfish.security.common.Group;
+
+public class SubjectUtil {
+
+    /**
+     * Utility method to find the user names from a subject. The method assumes the user name is
+     * represented by {@link org.glassfish.security.common.PrincipalImpl PrincipalImpl } inside the Subject's principal set.
+     * @param subject the subject from which to find the user name
+     * @return a list of strings representing the user name. The list may have more than one entry if the subject's principal set
+     * contains more than one PrincipalImpl instances, or empty entry (i.e., anonymous user) if the subject's principal set contains no PrincipalImpl instances.
+     */
+    public static List<String> getUsernamesFromSubject(Subject subject) {
+
+        List<String> userList = new ArrayList<String>();
+
+        Set<Principal> princSet = null;
+
+        if (subject != null) {
+
+            princSet = subject.getPrincipals();
+            for (Principal p : princSet) {
+                if ((p != null) && (
+                  p.getClass().isAssignableFrom(PrincipalImpl.class)  ||
+                  "weblogic.security.principal.WLSUserImpl".equals(p.getClass().getCanonicalName())
+                		)) {
+                    String uName = p.getName();
+                    userList.add(uName);
+                }
+            }
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * Utility method to find the group names from a subject. The method assumes the group name is
+     * represented by {@link org.glassfish.security.common.Group Group } inside the Subject's principal set.
+     * @param subject the subject from which to find the username
+     * @return a list of strings representing the group names. The list may have more than one entry if the subject's principal set
+     * contains more than one Group instances, or empty entry if the subject's principal set contains no Group instances.
+     */
+    public static List<String> getGroupnamesFromSubject(Subject subject) {
+
+        List<String> groupList = new ArrayList<String>();
+
+        Set<Group> princSet = null;
+
+        if (subject != null) {
+
+            princSet = subject.getPrincipals(Group.class);
+            for (PrincipalImpl g : princSet) {
+                String gName = g.getName();
+                groupList.add(gName);
+            }
+        }
+
+        return groupList;
+    }
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/config/AuthenticationService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/AuthenticationService.java
new file mode 100644
index 0000000..809fc00
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/AuthenticationService.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.config;
+
+import java.beans.PropertyVetoException;
+
+import org.jvnet.hk2.config.Attribute;
+import org.jvnet.hk2.config.Configured;
+
+/**
+ * The AuthenticationService Configuration
+ */
+@Configured
+public interface AuthenticationService extends SecurityConfiguration {
+    /**
+     * Determines if the Authentication Service instance should use
+     * a GlassFish AuthRealm PasswordCredential with the LoginModule(s).
+     */
+    @Attribute(defaultValue = "false")
+    boolean getUsePasswordCredential();
+    void setUsePasswordCredential(boolean value) throws PropertyVetoException;
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/config/AuthorizationService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/AuthorizationService.java
new file mode 100644
index 0000000..7ec7571
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/AuthorizationService.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.config;
+
+
+import org.jvnet.hk2.config.Configured;
+
+
+@Configured
+public interface AuthorizationService extends SecurityConfiguration {
+
+    
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/config/LoginModuleConfig.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/LoginModuleConfig.java
new file mode 100644
index 0000000..3cdb9c1
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/LoginModuleConfig.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.config;
+
+import org.jvnet.hk2.config.Attribute;
+import org.jvnet.hk2.config.Configured;
+import org.jvnet.hk2.config.DuckTyped;
+import org.jvnet.hk2.config.Element;
+import org.jvnet.hk2.config.types.Property;
+import org.jvnet.hk2.config.types.PropertyBag;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import java.beans.PropertyVetoException;
+import javax.validation.constraints.NotNull;
+import com.sun.enterprise.config.serverbeans.customvalidators.JavaClassName;
+
+/**
+ * The LoginModule configuration used for a security provider plugin.
+ * 
+ * Defines setup for standard JAAS LoginModule Configuration.
+ */
+@Configured
+public interface LoginModuleConfig extends SecurityProviderConfig, PropertyBag {
+    /**
+     * Gets the class name of the LoginModule.
+     */
+    @Attribute(required=true)
+    @NotNull
+    @JavaClassName
+    public String getModuleClass();
+    public void setModuleClass(String value) throws PropertyVetoException;
+
+    /**
+     * Gets the JAAS control flag of the LoginModule.
+     */
+    @Attribute(required=true)
+    @NotNull
+    public String getControlFlag();
+    public void setControlFlag(String value) throws PropertyVetoException;
+
+    /**
+     * Gets the properties of the LoginModule.
+     */
+    @Element
+    List<Property> getProperty();
+
+    /**
+     * Gets the options of the LoginModule for use with JAAS Configuration.
+     */
+    @DuckTyped
+    Map<String,?> getModuleOptions();
+
+    class Duck {
+        /**
+         * Gets the options of the LoginModule for use with JAAS Configuration.
+         */
+        public static Map<String,?> getModuleOptions(LoginModuleConfig config) {
+        	Map<String,String> moduleOptions = new HashMap<String,String>();
+            for (Property prop : config.getProperty()) {
+                moduleOptions.put(prop.getName(), prop.getValue());
+            }
+            return moduleOptions;
+        }
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/config/RoleMappingService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/RoleMappingService.java
new file mode 100644
index 0000000..f7c950e
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/RoleMappingService.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.config;
+
+import org.jvnet.hk2.config.Configured;
+
+@Configured
+public interface RoleMappingService extends SecurityConfiguration {
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityConfigUpgradeService.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityConfigUpgradeService.java
new file mode 100644
index 0000000..0ebd0c5
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityConfigUpgradeService.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.config;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.security.auth.login.FileLoginModule;
+import org.glassfish.api.admin.config.ConfigurationUpgrade;
+import org.glassfish.hk2.api.PerLookup;
+import org.glassfish.hk2.api.PostConstruct;
+import org.glassfish.security.services.provider.authorization.AuthorizationProviderConfig;
+import org.jvnet.hk2.annotations.Service;
+import org.jvnet.hk2.config.Transaction;
+import org.jvnet.hk2.config.TransactionFailure;
+import org.jvnet.hk2.config.types.Property;
+
+import javax.inject.Inject;
+import java.beans.PropertyVetoException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Upgrades the configuration to use the default file realm and the
+ * login module which handles non-username/password admin authentication.
+ *
+ * @author tjquinn
+ * @author Masoud Kalali
+ */
+@Service
+@PerLookup
+public class SecurityConfigUpgradeService implements ConfigurationUpgrade, PostConstruct {
+
+    private static final String AUTHENTICATION_SERVICE_NAME = "adminAuth";
+    private static final String FILE_REALM_PROVIDER_NAME = "filerealm";
+    private static final String FILE_REALM_PROVIDER_PROVIDER_NAME = "adminFile";
+    private static final String FILE_LOGIN_MODULE_NAME = "adminFileLM";
+    private static final String FILE_LOGIN_MODULE_CLASS = FileLoginModule.class.getName();
+
+    private static final String ADM_REALM_PROVIDER_NAME = "spcrealm";
+    private static final String ADM_REALM_PROVIDER_PROVIDER_NAME = "adminSpc";
+    private static final String ADM_LOGIN_MODULE_NAME = "adminSpecialLM";
+    private static final String ADM_LOGIN_MODULE_CLASS = "com.sun.enterprise.admin.util.AdminLoginModule";
+
+    private static final String LOGIN_MODULE_TYPE_NAME = "LoginModule";
+
+    private static final String AUTHORIZATION_SERVICE_NAME = "authorizationService";
+    private static final String SIMPLE_PROVIDER_PROVIDER_NAME = "simpleAuthorizationProvider";
+    private static final String SIMPLE_PROVIDER_NAME = "simpleAuthorization";
+    private static final String SIMPLE_PROVIDER_TYPE = "simple";
+    private static final String SIMPLE_PROVIDER_CONFIG_NAME = "simpleAuthorizationProviderConfig";
+    private static final String SIMPLE_PROVIDER_CLASS_NAME = "org.glassfish.security.services.provider.authorization.SimpleAuthorizationProviderImpl";
+    private static final String SUPPORT_POLICY_DEPLOY = "false";
+
+    private static final Logger logger = Logger.getAnonymousLogger();
+
+    @Inject
+    private Domain domain;
+
+    @Override
+    public void postConstruct() {
+        if (domain.getExtensionByType(SecurityConfigurations.class) != null) {
+            /*
+             * The domain already contains a security-configurations setting,
+             * so for now that's sufficient to conclude we don't need to upgrade.
+             */
+            logger.log(Level.INFO, "SecurityConfigUpgradeService bypassing - security-configurations already present");
+            return;
+        }
+        Transaction t = null;
+        try {
+            t = new Transaction();
+            final Domain domain_w = t.enroll(domain);
+            
+            /*
+             * Create the security configurations element and add it to the domain.
+             */
+            final SecurityConfigurations sc_w = domain_w.createChild(SecurityConfigurations.class);
+            domain_w.getExtensions().add(sc_w);
+            
+            /*
+             * Create and add the authentication service.
+             */
+            final AuthenticationService as_w = addAuthenticationService(sc_w);
+            
+            /*
+             * Next, add the two providers and their children.
+             */
+            addAdmRealmProvider(as_w);
+            addFileRealmProvider(as_w);
+
+            /**
+             * Next add the authorization service
+             */
+            final AuthorizationService authorizationService = addAuthorizationService(sc_w);
+            /**
+             * Next add the authorization service provider
+             */
+            addSimpleAuthorizationProvider(authorizationService);
+
+            t.commit();
+            logger.log(Level.INFO, "SecurityConfigUpgradeService successfully completed the upgrade");
+
+        } catch (Exception ex) {
+            if (t != null) {
+                t.rollback();
+            }
+            logger.log(Level.SEVERE, null, ex);
+        }
+    }
+
+    private AuthenticationService addAuthenticationService(final SecurityConfigurations sc_w) throws TransactionFailure, PropertyVetoException {
+        final AuthenticationService as_w = sc_w.createChild(AuthenticationService.class);
+        sc_w.getSecurityServices().add(as_w);
+        as_w.setDefault(true);
+        as_w.setName(AUTHENTICATION_SERVICE_NAME);
+        as_w.setUsePasswordCredential(true);
+        return as_w;
+    }
+
+    private SecurityProvider addFileRealmProvider(final AuthenticationService as_w) throws PropertyVetoException, TransactionFailure {
+        final SecurityProvider sp_w = addProvider(as_w, FILE_REALM_PROVIDER_NAME, FILE_REALM_PROVIDER_PROVIDER_NAME, LOGIN_MODULE_TYPE_NAME);
+        addLoginModule(sp_w, FILE_LOGIN_MODULE_NAME, FILE_LOGIN_MODULE_CLASS);
+        return sp_w;
+
+    }
+
+    private SecurityProvider addAdmRealmProvider(final AuthenticationService as_w) throws TransactionFailure, PropertyVetoException {
+        final SecurityProvider sp_w = addProvider(as_w, ADM_REALM_PROVIDER_NAME, ADM_REALM_PROVIDER_PROVIDER_NAME, LOGIN_MODULE_TYPE_NAME);
+        addLoginModule(sp_w, ADM_LOGIN_MODULE_NAME, ADM_LOGIN_MODULE_CLASS);
+        return sp_w;
+    }
+
+    private SecurityProvider addProvider(final AuthenticationService as_w, final String providerName, final String providerProviderName,
+                                         final String type) throws TransactionFailure, PropertyVetoException {
+
+        final SecurityProvider sp_w = as_w.createChild(SecurityProvider.class);
+        as_w.getSecurityProviders().add(sp_w);
+        sp_w.setName(providerName);
+        sp_w.setProviderName(providerProviderName);
+        sp_w.setType(type);
+        return sp_w;
+    }
+
+    private LoginModuleConfig addLoginModule(final SecurityProvider sp_w, final String name, final String className) throws TransactionFailure, PropertyVetoException {
+        final LoginModuleConfig lm_w = sp_w.createChild(LoginModuleConfig.class);
+        sp_w.getSecurityProviderConfig().add(lm_w);
+        lm_w.setName(name);
+        lm_w.setModuleClass(className);
+        lm_w.setControlFlag("sufficient");
+
+        final Property configProp = lm_w.createChild(Property.class);
+        configProp.setName("config");
+        configProp.setValue("server-config");
+
+        final Property realmProp = lm_w.createChild(Property.class);
+        realmProp.setName("auth-realm");
+        realmProp.setValue("admin-realm");
+
+        lm_w.getProperty().add(configProp);
+        lm_w.getProperty().add(realmProp);
+        return lm_w;
+
+    }
+
+    private AuthorizationService addAuthorizationService(final SecurityConfigurations sc_w) throws TransactionFailure, PropertyVetoException {
+        final AuthorizationService as_w = sc_w.createChild(AuthorizationService.class);
+        sc_w.getSecurityServices().add(as_w);
+        as_w.setDefault(true);
+        as_w.setName(AUTHORIZATION_SERVICE_NAME);
+        return as_w;
+    }
+
+    private SecurityProvider addSimpleAuthorizationProvider(final AuthorizationService as_w) throws PropertyVetoException, TransactionFailure {
+        final SecurityProvider sp_w = addAuthzProvider(as_w, SIMPLE_PROVIDER_NAME, SIMPLE_PROVIDER_PROVIDER_NAME, SIMPLE_PROVIDER_TYPE);
+        addAuthorizationConfig(sp_w, SIMPLE_PROVIDER_CONFIG_NAME, SUPPORT_POLICY_DEPLOY);
+        return sp_w;
+    }
+
+    private void addAuthorizationConfig(SecurityProvider sp_w, String configName, String supportPolicyDeploy) throws TransactionFailure, PropertyVetoException {
+        final AuthorizationProviderConfig authorizationProviderConfig = sp_w.createChild(AuthorizationProviderConfig.class);
+        authorizationProviderConfig.setName(configName);
+        authorizationProviderConfig.setSupportPolicyDeploy(Boolean.valueOf(supportPolicyDeploy));
+        authorizationProviderConfig.setProviderClass(SIMPLE_PROVIDER_CLASS_NAME);
+        sp_w.getSecurityProviderConfig().add(authorizationProviderConfig);
+    }
+
+    private SecurityProvider addAuthzProvider(AuthorizationService as_w, String simpleProviderName, String simpleProviderProviderName, String simpleProviderType) throws TransactionFailure, PropertyVetoException {
+        final SecurityProvider sp_w = as_w.createChild(SecurityProvider.class);
+        sp_w.setName(simpleProviderName);
+        sp_w.setProviderName(simpleProviderProviderName);
+        sp_w.setType(simpleProviderType);
+        as_w.getSecurityProviders().add(sp_w);
+        return sp_w;
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityConfiguration.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityConfiguration.java
new file mode 100644
index 0000000..6540b50
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityConfiguration.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.config;
+
+import org.jvnet.hk2.config.Attribute;
+import org.jvnet.hk2.config.ConfigBeanProxy;
+import org.jvnet.hk2.config.Configured;
+import org.jvnet.hk2.config.DuckTyped;
+import org.jvnet.hk2.config.Element;
+
+import javax.validation.constraints.NotNull;
+import java.beans.PropertyVetoException;
+import java.util.List;
+
+/**
+ * Base interface for all security service configurations.
+ * 
+ * Each security service configuration has a name, indication of the service
+ * configuration being the default when multiple service configurations are
+ * present and an optional list of the specific security provider plugins. 
+ */
+@Configured
+public interface SecurityConfiguration extends ConfigBeanProxy {
+    /**
+     * Gets the name of the security service instance.
+     */
+    @Attribute(required=true, key=true)
+    @NotNull
+    public String getName();
+    public void setName(String value) throws PropertyVetoException;
+
+    /**
+     * Determine if this is the default instance.
+     */
+    @Attribute(defaultValue = "false")
+    boolean getDefault();
+    void setDefault(boolean defaultValue) throws PropertyVetoException;
+
+    /**
+     * Gets the list of the security provider plugins used by the security service.
+     */
+    @Element("security-provider")
+    List<SecurityProvider> getSecurityProviders();
+
+    /**
+     * Gets a named security provider.
+     */
+    @DuckTyped
+    SecurityProvider getSecurityProviderByName(String name);
+
+    class Duck {
+        /**
+         * Gets a named security provider.
+         */
+    	public static SecurityProvider getSecurityProviderByName(SecurityConfiguration securityServiceConfiguration, String name) {
+            for (SecurityProvider config : securityServiceConfiguration.getSecurityProviders()) {
+                if (config.getProviderName().equals(name)) {
+                    return config;
+                }
+            }
+            return null;
+        }
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityConfigurations.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityConfigurations.java
new file mode 100644
index 0000000..83d8ee4
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityConfigurations.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.config;
+
+import com.sun.enterprise.config.serverbeans.DomainExtension;
+import com.sun.enterprise.config.modularity.annotation.HasNoDefaultConfiguration;
+import org.jvnet.hk2.config.ConfigBeanProxy;
+import org.jvnet.hk2.config.Configured;
+import org.jvnet.hk2.config.DuckTyped;
+import org.jvnet.hk2.config.Element;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * The top level security configuration which holds the list of configured security services.
+ */
+@Configured
+@HasNoDefaultConfiguration
+public interface SecurityConfigurations extends ConfigBeanProxy, DomainExtension {
+    /**
+     * Gets the list of configured security services.
+     */
+    @Element("*")
+    List<SecurityConfiguration> getSecurityServices();
+
+    /**
+     * Gets the list of configured security services by security service type.
+     */
+    @DuckTyped
+    <T extends SecurityConfiguration> List<T> getSecurityServicesByType(Class<T> type);
+
+    /**
+     * Gets the default configured security service by security service type.
+     */
+    @DuckTyped
+    <T extends SecurityConfiguration> T getDefaultSecurityServiceByType(Class<T> type);
+
+    /**
+     * Gets a named security service configuration by specific security type.
+     */
+    @DuckTyped
+    <T extends SecurityConfiguration> T getSecurityServiceByName(String name, Class<T> type);
+
+    /**
+     * Gets a named security service configuration.
+     */
+    @DuckTyped
+    SecurityConfiguration getSecurityServiceByName(String name);
+
+    class Duck {
+        /**
+         * Gets the list of configured security services by security service type.
+         */
+        public static <T extends SecurityConfiguration> List<T> getSecurityServicesByType(SecurityConfigurations services, Class<T> type) {
+            List<T> typedServices = new ArrayList<T>();
+            for (SecurityConfiguration securityServiceConfiguration : services.getSecurityServices()) {
+                try {
+                    if (type.isAssignableFrom(securityServiceConfiguration.getClass())) {
+                        typedServices.add(type.cast(securityServiceConfiguration));
+                    }
+                } catch (Exception e) {
+                    // ignore, not the right type.
+                }
+            }
+			return Collections.unmodifiableList(typedServices);
+        }
+
+        /**
+         * Gets the default configured security service by security service type.
+         */
+    	public static <T extends SecurityConfiguration> T getDefaultSecurityServiceByType(SecurityConfigurations services, Class<T> type) {
+            for (SecurityConfiguration securityServiceConfiguration : services.getSecurityServices()) {
+                try {
+                    if (securityServiceConfiguration.getDefault()) {
+                        return type.cast(securityServiceConfiguration);
+                    }
+                } catch (Exception e) {
+                    // ignore, not the right type.
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Gets a named security service configuration by specific security type.
+         */
+    	public static <T extends SecurityConfiguration> T getSecurityServiceByName(SecurityConfigurations services, String name, Class<T> type) {
+            for (SecurityConfiguration securityServiceConfiguration : services.getSecurityServices()) {
+                try {
+                    if (securityServiceConfiguration.getName().equals(name)) {
+                        return type.cast(securityServiceConfiguration);
+                    }
+                } catch (Exception e) {
+                    // ignore, not the right type.
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Gets a named security service configuration.
+         */
+    	public static SecurityConfiguration getSecurityServiceByName(SecurityConfigurations services, String name) {
+            for (SecurityConfiguration securityServiceConfiguration : services.getSecurityServices()) {
+                if (securityServiceConfiguration.getName().equals(name)) {
+                    return securityServiceConfiguration;
+                }
+            }
+            return null;
+        }
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityProvider.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityProvider.java
new file mode 100644
index 0000000..dbb4a9e
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityProvider.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.config;
+
+import java.util.List;
+
+import java.beans.PropertyVetoException;
+import javax.validation.constraints.NotNull;
+
+import org.jvnet.hk2.config.Attribute;
+import org.jvnet.hk2.config.Configured;
+import org.jvnet.hk2.config.ConfigBeanProxy;
+import org.jvnet.hk2.config.Element;
+
+/**
+ * The configuration that is used by a security service to identify the
+ * set of security providers which are created and consumed by the service. 
+ */
+@Configured
+public interface SecurityProvider extends ConfigBeanProxy {
+    /**
+     * Gets the name of the security provider.
+     * The name represents the qualifier @Named given to the security provider. 
+     */
+    @Attribute
+    @NotNull
+    public String getName();
+    public void setName(String value) throws PropertyVetoException;
+
+    /**
+     * Gets the type of the security provider.
+     * The type represents a String used by the security service for the security provider interface.
+     */
+    @Attribute(required=true)
+    @NotNull
+    String getType();
+    void setType(String type) throws PropertyVetoException;
+
+    /**
+     * Gets the name of the security provider configuration instance.
+     * The provider name is used to reference specific provider configuration objects.
+     */
+    @Attribute(required=true, key=true)
+    @NotNull
+    String getProviderName();
+    void setProviderName(String name) throws PropertyVetoException;
+
+    /**
+     * Gets configuration object specific to the security provider implementation.
+     * Security provider configuration must extend the SecurityProviderConfig interface.
+     */
+    @Element("*")
+    List<SecurityProviderConfig> getSecurityProviderConfig();
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityProviderConfig.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityProviderConfig.java
new file mode 100644
index 0000000..f1be06b
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/config/SecurityProviderConfig.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.config;
+
+import java.beans.PropertyVetoException;
+
+import org.jvnet.hk2.config.Attribute;
+import org.jvnet.hk2.config.Configured;
+import org.jvnet.hk2.config.ConfigBeanProxy;
+
+/**
+ * Base interface for all security provider implementation configuration.
+ * 
+ * Security plugin configuration objects extend SecurityProviderConfig interface
+ * such that the configuration of the plugin can be associated with a specific
+ * security service configuration.
+ */
+@Configured
+public interface SecurityProviderConfig extends ConfigBeanProxy {
+    /**
+     * Gets the name of the security provider implementation.
+     */
+    @Attribute(required=true, key=true)
+    public String getName();
+    public void setName(String value) throws PropertyVetoException;
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/AuthenticationServiceFactory.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/AuthenticationServiceFactory.java
new file mode 100644
index 0000000..c8de27b
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/AuthenticationServiceFactory.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl;
+
+import java.security.AccessController;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.glassfish.hk2.api.Factory;
+import org.glassfish.hk2.api.ServiceLocator;
+
+import org.glassfish.security.services.common.PrivilegedLookup;
+import org.glassfish.security.services.common.Secure;
+import org.glassfish.security.services.common.StateManager;
+import org.glassfish.security.services.common.SecurityScope;
+
+import org.glassfish.security.services.api.authentication.AuthenticationService;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+
+/**
+ * The factory of AuthenticationService instances used by the SecurityScopeContext.
+ */
+@Singleton
+@Secure(accessPermissionName = "security/service/authentication")
+public class AuthenticationServiceFactory extends ServiceFactory implements Factory<AuthenticationService> {
+    
+    @Inject
+    private StateManager manager;
+
+    @Inject
+    private ServiceLocator serviceLocator;
+
+    @SecurityScope
+    public AuthenticationService provide() {
+        String currentState = manager.getCurrent();
+
+        // Get Service Instance
+        AuthenticationService atnService = AccessController.doPrivileged( 
+                new PrivilegedLookup<AuthenticationService>(
+                        serviceLocator, AuthenticationService.class));
+
+        // Get Service Configuration
+        org.glassfish.security.services.config.AuthenticationService atnConfiguration =
+            serviceLocator.getService(org.glassfish.security.services.config.AuthenticationService.class,currentState);
+
+        // Initialize Service
+        atnService.initialize(atnConfiguration);
+
+        return atnService;
+    }
+
+    @Override
+    public void dispose(AuthenticationService instance) {
+    }
+
+    /**
+     * Helper function to obtain the Authentication Service configuration from the Domain.
+     */
+    public static org.glassfish.security.services.config.AuthenticationService getAuthenticationServiceConfiguration(Domain domain) {
+		org.glassfish.security.services.config.AuthenticationService atnConfiguration =
+        	ServiceFactory.getSecurityServiceConfiguration(
+        			domain, org.glassfish.security.services.config.AuthenticationService.class);
+        return atnConfiguration;
+	}
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/AuthenticationServiceImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/AuthenticationServiceImpl.java
new file mode 100644
index 0000000..b5ea778
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/AuthenticationServiceImpl.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl;
+
+import java.io.IOException;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+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.AppConfigurationEntry;
+import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.glassfish.hk2.api.PostConstruct;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.internal.api.Globals;
+import org.glassfish.internal.api.ServerContext;
+import org.glassfish.security.services.api.authentication.AuthenticationService;
+import org.glassfish.security.services.api.authentication.ImpersonationService;
+import org.glassfish.security.services.config.LoginModuleConfig;
+import org.glassfish.security.services.config.SecurityConfiguration;
+import org.glassfish.security.services.config.SecurityProvider;
+import org.glassfish.security.services.config.SecurityProviderConfig;
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.security.services.common.Secure;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.security.auth.login.common.PasswordCredential;
+import com.sun.enterprise.security.auth.realm.RealmsManager;
+import com.sun.enterprise.security.common.AppservAccessController;
+
+/**
+ * The Authentication Service Implementation.
+ * 
+ * Use JAAS LoginContext with the LoginModule(s) specified by the service configuration.
+ */
+@Service
+@Singleton
+@Secure(accessPermissionName = "security/service/authentication")
+public class AuthenticationServiceImpl implements AuthenticationService, PostConstruct {
+	@Inject
+	private Domain domain;
+
+	@Inject
+	ServerContext serverContext;
+        
+        @Inject
+        private ServiceLocator locator;
+        
+        @Inject
+        private ImpersonationService impersonationService;
+        
+        private static final Logger LOG = Logger.getLogger(AuthenticationServiceImpl.class.getName());
+
+
+	// Authentication Service Configuration Information
+	private String name = null;
+	private String realmName = null;
+	private Configuration configuration = null;
+	private boolean usePasswordCredential = false;
+	private org.glassfish.security.services.config.AuthenticationService config = null;
+
+
+	/**
+	 * Initialize the Authentication Service configuration.
+	 * 
+	 * Create the JAAS Configuration using the specified LoginModule configurations
+	 */
+	@Override
+	public void initialize(SecurityConfiguration securityServiceConfiguration) {
+//            org.glassfish.security.services.config.AuthenticationService as = (org.glassfish.security.services.config.AuthenticationService) securityServiceConfiguration;
+//            LOG.info("*** AuthenticationServiceImpl auth svc file realm provider module class: ");
+//            for (SecurityProvider sp : as.getSecurityProviders()) {
+//                LOG.info("   *** Provider name/type" + sp.getName() + "/" + sp.getType());
+//                if (sp.getSecurityProviderConfig() == null) {
+//                    LOG.info("   *** getSecurityProviderConfig returned null");
+//                } else {
+//                    for (SecurityProviderConfig spc : sp.getSecurityProviderConfig()) {
+//                        LOG.info("      *** " + spc.getName());
+//                        if (sp.getType().equals("LoginModule")) {
+//                            LoginModuleConfig lmc = (LoginModuleConfig) spc;
+//                            LOG.info("      *** LoginModule config: class is " + lmc.getModuleClass());
+//                        }
+//                    }
+//                }
+//            }
+        config = (org.glassfish.security.services.config.AuthenticationService) securityServiceConfiguration;
+        if (config == null)
+        	return;
+
+        // JAAS LoginContext Name
+        name = config.getName();
+
+        // Determine if handling Realm password credential
+        usePasswordCredential = config.getUsePasswordCredential();
+
+        // Build JAAS Configuration based on the individual LoginModuleConfig settings
+        List<SecurityProvider> providers = config.getSecurityProviders();
+        if (providers != null) {
+    		ArrayList<AppConfigurationEntry> lmEntries = new ArrayList<AppConfigurationEntry>();
+        	for (SecurityProvider provider : providers) {
+
+        		// If the provider is a LoginModule look for the LoginModuleConfig
+        		if ("LoginModule".equalsIgnoreCase(provider.getType())) {
+        			List<SecurityProviderConfig> providerConfig = provider.getSecurityProviderConfig();
+        			if ((providerConfig != null) && (!providerConfig.isEmpty())) {
+
+        				// Create the JAAS AppConfigurationEntry from the LoginModule settings
+        				LoginModuleConfig lmConfig = (LoginModuleConfig) providerConfig.get(0);
+        				Map<String, ?> lmOptions = lmConfig.getModuleOptions();
+        				lmEntries.add(new AppConfigurationEntry(lmConfig.getModuleClass(),
+        						getLoginModuleControlFlag(lmConfig.getControlFlag()),lmOptions));
+
+        				// Obtain the Realm name for password credential from the LoginModule options
+        				// Use the first LoginModule with auth-realm (i.e. unable to stack Realms)
+        				if (usePasswordCredential && (realmName == null)) {
+        					String authRealm = (String) lmOptions.get("auth-realm");
+        					if ((authRealm != null) && (!authRealm.isEmpty()))
+    							realmName = authRealm;
+        				}
+        			}
+        		}
+        	}
+        	if (!lmEntries.isEmpty())
+        		configuration = new AuthenticationJaasConfiguration(name,lmEntries);
+        }
+
+        // If required, initialize the currently configured Realm instances
+        // TODO - Reconcile initialization with SecurityLifeCycle
+        if (usePasswordCredential && (realmName != null)) {
+        	RealmsManager realmsManager = locator.getService(RealmsManager.class);
+        	realmsManager.createRealms();
+        }
+    }
+
+	@Override
+	public Subject login(String username, char[] password, Subject subject)
+			throws LoginException {
+		CallbackHandler cbh = new AuthenticationCallbackHandler(username, password);
+		return loginEx(cbh, subject);
+	}
+
+	@Override
+	public Subject login(CallbackHandler cbh, Subject subject)
+			throws LoginException {
+		if (cbh == null)
+			throw new LoginException("AuthenticationService: JAAS CallbackHandler not supplied");
+
+		// TODO - Wrap CallbackHandler to obtain name for auditing
+		return loginEx(cbh, subject);
+	}
+
+	private Subject loginEx(CallbackHandler handler, Subject subject)
+			throws LoginException {
+		// Use the supplied Subject or create a new Subject
+		Subject _subject = subject;
+		if (_subject == null)
+			_subject = new Subject();
+
+		ClassLoader tcl = null;
+		boolean restoreTcl = false;
+		try {
+			// Unable to login without a JAAS Configuration instance
+			// TODO - Dynamic configuration handling?
+			if (configuration == null) {
+				throw new UnsupportedOperationException(
+						"JAAS Configuration setup incomplete, unable to perform login");
+			}
+
+			// Setup the PasswordCredential for the Realm LoginModules when configured
+			if (usePasswordCredential) {
+				setupPasswordCredential(_subject, handler);
+			}
+
+			// When needed, setup the Context ClassLoader so JAAS can load the LoginModule(s)
+			tcl = (ClassLoader) AppservAccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+				public ClassLoader run() {
+					return Thread.currentThread().getContextClassLoader();
+				}
+			});
+			final ClassLoader ccl = serverContext.getCommonClassLoader();
+			if (!ccl.equals(tcl)) {
+				AppservAccessController.doPrivileged(new PrivilegedAction<Object>() {
+					public Object run() {
+						Thread.currentThread().setContextClassLoader(ccl);
+						return null;
+					}
+				});
+				restoreTcl = true;
+			}
+
+			// Perform the login via the JAAS LoginContext
+			LoginContext context = new LoginContext(name, _subject, handler, configuration);
+			context.login();
+		} catch (Exception exc) {
+			// TODO - Address Audit/Log/Debug handling options
+			if (exc instanceof LoginException)
+				throw (LoginException) exc;
+
+			throw (LoginException) new LoginException(
+					"AuthenticationService: "+ exc.getMessage()).initCause(exc);
+		} finally {
+			if (restoreTcl) {
+				final ClassLoader cl = tcl;
+				AppservAccessController.doPrivileged(new PrivilegedAction<Object>() {
+					public Object run() {
+						Thread.currentThread().setContextClassLoader(cl);
+						return null;
+					}
+				});
+			}
+		}
+
+		// Return the Subject that was logged in
+		return _subject;
+	}
+
+	@Override
+	public Subject impersonate(String user, String[] groups, Subject subject, boolean virtual)
+			throws LoginException {
+	  return impersonationService.impersonate(user, groups, subject, virtual);
+	}
+
+	/**
+	 * Handle lookup of authentication service configuration and initialization.
+	 * If no service is configured the service run-time will throw exceptions.
+	 * 
+	 * Addresses alternate configuration handling until adopt @Proxiable support. 
+	 */
+	@Override
+	public void postConstruct() {
+            /*
+             * Realm-related classes uses Globals (they are not services)
+             * so make sure it is set up.
+             */
+            if (Globals.getDefaultBaseServiceLocator() == null) {
+                Globals.setDefaultHabitat(locator);
+            }
+            // TODO - Dynamic configuration changes?
+		initialize(AuthenticationServiceFactory.getAuthenticationServiceConfiguration(domain));
+	}
+
+	/**
+	 * A PasswordCredential object is needed when using the existing Realm LoginModules.
+	 * 
+	 * Unless the CallbackHandler is from the AuthenticationService obtain the name
+	 * and password from the supplied JAAS CallbackHandler directly. Establishing the
+	 * PasswordCredential in the Subject is determined by service configuration.
+	 * 
+	 * @throws LoginException when unable to obtain data from the CallbackHandler 
+	 */
+	private void setupPasswordCredential(Subject subject, CallbackHandler callbackHandler)
+			throws LoginException {
+		String username = null;
+		char[] password = null;
+
+		// Obtain the username and password for the PasswordCredential
+		if (callbackHandler instanceof AuthenticationCallbackHandler) {
+			username = ((AuthenticationCallbackHandler) callbackHandler).getUsername();
+			password = ((AuthenticationCallbackHandler) callbackHandler).getPassword();
+		}
+		else {
+			// Use the supplied callback handler to obtain the PasswordCredential information
+			// TODO - How does this impact Audit ability to get name?
+			Callback[] callbacks = new Callback[2];
+			callbacks[0] = new NameCallback("username: ");
+			callbacks[1] = new PasswordCallback("password: ", false);
+			try {
+				callbackHandler.handle(callbacks);
+				username = ((NameCallback) callbacks[0]).getName();
+				password = ((PasswordCallback) callbacks[1]).getPassword();
+			} catch (IOException ioe) {
+				throw (LoginException) new LoginException("AuthenticationService unable to create PasswordCredential: "+ ioe.getMessage()).initCause(ioe);
+			} catch (UnsupportedCallbackException uce) {
+				throw (LoginException) new LoginException("AuthenticationService unable to create PasswordCredential: "+ uce.getMessage()).initCause(uce);
+			}			
+		}
+
+		// Add the PasswordCredential to the Subject
+		final Subject s = subject;
+		final PasswordCredential pc = new PasswordCredential(username, password, realmName);
+		AppservAccessController.doPrivileged(new PrivilegedAction<Object>() {
+			public Object run() {
+				s.getPrivateCredentials().add(pc);
+				return null;
+			}
+		});
+	}
+
+	/**
+	 * Convert the String setting to the JAAS LoginModuleControlFlag.
+	 * An unknown or null flag value is treated as LoginModuleControlFlag.REQUIRED.
+	 */
+	private LoginModuleControlFlag getLoginModuleControlFlag(String controlFlag) {
+		LoginModuleControlFlag flag = LoginModuleControlFlag.REQUIRED;
+		// TODO - Handle invalid control flag?
+		if (controlFlag != null) {
+			if ("required".equalsIgnoreCase(controlFlag))
+				return flag;
+			// Check additional flag types
+			if ("sufficient".equalsIgnoreCase(controlFlag))
+				flag = LoginModuleControlFlag.SUFFICIENT;
+			else if ("optional".equalsIgnoreCase(controlFlag))
+				flag = LoginModuleControlFlag.OPTIONAL;
+			else if ("requisite".equalsIgnoreCase(controlFlag))
+				flag = LoginModuleControlFlag.REQUISITE;
+		}
+		return flag;
+	}
+
+	/**
+	 * The Authentication Service CallbackHandler implementation.
+	 *  
+	 * Facilitates use of the standard JAAS NameCallback and PasswordCallback.
+	 */
+	private static class AuthenticationCallbackHandler implements CallbackHandler {
+		private String user;
+		private char[] pass;
+
+		public AuthenticationCallbackHandler(String username, char[] password) {
+			user = username;
+			pass = password;
+		}
+
+		protected String getUsername() { return user; }
+		protected char[] getPassword() { return pass; }
+
+		@Override
+		public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
+			for (int i = 0; i < callbacks.length; i++) {
+				if (callbacks[i] instanceof NameCallback)
+					((NameCallback) callbacks[i]).setName(user);
+				else if (callbacks[i] instanceof PasswordCallback)
+					((PasswordCallback) callbacks[i]).setPassword(pass);
+				else
+					// TODO - Have configuration setting for throwing exception
+					throw new UnsupportedCallbackException(callbacks[i],
+							"AuthenticationCallbackHandler: Unrecognized Callback "
+							+ callbacks[i].getClass().getName());
+			}
+		}
+	}
+
+	/**
+	 * The Authentication Service JAAS Configuration implementation.
+	 *  
+	 * Facilitates the use of JAAS LoginContext with Authentication Service LoginModule configuration.
+	 */
+	private static class AuthenticationJaasConfiguration extends Configuration {
+		private String configurationName;
+		private AppConfigurationEntry[] lmEntries;
+
+		/**
+		 * Create the JAAS Configuration instance used by the Authentication Service.
+		 */
+		private AuthenticationJaasConfiguration(String name, ArrayList<AppConfigurationEntry> entries) {
+			configurationName = name;
+			lmEntries = entries.toArray(new AppConfigurationEntry[entries.size()]);
+		}
+
+		/**
+		 * Get the LoginModule(s) specified by the Authentication Service configuration.
+		 */
+		@Override
+		public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+			if (configurationName.equals(name))
+				return lmEntries;
+			else
+				return null;
+		}
+	}
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/ImpersonationServiceImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/ImpersonationServiceImpl.java
new file mode 100644
index 0000000..ca61211
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/ImpersonationServiceImpl.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl;
+
+import java.security.Principal;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.inject.Singleton;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
+import org.glassfish.security.common.Group;
+import org.glassfish.security.common.PrincipalImpl;
+import org.glassfish.security.services.api.authentication.ImpersonationService;
+import org.glassfish.security.services.common.Secure;
+import org.jvnet.hk2.annotations.Service;
+
+/**
+ * The Impersonation Service Implementation.
+ * 
+ * @author jazheng
+ */
+@Service(name="impersonationService")
+@Singleton
+@Secure(accessPermissionName = "security/service/impersonation/simple")
+public class ImpersonationServiceImpl implements ImpersonationService {
+
+  static final Logger LOG = Logger
+      .getLogger(ImpersonationServiceImpl.class.getName());
+
+  @Override
+  public Subject impersonate(String user, String[] groups, Subject subject,
+      boolean virtual) throws LoginException {
+
+    // Use the supplied Subject or create a new Subject
+    final Subject _subject = 
+      (subject != null)? subject: new Subject();
+    
+    if (user == null || user.isEmpty()) {
+      return _subject;
+    }
+    
+    // TODO - Add support for virtual = false after IdentityManager
+    // is available in open source 
+    if (!virtual) {
+      throw new UnsupportedOperationException(
+          "Use of non-virtual parameter is not supported");
+    } else {
+      // Build the Subject
+      Set<Principal> principals = _subject.getPrincipals();
+      principals.add(new PrincipalImpl(user));
+      if (groups != null) {
+        for (String group: groups) {
+          principals.add(new Group(group));
+        }
+      }
+    }
+ 
+    // Return the impersonated Subject
+    return _subject;
+  }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/JCEKSDomainPasswordAliasStore.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/JCEKSDomainPasswordAliasStore.java
new file mode 100644
index 0000000..03310cc
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/JCEKSDomainPasswordAliasStore.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl;
+
+import com.sun.enterprise.security.store.DomainScopedPasswordAliasStore;
+import com.sun.enterprise.security.store.IdentityManagement;
+import com.sun.enterprise.util.SystemPropertyConstants;
+import java.io.File;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.glassfish.hk2.api.PerLookup;
+import org.glassfish.security.services.common.Secure;
+import org.jvnet.hk2.annotations.Optional;
+import org.jvnet.hk2.annotations.Service;
+
+/**
+ * Exposes as a service the JCEKS implementation of the
+ * domain-scoped password alias store.
+ * @author tjquinn
+ */
+@Service
+@Named("JCEKS")
+@PerLookup
+@Secure(accessPermissionName = "security/service/credential/provider/jceks")
+public class JCEKSDomainPasswordAliasStore extends JCEKSPasswordAliasStore implements DomainScopedPasswordAliasStore  {
+    
+    private static final String PASSWORD_ALIAS_KEYSTORE = "domain-passwords";
+
+    @Inject @Optional
+    private IdentityManagement idm;
+    
+    @PostConstruct
+    private void initStore() {
+        try {
+            init(pathToDomainAliasStore(), getMasterPassword());
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+    
+    private char[] getMasterPassword() {
+        return idm == null ? null : idm.getMasterPassword();
+    }
+    
+    private static String pathToDomainAliasStore() {
+        return System.getProperty(SystemPropertyConstants.INSTANCE_ROOT_PROPERTY) +
+                File.separator + "config" + File.separator + PASSWORD_ALIAS_KEYSTORE;
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/JCEKSPasswordAliasStore.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/JCEKSPasswordAliasStore.java
new file mode 100644
index 0000000..971427b
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/JCEKSPasswordAliasStore.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl;
+
+import com.sun.enterprise.security.store.PasswordAdapter;
+import com.sun.enterprise.util.Utility;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.crypto.SecretKey;
+import org.glassfish.api.admin.PasswordAliasStore;
+
+/**
+ * Provides the PasswordAliasStore behavior using a JCEKS keystore.
+ * <p>
+ * The keystore is actually managed by the PasswordAdapter, to which
+ * this implementation currently delegates its work.  
+ * <p>
+ * Note that this service is currently per-lookup.  This is so that each
+ * use of the alias store gets the current on-disk information.  Ideally we can change this
+ * when we can use Java 7 features, including the WatchService feature.  
+ * <p>
+ * This class's methods are not
+ * synchronized because the PasswordAdapter's methods are.  If this implementation
+ * changes so that it no longer delegates to those synchronized PasswordAdapter
+ * methods, then make sure that the implementation is thread-safe.
+ * <p>
+ * Note that the domain-scoped password alias store service class extends this
+ * class.  As a service, that class will be instantiated using the no-args 
+ * constructor.  So the actual initialization of the class occurs in the init
+ * method.  The domain-scoped service class invokes the init method itself.
+ * Any code that needs to create some other alias store can use the newInstance
+ * method to provide the location of the alias store file and the password.
+ * 
+ * @author tjquinn
+ */
+public class JCEKSPasswordAliasStore implements PasswordAliasStore {
+
+    private final static Charset utf8 = Charset.forName("UTF-8");
+    
+    private PasswordAdapter pa = null;
+    private String pathToAliasStore;
+    private char[] storePassword;
+    
+    protected final void init(final String pathToAliasStore, final char[] storePassword) {
+        this.pathToAliasStore = pathToAliasStore;
+        this.storePassword = storePassword;
+    }
+    
+    private synchronized PasswordAdapter pa() {
+        if (pa == null) {
+            try {
+                pa = new PasswordAdapter(pathToAliasStore, storePassword);
+            } catch (Exception ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+        return pa;
+    }
+    
+    public static JCEKSPasswordAliasStore newInstance(final String pathToAliasStore, final char[] storePassword) {
+        final JCEKSPasswordAliasStore result = new JCEKSPasswordAliasStore();
+        result.init(pathToAliasStore, storePassword);
+        return result;
+    }
+    
+    @Override
+    public void clear() {
+        try {
+            for (Enumeration<String> aliasEnum = pa().getAliases(); aliasEnum.hasMoreElements(); ) {
+                pa().removeAlias(aliasEnum.nextElement());
+            }
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    public void put(String alias, char[] password) {
+        final CharBuffer charBuffer = CharBuffer.wrap(password);
+        final ByteBuffer byteBuffer = utf8.encode(charBuffer);
+        try {
+            pa().setPasswordForAlias(alias, Utility.toByteArray(byteBuffer));
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    public void putAll(PasswordAliasStore otherStore) {
+        final Map<String,char[]> entries = new HashMap<String,char[]>();
+        for (Iterator<String> aliasIt = otherStore.keys(); aliasIt.hasNext();) {
+            final String alias = aliasIt.next();
+            entries.put(alias, otherStore.get(alias));
+        }
+        putAll(entries);
+    }
+
+    @Override
+    public void putAll(Map<String, char[]> settings) {
+        for (Map.Entry<String,char[]> entry : settings.entrySet()) {
+            put(entry.getKey(), entry.getValue());
+        }
+        settings.clear();
+    }
+
+    @Override
+    public void remove(String alias) {
+        try {
+            pa().removeAlias(alias);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    public boolean containsKey(String alias) {
+        try {
+            return pa().aliasExists(alias);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    public char[] get(String alias) {
+        try {
+            final SecretKey secretKey = pa().getPasswordSecretKeyForAlias(alias);
+            final ByteBuffer byteBuffer = ByteBuffer.wrap(secretKey.getEncoded());
+            return Utility.toCharArray(utf8.decode(byteBuffer));
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    @Override
+    public Iterator<String> keys() {
+        final List<String> keys = new ArrayList<String>();
+        try {
+            for (Enumeration<String> aliases = pa().getAliases(); aliases.hasMoreElements(); keys.add(aliases.nextElement())) {}
+            return keys.iterator();
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    public int size() {
+        try {
+            int size = 0;
+            for (Enumeration<String> aliases = pa().getAliases(); aliases.hasMoreElements(); size++, aliases.nextElement() ) {}
+            return size;
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/NucleusInternalSystemAdministrator.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/NucleusInternalSystemAdministrator.java
new file mode 100644
index 0000000..0907598
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/NucleusInternalSystemAdministrator.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl;
+
+import javax.inject.Singleton;
+import org.glassfish.security.services.api.authentication.AbstractInternalSystemAdministrator;
+import org.glassfish.security.services.api.authorization.AuthorizationAdminConstants;
+import org.jvnet.hk2.annotations.Service;
+
+/**
+ * Nucleus (open-source) implementation of the InternalSystemAdministrator contract.
+ * 
+ * @author tjquinn
+ */
+@Service(name="nucleus")
+@Singleton
+public class NucleusInternalSystemAdministrator extends AbstractInternalSystemAdministrator {
+
+    @Override
+    protected String getInternalUsername() {
+        return "_InternalSystemAdministrator_";
+    }
+
+    @Override
+    protected String getAdminGroupName() {
+        return AuthorizationAdminConstants.ADMIN_GROUP;
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/ServiceFactory.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/ServiceFactory.java
new file mode 100644
index 0000000..8f772be
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/ServiceFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl;
+
+import java.util.List;
+
+import org.glassfish.security.services.config.SecurityConfigurations;
+import org.glassfish.security.services.config.SecurityConfiguration;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+
+/**
+ * The base security service factory class.
+ */
+public class ServiceFactory {
+	/**
+	 * Get the security service configuration for the specified service type.
+	 * 
+	 * Attempt to obtain the service configuration marked as default
+	 * otherwise use the first configured service instance.
+	 * 
+	 * @param domain The current Domain configuration object
+	 * @param type The type of the security service configuration
+	 * 
+	 * @return null when no service configurations are found
+	 */
+	public static <T extends SecurityConfiguration> T getSecurityServiceConfiguration(Domain domain, Class<T> type) {
+		T config = null;
+
+		// Look for security service configurations
+		SecurityConfigurations secConfigs = domain.getExtensionByType(SecurityConfigurations.class);
+		if (secConfigs != null) {
+			// Look for the service configuration marked default
+			config = secConfigs.getDefaultSecurityServiceByType(type);
+			if (config == null) {
+				// Obtain the first service configuration listed
+				List<T> configs = secConfigs.getSecurityServicesByType(type);
+				if (!configs.isEmpty())
+					config = configs.get(0);
+			}
+		}
+
+		// Return the service configuration
+		return config;
+	}
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/ServiceLogging.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/ServiceLogging.java
new file mode 100644
index 0000000..63c83c3
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/ServiceLogging.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl;
+
+import org.glassfish.logging.annotation.LogMessagesResourceBundle;
+import org.glassfish.logging.annotation.LoggerInfo;
+
+/**
+ * The security service logging class.
+ */
+public class ServiceLogging {
+	@LogMessagesResourceBundle
+	public static final String SHARED_LOGMESSAGE_RESOURCE = "org.glassfish.security.services.LogMessages";
+
+	@LoggerInfo(subsystem="SECSVCS", description="Security Services Logger", publish=true)
+	public static final String SEC_SVCS_LOGGER = "javax.enterprise.security.services";
+
+	@LoggerInfo(subsystem="SECPROV", description="Security Provider Logger", publish=true)
+	public static final String SEC_PROV_LOGGER = "javax.enterprise.security.services.provider";
+	
+	@LoggerInfo(subsystem="SECCMDS", description="Security Services Command Logger", publish=true)
+	public static final String SEC_COMMANDS_LOGGER = "javax.enterprise.security.services.commands";
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AuthorizationServiceImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AuthorizationServiceImpl.java
new file mode 100644
index 0000000..38ee6ff
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AuthorizationServiceImpl.java
@@ -0,0 +1,561 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import java.net.URI;
+import java.security.Permission;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.ProtectionDomain;
+import java.security.Policy;
+import java.security.CodeSource;
+import java.security.CodeSigner;
+import javax.security.auth.Subject;
+
+import org.glassfish.security.services.api.authorization.AuthorizationService;
+import org.glassfish.security.services.api.authorization.AzAction;
+import org.glassfish.security.services.api.authorization.AzResource;
+import org.glassfish.security.services.api.authorization.AzResult;
+import org.glassfish.security.services.api.authorization.AzSubject;
+import org.glassfish.security.services.api.context.SecurityContextService;
+import org.glassfish.security.services.common.PrivilegedLookup;
+import org.glassfish.security.services.common.Secure;
+import org.glassfish.security.services.config.SecurityConfiguration;
+import org.glassfish.security.services.impl.ServiceFactory;
+import org.glassfish.security.services.impl.ServiceLogging;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PostConstruct;
+import org.glassfish.hk2.api.ServiceLocator;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import org.glassfish.logging.annotation.LogMessageInfo;
+
+import org.glassfish.security.services.api.authorization.*;
+import org.glassfish.security.services.api.common.Attributes;
+import org.glassfish.security.services.config.SecurityProvider;
+import org.glassfish.security.services.spi.authorization.AuthorizationProvider;
+
+/**
+ * <code>AuthorizationServiceImpl</code> implements
+ * <code>{@link org.glassfish.security.services.api.authorization.AuthorizationService}</code>
+ * by delegating authorization decisions to configured
+ * <code>{@link org.glassfish.security.services.spi.AuthorizationProvider}</code>
+ * instances.
+ */
+@Service
+@Singleton
+@Secure(accessPermissionName = "security/service/authorization")
+public final class AuthorizationServiceImpl implements AuthorizationService, PostConstruct {
+    private static final Level DEBUG_LEVEL = Level.FINER;
+    private static final Logger logger =
+        Logger.getLogger(ServiceLogging.SEC_SVCS_LOGGER,ServiceLogging.SHARED_LOGMESSAGE_RESOURCE);
+    private static LocalStringManagerImpl localStrings =
+        new LocalStringManagerImpl(AuthorizationServiceImpl.class);
+    @Inject
+    private volatile Domain domain;
+
+    @Inject
+    private volatile ServiceLocator serviceLocator;
+    
+    private volatile org.glassfish.security.services.config.AuthorizationService atzSvCfg;
+
+    @Inject
+    private volatile SecurityContextService securityContextService;
+
+    private volatile SecurityProvider atzPrvConfig;
+    
+    private volatile AuthorizationProvider provider;
+    
+    private static final CodeSource NULL_CODESOURCE = new CodeSource(null, (CodeSigner[])null);
+
+    enum InitializationState {
+        NOT_INITIALIZED,
+        SUCCESS_INIT,
+        FAILED_INIT
+    }
+    private volatile InitializationState initialized = InitializationState.NOT_INITIALIZED;
+    private volatile String reasonInitFailed =
+    		localStrings.getLocalString("service.atz.never_init","Authorization Service never initialized.");
+
+    private final List<AzAttributeResolver> attributeResolvers =
+            Collections.synchronizedList(new java.util.ArrayList<AzAttributeResolver>());
+
+	private boolean isDebug() {
+		return logger.isLoggable(DEBUG_LEVEL);
+	}
+
+    /**
+     * Initialize the security service instance with the specific security service configuration.
+     *
+     * @see org.glassfish.security.services.api.SecurityService#initialize
+     */
+    @Override
+    public void initialize(final SecurityConfiguration securityServiceConfiguration) {
+
+        if ( InitializationState.NOT_INITIALIZED != initialized ) {
+            return;
+        }
+
+        try {
+            // Get service level config
+            if ( !( securityServiceConfiguration instanceof org.glassfish.security.services.config.AuthorizationService ) ) {
+                throw new IllegalStateException(
+                		localStrings.getLocalString("service.atz.not_config","The Authorization service is not configured in the domain configuration file."));
+            }
+            atzSvCfg = (org.glassfish.security.services.config.AuthorizationService) securityServiceConfiguration;
+
+            // Get provider level config, consider only one provider for now and take the first provider found.
+            List<SecurityProvider> providersConfig = atzSvCfg.getSecurityProviders();
+            if ( (providersConfig == null) || ( (atzPrvConfig = providersConfig.get(0)) == null ) ) {
+                throw new IllegalStateException(
+                		localStrings.getLocalString("service.atz.no_prov_config","No provider configured for the Authorization service in the domain configuration file."));
+            }
+
+            // Get the provider
+            final String providerName = atzPrvConfig.getName();
+            if ( isDebug() ) {
+                logger.log(DEBUG_LEVEL, "Attempting to get Authorization provider \"{0}\".", providerName );
+            }
+            provider =  AccessController.doPrivileged(
+                            new PrivilegedLookup<AuthorizationProvider>(
+                                    serviceLocator, AuthorizationProvider.class, providerName)); 
+            if (provider == null) {
+                throw new IllegalStateException(
+                    localStrings.getLocalString("service.atz.not_provider","Authorization Provider {0} not found.", providerName));
+            }
+
+            // Initialize the provider
+            provider.initialize(atzPrvConfig);
+
+            initialized = InitializationState.SUCCESS_INIT;
+            reasonInitFailed = null;
+
+            logger.log(Level.INFO, ATZSVC_INITIALIZED);
+
+        } catch ( Exception e ) {
+            String eMsg = e.getMessage();
+            String eClass = e.getClass().getName();
+            reasonInitFailed = localStrings.getLocalString("service.atz.init_failed",
+                "Authorization Service initialization failed, exception {0}, message {1}", eClass, eMsg);
+            logger.log(Level.WARNING, ATZSVC_INIT_FAILED, new Object[] {eClass, eMsg});
+            throw new RuntimeException( reasonInitFailed, e );
+        } finally {
+            if ( InitializationState.SUCCESS_INIT != initialized ) {
+                initialized = InitializationState.FAILED_INIT;
+            }
+        }
+    }
+
+    /**
+     * Determine whether the given Subject has been granted the specified Permission
+     * by delegating to the configured java.security.Policy object.  This method is
+     * a high-level convenience method that tests for a Subject-based permission
+     * grant without reference to the AccessControlContext of the caller.
+     *
+     * In addition, this method isolates the query from the underlying Policy configuration
+     * model.  It could, for example, multiplex queries across multiple instances of Policy
+     * configured in an implementation-specific way such that different threads, or different
+     * applications, query different Policy objects.  The initial implementation simply
+     * delegates to the configured Policy as defined by Java SE.
+     *
+     * @param subject The Subject for which permission is being tested.
+     * @param permission The Permission being queried.
+     * @return True or false, depending on whether the specified Permission
+     * is granted to the Subject by the configured Policy.
+     * @throws IllegalArgumentException Given null or illegal subject or permission
+     * @see AuthorizationService#isPermissionGranted(javax.security.auth.Subject, java.security.Permission)
+     */
+    @Override
+	public boolean isPermissionGranted(
+        final Subject subject, final Permission permission) {
+
+        // Validate inputs
+        if ( null == subject ) {
+            throw new IllegalArgumentException(localStrings.getLocalString("service.subject_null", "The supplied Subject is null."));
+        }
+        if ( null == permission ) {
+            throw new IllegalArgumentException(localStrings.getLocalString("service.permission_null","The supplied Permission is null."));
+        }
+
+        Set<Principal> principalset = subject.getPrincipals();
+        Principal[] principalAr = (principalset.size() == 0) ? null : principalset.toArray(new Principal[principalset.size()]);
+        ProtectionDomain pd = new ProtectionDomain(NULL_CODESOURCE, null, null, principalAr); 
+        Policy policy = Policy.getPolicy();
+        boolean result = policy.implies(pd, permission);
+
+        return result;
+	}
+
+
+    /**
+     * Determine whether the given Subject is authorized to access the given resource,
+     * specified by a URI.
+     *
+     * @param subject The Subject being tested.
+     * @param resource URI of the resource being tested.
+     * @return True or false, depending on whether the access is authorized.
+     * @throws IllegalArgumentException Given null or illegal subject or resource
+     * @throws IllegalStateException Service was not initialized.
+     * @see AuthorizationService#isAuthorized(javax.security.auth.Subject, java.net.URI)
+     */
+    @Override
+	public boolean isAuthorized(Subject subject, URI resource) {
+		return isAuthorized(subject, resource, null);
+	}
+
+
+    /**
+     * Determine whether the given Subject is authorized to access the given resource,
+     * specified by a URI.
+     *
+     * @param subject The Subject being tested.
+     * @param resource URI of the resource being tested.
+     * @param action The action, with respect to the resource parameter,
+     * for which authorization is desired. To check authorization for all actions,
+     * action is represented by null or "*".
+     * @return True or false, depending on whether the access is authorized.
+     * @throws IllegalArgumentException Given null or illegal subject or resource
+     * @throws IllegalStateException Service was not initialized.
+     * @see AuthorizationService#isAuthorized(javax.security.auth.Subject, java.net.URI, String)
+     */
+    @Override
+    public boolean isAuthorized(final Subject subject, final URI resource, final String action) {
+
+        checkServiceAvailability();
+
+        // Validate inputs
+        if ( null == subject ) {
+            throw new IllegalArgumentException(localStrings.getLocalString("service.subject_null", "The supplied Subject is null."));
+        }
+        if ( null == resource ) {
+            throw new IllegalArgumentException(localStrings.getLocalString("service.resource_null", "The supplied Resource is null."));
+        }
+        // Note: null action means all actions (i.e., no action condition)
+
+        // Convert parameters
+        AzSubject azSubject = makeAzSubject( subject );
+        AzResource azResource = makeAzResource( resource );
+        AzAction azAction = makeAzAction(action);
+
+        AzResult azResult = getAuthorizationDecision(azSubject, azResource, azAction);
+
+        boolean result =
+            AzResult.Status.OK.equals(azResult.getStatus()) &&
+            AzResult.Decision.PERMIT.equals(azResult.getDecision());
+        return result;
+	}
+
+
+    /**
+     * The primary authorization method.  The isAuthorized() methods call this method
+     * after converting their arguments into the appropriate attribute collection type.
+     * It returns a full AzResult, including authorization status, decision, and
+     * obligations.
+     *
+     * This method performs two steps prior to invoking the configured AuthorizationProvider
+     * to evaluate the request:  First, it acquires the current AzEnvironment attributes by
+     * calling the Security Context service.  Second, it calls the Role Mapping service to
+     * determine which roles the subject has, and adds the resulting role attributes into
+     * the AzSubject.
+     *
+     * @param subject The attributes collection representing the Subject for which an authorization
+     * decision is requested.
+     * @param resource The attributes collection representing the resource for which access is
+     * being requested.
+     * @param action  The attributes collection representing the action, with respect to the resource,
+     * for which access is being requested.  A null action is interpreted as all
+     * actions, however all actions may also be represented by the AzAction instance.
+     * See <code>{@link org.glassfish.security.services.api.authorization.AzAction}</code>.
+     * @return The AzResult indicating the result of the access decision.
+     * @throws IllegalArgumentException Given null or illegal subject or resource
+     * @throws IllegalStateException Service was not initialized.
+     * @see AuthorizationService#getAuthorizationDecision
+     */
+    @Override
+    public AzResult getAuthorizationDecision(
+            final AzSubject subject,
+            final AzResource resource,
+            final AzAction action) {
+
+        checkServiceAvailability();
+
+        // Validate inputs
+        if ( null == subject ) {
+            throw new IllegalArgumentException(localStrings.getLocalString("service.subject_null", "The supplied Subject is null."));
+        }
+        if ( null == resource ) {
+            throw new IllegalArgumentException(localStrings.getLocalString("service.resource_null", "The supplied Resource is null."));
+        }
+
+        // TODO: setup current AzEnvironment instance. Should a null or empty instance to represent current environment?
+        final AzEnvironment env = new AzEnvironmentImpl();
+        final Attributes attrs = securityContextService.getEnvironmentAttributes();
+        for (String attrName : attrs.getAttributeNames()) {
+            env.addAttribute(attrName, attrs.getAttributeValue(attrName), true);
+        }
+
+        AzResult result =  provider.getAuthorizationDecision(
+            subject, resource, action, env, attributeResolvers );
+
+        if ( isDebug() ) {
+            logger.log(DEBUG_LEVEL,
+            "Authorization Service result for {0} was {1}.",
+            new String[]{ subject.toString(), result.toString() } );
+        }
+
+        return result;
+	}
+
+
+    /**
+     * Convert a Java Subject into a typed attributes collection.
+     *
+     * @param subject The Subject to convert.
+     * @return The resulting AzSubject.
+     * @throws IllegalArgumentException Given null or illegal subject
+     * @see AuthorizationService#makeAzSubject(javax.security.auth.Subject)
+     */
+    @Override
+    public AzSubject makeAzSubject(final Subject subject) {
+        AzSubject azs = new AzSubjectImpl(subject);
+        return azs;
+    }
+
+
+    /**
+     * Convert a resource, expressed as a URI, into a typed attributes collection.
+     * <p>
+     * Query parameters in the given URI are appended to this
+     * <code>AzResource</code> instance attributes collection.
+     *
+     * @param resource The URI to convert.
+     * @return The resulting AzResource.
+     * @see AuthorizationService#makeAzResource(java.net.URI)
+     * @throws IllegalArgumentException Given null or illegal resource
+     */
+    @Override
+    public AzResource makeAzResource(final URI resource) {
+        AzResource azr = new AzResourceImpl( resource );
+        return azr;
+    }
+
+
+    /**
+     * Convert an action, expressed as a String, into a typed attributes collection.
+     *
+     * @param action The action to convert. null or "*" represents all actions.
+     * @return The resulting AzAction.
+     * @see AuthorizationService#makeAzAction(String)
+     */
+    @Override
+    public AzAction makeAzAction(final String action) {
+        AzAction aza = new AzActionImpl( action );
+        return aza;
+    }
+
+
+    /**
+     * Find an existing PolicyDeploymentContext, or create a new one if one does not
+     * already exist for the specified appContext.  The context will be returned in
+     * an "open" state, and will stay that way until commit() or delete() is called.
+     *
+     * @param appContext The application context for which the PolicyDeploymentContext
+     * is desired.
+     * @return The resulting PolicyDeploymentContext,
+     * null if the configured providers do not support this feature.
+     * @throws IllegalStateException Service was not initialized.
+     * @see AuthorizationService#findOrCreateDeploymentContext(String)
+     */
+    @Override
+    public PolicyDeploymentContext findOrCreateDeploymentContext(
+            final String appContext) {
+
+        checkServiceAvailability();
+
+        // TODO: Unsupported Operation Exception undocumented, not optional
+
+        return provider.findOrCreateDeploymentContext(appContext);
+	}
+
+
+    /**
+     * Called when the instance has been created and the component is
+     * about to be place into commission.
+     * <p>
+     * The component has been injected with any dependency and
+     * will be placed into commission by the subsystem.
+     * <p>
+     * Hk2 will catch all unchecked exceptions,
+     * and will consequently cause the backing inhabitant to be released.
+     *
+     * @see org.glassfish.hk2.api.PostConstruct#postConstruct()
+     */
+    @Override
+    public void postConstruct() {
+
+        org.glassfish.security.services.config.AuthorizationService atzConfiguration =
+                ServiceFactory.getSecurityServiceConfiguration(
+                        domain, org.glassfish.security.services.config.AuthorizationService.class);
+
+        initialize(atzConfiguration);
+    }
+
+
+    /**
+     * Appends the given <code>{@link org.glassfish.security.services.api.authorization.AzAttributeResolver}</code>
+     * instance to the internal ordered list of <code>AzAttributeResolver</code> instances,
+     * if not currently in the list based on
+     * <code>{@link org.glassfish.security.services.api.authorization.AzAttributeResolver#equals}</code>.
+     *
+     * @param resolver The <code>AzAttributeResolver</code> instance to append.
+     * @return true if the <code>AzAttributeResolver</code> was added,
+     * false if the <code>AzAttributeResolver</code> was already in the list.
+     * @throws IllegalArgumentException Given AzAttributeResolver was null.
+     * @see AuthorizationService#appendAttributeResolver
+     */
+    @Override
+    public boolean appendAttributeResolver(AzAttributeResolver resolver) {
+        if ( null == resolver ) {
+            throw new IllegalArgumentException(localStrings.getLocalString("service.resolver_null","The supplied Attribute Resolver is null."));
+        }
+        synchronized ( attributeResolvers ) {
+            if ( !attributeResolvers.contains( resolver ) ) {
+                attributeResolvers.add( resolver );
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * Replaces the internal list of <code>AttributeResolver</code> instances
+     * with the given list. If multiple equivalent instances exist in the given list,
+     * only the first such instance will be inserted.
+     *
+     * @param resolverList Replacement list of <code>AzAttributeResolver</code> instances
+     * @throws IllegalArgumentException Given AzAttributeResolver list was null.
+     * @see AuthorizationService#setAttributeResolvers
+     */
+    @Override
+    public void setAttributeResolvers(List<AzAttributeResolver> resolverList) {
+        if ( null == resolverList ) {
+            throw new IllegalArgumentException(localStrings.getLocalString("service.resolver_null","The supplied Attribute Resolver is null."));
+        }
+
+        synchronized ( attributeResolvers ) {
+            attributeResolvers.clear();
+            for ( AzAttributeResolver ar : resolverList ) {
+                if ( (null != ar) && !attributeResolvers.contains(ar) ) {
+                    attributeResolvers.add( ar );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Determines the current list of <code>AttributeResolver</code> instances,
+     * in execution order.
+     *
+     * @return  The current list of AttributeResolver instances,
+     * in execution order.
+     * @see AuthorizationService#getAttributeResolvers
+     */
+    @Override
+    public List<AzAttributeResolver> getAttributeResolvers() {
+        return new ArrayList<AzAttributeResolver>( attributeResolvers );
+    }
+
+
+    /**
+     * Removes all <code>AttributeResolver</code> instances from the current
+     * internal list of <code>AttributeResolver</code> instances.
+     *
+     * @return true if any <code>AttributeResolver</code> instances were removed,
+     * false if the list was empty.
+     * @see AuthorizationService#removeAllAttributeResolvers
+     */
+    @Override
+    public boolean removeAllAttributeResolvers() {
+        synchronized ( attributeResolvers ) {
+            if ( attributeResolvers.isEmpty() ) {
+                return false;
+            } else {
+                attributeResolvers.clear();
+                return true;
+            }
+        }
+    }
+
+
+    /**
+     * Determines whether this service has been initialized.
+     * @return The initialization state
+     */
+    final InitializationState getInitializationState() {
+        return initialized;
+    }
+
+
+    /**
+     * Determines the reason why the service failed to initialize.
+     * @return The reason why the service failed to initialize,
+     * null if initialization was successful or the failure reason was unknown.
+     */
+    final String getReasonInitializationFailed() {
+        return reasonInitFailed;
+    }
+
+
+    /**
+     * Checks whether this service is available.
+     * @throws IllegalStateException This service is not available.
+     */
+    final void checkServiceAvailability() {
+        if ( InitializationState.SUCCESS_INIT != getInitializationState() ) {
+            throw new IllegalStateException(
+                localStrings.getLocalString("service.atz.not_avail","The Authorization service is not available.") +
+                getReasonInitializationFailed() );
+        }
+    }
+
+	//
+	// Log Messages
+	//
+
+	@LogMessageInfo(
+			message = "Authorization Service has successfully initialized.",
+			level = "INFO")
+	private static final String ATZSVC_INITIALIZED = "SEC-SVCS-00100";
+
+	@LogMessageInfo(
+			message = "Authorization Service initialization failed, exception {0}, message {1}",
+			level = "WARNING")
+	private static final String ATZSVC_INIT_FAILED = "SEC-SVCS-00101";
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzActionImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzActionImpl.java
new file mode 100755
index 0000000..f206937
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzActionImpl.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import org.glassfish.security.services.api.authorization.AzAction;
+
+public final class AzActionImpl extends AzAttributesImpl implements AzAction {
+
+    private final String action;
+
+
+    /**
+     * Constructor
+     *
+     * @param action The represented action, null or "*" to represent all actions
+     */
+    public AzActionImpl( String action )  {
+        super( NAME );
+
+        if ( "*".equals( action ) ) {
+            action = null;
+        }
+        this.action = action;
+    }
+
+
+    /**
+     * Determines the action represented as a string.
+     * @return The represented action, null represents all actions
+     * @see org.glassfish.security.services.api.authorization.AzAction#getAction()
+     */
+    @Override
+    public String getAction() {
+        return action;
+    }
+
+
+    /**
+     * Determines the represented action, "*" represents all actions
+     * @return The represented action.
+     */
+    @Override
+    public String toString() {
+        return action == null ? "*" : action;
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzAttributesImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzAttributesImpl.java
new file mode 100755
index 0000000..9734ab5
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzAttributesImpl.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import org.glassfish.security.services.api.authorization.AzAttributes;
+import org.glassfish.security.services.impl.common.AttributesImpl;
+
+/**
+ * <code>AzAttributesImpl</code> implements AzAttributes to provide an abstract
+ * layer specifically for Authorization attributes.
+ */
+public abstract class AzAttributesImpl extends AttributesImpl implements AzAttributes {
+
+    private final String name;
+
+
+    /**
+     * Copy constructor
+     *
+     * @param other The copy source
+     */
+    public AzAttributesImpl( AzAttributesImpl other ) {
+        super( other );
+
+        this.name = other.getName();
+    }
+
+
+    /**
+     * Constructor
+     * @param name The name of this collection.
+     * @throws IllegalArgumentException Given name is null or empty
+     */
+    public AzAttributesImpl( String name ) {
+
+        if ( null == name ) {
+            throw new IllegalArgumentException( "Illegal null name given." );
+        }
+
+        name = name.trim();
+        if ( name.isEmpty() ) {
+            throw new IllegalArgumentException( "Illegal empty name given." );
+        }
+
+        this.name = name;
+    }
+
+    /**
+     * Determines a name to denote this collection of attributes.
+     * <p>
+     * For example, this name may be used to qualify attributes by collection
+     * type in XACML.
+     *
+     * @return The collection name
+     * @see org.glassfish.security.services.api.authorization.AzAttributes#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzEnvironmentImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzEnvironmentImpl.java
new file mode 100755
index 0000000..96c3cfb
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzEnvironmentImpl.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import org.glassfish.security.services.api.authorization.AzEnvironment;
+
+public final class AzEnvironmentImpl extends AzAttributesImpl implements AzEnvironment {
+
+    /**
+     * Constructor
+     */
+    public AzEnvironmentImpl() {
+        super( NAME );
+    }
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzObligationsImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzObligationsImpl.java
new file mode 100755
index 0000000..3937547
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzObligationsImpl.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import org.glassfish.security.services.api.authorization.AzObligations;
+
+public final class AzObligationsImpl extends AzAttributesImpl implements AzObligations {
+
+    /**
+     * Constructor
+     */
+    public AzObligationsImpl() {
+        super(NAME);
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzResourceImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzResourceImpl.java
new file mode 100755
index 0000000..aa729ef
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzResourceImpl.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import org.glassfish.logging.annotation.LogMessageInfo;
+import org.glassfish.security.services.api.authorization.AzResource;
+import org.glassfish.security.services.api.common.Attributes;
+import org.glassfish.security.services.impl.ServiceLogging;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLDecoder;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public final class AzResourceImpl extends AzAttributesImpl implements AzResource {
+
+
+    private static final Logger logger = Logger.getLogger(ServiceLogging.SEC_SVCS_LOGGER,ServiceLogging.SHARED_LOGMESSAGE_RESOURCE);
+
+    private static final boolean REPLACE = true;
+
+
+    private final URI uri;
+
+
+    /**
+     * Constructor
+     *
+     * @param resource The represented resource
+     * @throws IllegalArgumentException Given resource was null
+     */
+    public AzResourceImpl( URI resource )  {
+        super(NAME);
+
+        if ( null == resource ) {
+            throw new IllegalArgumentException("Illegal null resource URI.");
+        }
+        this.uri = resource;
+
+        // Dump the query parameters into the attribute map.
+        addAttributesFromUriQuery( uri, this, !REPLACE );
+    }
+
+
+    /**
+     * Determines the URI representing this resource.
+     * @return The URI representing this resource., never null.
+     */
+    @Override
+    public URI getUri() {
+        return uri;
+    }
+
+
+    /**
+     * Determines the URI used to initialize this resource.
+     * @return The URI used to initialize this resource.
+     */
+    @Override
+    public String toString() {
+        return uri.toString();
+    }
+
+
+    /**
+     * Yet another URI query parser, but this one knows how to populate
+     * <code>{@link org.glassfish.security.services.api.common.Attributes}</code>.
+     *
+     * @param uri The URI from which the query will be derived.
+     * @param attributes Attributes collection to populate
+     * @param replace true to replace entire attribute, false to append value to attribute.
+     * See <code>{@link org.glassfish.security.services.api.common.Attributes#addAttribute}</code>.
+     * @throws IllegalArgumentException URI or Attributes is null.
+     */
+    static void addAttributesFromUriQuery( URI uri, Attributes attributes, boolean replace ) {
+        if ( null == uri ) {
+            throw new IllegalArgumentException( "Illegal null URI." );
+        }
+        if ( null == attributes ) {
+            throw new IllegalArgumentException( "Illegal null Attributes." );
+        }
+
+        String query = uri.getRawQuery();
+        if ( ( null != query ) && ( query.length() > 0 ) ) {
+            String[] params = query.split( "&" );
+            if ( ( null != params ) && ( params.length > 0 ) ) {
+                for ( String nv : params ) {
+                    if ( (null == nv) || (nv.length() <= 0) )  {
+                        continue;
+                    }
+
+                    String name, value;
+                    int equalsPos = nv.indexOf( "=" );
+                    if ( -1 == equalsPos ) {
+                        name = decodeURI( nv );
+                        value = "";
+                    } else {
+                        name = decodeURI( nv.substring( 0, equalsPos ) );
+                        value = decodeURI( nv.substring( equalsPos + 1 ) );
+                    }
+
+                    attributes.addAttribute( name, value, replace );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * URI decode the input, assumes UTF-8 encoding.
+     *
+     * @param input The input to decode.
+     * @return The decoded input, null returns null.
+     */
+    static String decodeURI( String input ) {
+        if ( null == input ) {
+            return null;
+        }
+
+        String output = input;
+        try {
+            output = URLDecoder.decode(input, "UTF-8");
+        } catch ( UnsupportedEncodingException e ) {
+            if ( logger.isLoggable( Level.WARNING ) ) {
+                logger.log( Level.WARNING, URI_DECODING_ERROR, e.getLocalizedMessage() );
+            }
+        }
+
+        return output;
+    }
+    
+	@LogMessageInfo(
+			message = "Unable to decode URI: {0}.",
+			level = "WARNING")
+	private static final String URI_DECODING_ERROR = "SEC-SVCS-00102";
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzResultImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzResultImpl.java
new file mode 100755
index 0000000..cf907a7
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzResultImpl.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import org.glassfish.security.services.api.authorization.AzObligations;
+import org.glassfish.security.services.api.authorization.AzResult;
+
+import java.text.MessageFormat;
+
+public final class AzResultImpl implements AzResult {
+	
+	private final Decision decision;
+	private final Status status;
+	private final AzObligations obligations;
+	
+	public AzResultImpl(Decision d, Status s, AzObligations o) {
+		decision = d;
+		status = s;
+		obligations = o;
+	}
+
+	public Decision getDecision() {
+		return decision;
+	}
+
+	public Status getStatus() {
+		return status;
+	}
+
+	public AzObligations getObligations() {
+		return obligations;
+	}
+
+
+    @Override
+    public String toString() {
+        return MessageFormat.format("status={0}, decision=[1]",
+            status, decision);
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzSubjectImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzSubjectImpl.java
new file mode 100755
index 0000000..0980d4f
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/AzSubjectImpl.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import org.glassfish.security.services.api.authorization.AzSubject;
+
+import javax.security.auth.Subject;
+
+public final class AzSubjectImpl extends AzAttributesImpl implements AzSubject {
+
+    final private Subject subject;
+
+    /**
+     * Constructor
+     *
+     * @param subject The represented subject
+     * @throws IllegalArgumentException Given subject was null
+     */
+    public AzSubjectImpl( Subject subject )  {
+        super(NAME);
+
+        if ( null == subject ) {
+            throw new IllegalArgumentException("Illegal null Subject.");
+        }
+        this.subject = subject;
+    }
+
+
+    /**
+     * Determines the <code>{@link javax.security.auth.Subject}</code>
+     * represented by this AzSubject.
+     * @return The represented Subject.
+     */
+    @Override
+    public final Subject getSubject() {
+        return subject;
+    }
+
+
+    @Override
+    public String toString() {
+        return subject.toString();
+    }
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/RoleMappingServiceImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/RoleMappingServiceImpl.java
new file mode 100644
index 0000000..dda6d48
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/authorization/RoleMappingServiceImpl.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import java.net.URI;
+import java.security.AccessController;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.security.auth.Subject;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PostConstruct;
+import org.glassfish.hk2.api.ServiceLocator;
+
+import org.glassfish.security.services.api.authorization.AzAttributeResolver;
+import org.glassfish.security.services.api.authorization.AzResource;
+import org.glassfish.security.services.api.authorization.AzSubject;
+import org.glassfish.security.services.api.authorization.RoleMappingService;
+import org.glassfish.security.services.common.PrivilegedLookup;
+import org.glassfish.security.services.common.Secure;
+import org.glassfish.security.services.config.SecurityConfiguration;
+import org.glassfish.security.services.config.SecurityProvider;
+import org.glassfish.security.services.impl.ServiceFactory;
+import org.glassfish.security.services.impl.ServiceLogging;
+import org.glassfish.security.services.spi.authorization.RoleMappingProvider;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+
+import com.sun.enterprise.util.LocalStringManagerImpl;
+import org.glassfish.logging.annotation.LogMessageInfo;
+
+/**
+ * <code>RoleMappingServiceImpl</code> implements
+ * <code>{@link org.glassfish.security.services.api.authorization.RoleMappingService}</code>
+ * by delegating role mapping decisions to configured
+ * <code>{@link org.glassfish.security.services.spi.RoleMappingProvider}</code>
+ * instances.
+ */
+@Service
+@Singleton
+@Secure(accessPermissionName="security/service/rolemapper")
+public final class RoleMappingServiceImpl implements RoleMappingService, PostConstruct {
+	private static final Level DEBUG_LEVEL = Level.FINER;
+	private static final Logger logger =
+			Logger.getLogger(ServiceLogging.SEC_SVCS_LOGGER,ServiceLogging.SHARED_LOGMESSAGE_RESOURCE);
+	private static LocalStringManagerImpl localStrings =
+			new LocalStringManagerImpl(RoleMappingServiceImpl.class);
+
+	@Inject
+	private Domain domain;
+
+	@Inject
+	private ServiceLocator serviceLocator;
+
+	// Role Mapping Service Configuration Information
+	private org.glassfish.security.services.config.RoleMappingService config;
+	private RoleMappingProvider provider;
+
+	// Service lifecycle
+	enum InitializationState {
+		NOT_INITIALIZED,
+		SUCCESS_INIT,
+		FAILED_INIT
+	}
+	private volatile InitializationState initialized = InitializationState.NOT_INITIALIZED;
+	private volatile String reasonInitFailed = 
+			localStrings.getLocalString("service.role.not_config","The Role Mapping Service was not configured properly.");
+
+	final InitializationState getInitializationState() {
+		return initialized;
+	}
+
+	final String getReasonInitializationFailed() {
+		return reasonInitFailed;
+	}
+
+	final void checkServiceAvailability() {
+		if (InitializationState.SUCCESS_INIT != getInitializationState()) {
+			throw new IllegalStateException(
+					localStrings.getLocalString("service.role.not_avail","The Role Mapping Service is not available.")
+					+ getReasonInitializationFailed());
+		}
+	}
+
+	private final List<AzAttributeResolver> attributeResolvers =
+			Collections.synchronizedList(new java.util.ArrayList<AzAttributeResolver>());
+
+	private boolean isDebug() {
+		return logger.isLoggable(DEBUG_LEVEL);
+	}
+
+	// Helpers
+	private AzSubject makeAzSubject(final Subject subject) {
+		AzSubject azs = new AzSubjectImpl(subject);
+		return azs;
+	}
+
+	private AzResource makeAzResource(final URI resource) {
+		AzResource azr = new AzResourceImpl(resource);
+		return azr;
+	}
+
+	/**
+	 * Initialize the Role Mapping service with the configured role mapping provider.
+	 */
+	@Override
+	public void initialize(SecurityConfiguration securityServiceConfiguration) {
+		if (InitializationState.NOT_INITIALIZED != initialized) {
+			return;
+		}
+		try {
+			// Get the Role Mapping Service configuration
+			config = (org.glassfish.security.services.config.RoleMappingService) securityServiceConfiguration;
+			if (config != null) {
+				// Get the role mapping provider configuration
+				// Consider only one provider for now and take the first provider found!
+				List<SecurityProvider> providersConfig = config.getSecurityProviders();
+				SecurityProvider roleProviderConfig = null;
+				if (providersConfig != null) roleProviderConfig = providersConfig.get(0);
+				if (roleProviderConfig != null) {
+					// Get the provider
+					String providerName = roleProviderConfig.getName();
+					if (isDebug()) {
+						logger.log(DEBUG_LEVEL, "Attempting to get Role Mapping Provider \"{0}\".", providerName );
+					}
+					provider = AccessController.doPrivileged(
+					        new PrivilegedLookup<RoleMappingProvider>(serviceLocator, RoleMappingProvider.class, providerName) );    
+							
+					if (provider == null) {
+						throw new IllegalStateException(localStrings.getLocalString("service.role.not_provider",
+								"Role Mapping Provider {0} not found.", providerName));
+					}
+
+					// Initialize the provider
+					provider.initialize(roleProviderConfig);
+
+					// Service setup complete
+					initialized = InitializationState.SUCCESS_INIT;
+					reasonInitFailed = null;
+
+					// Log initialized
+					logger.log(Level.INFO, ROLEMAPSVC_INITIALIZED);
+				}
+			}
+		} catch (Exception e) {
+			String eMsg = e.getMessage();
+			String eClass = e.getClass().getName();
+			reasonInitFailed = localStrings.getLocalString("service.role.init_failed",
+					"Role Mapping Service initialization failed, exception {0}, message {1}", eClass, eMsg);
+			logger.log(Level.WARNING, ROLEMAPSVC_INIT_FAILED, new Object[] {eClass, eMsg});
+			throw new RuntimeException(reasonInitFailed, e);
+		} finally {
+			if (InitializationState.SUCCESS_INIT != initialized) {
+				initialized = InitializationState.FAILED_INIT;
+			}
+		}
+	}
+
+	/**
+	 * Determine the user's role by converting arguments into security authorization data types.
+	 * 
+	 * @see <code>{@link org.glassfish.security.services.api.authorization.RoleMappingService}</code>
+	 */
+	@Override
+	public boolean isUserInRole(String appContext, Subject subject, URI resource, String role) {
+		// Validate inputs
+		if (subject == null) throw new IllegalArgumentException(
+				localStrings.getLocalString("service.subject_null", "The supplied Subject is null."));
+		if (resource == null) throw new IllegalArgumentException(
+				localStrings.getLocalString("service.resource_null", "The supplied Resource is null."));
+
+		// Convert arguments
+		return isUserInRole(appContext, makeAzSubject(subject), makeAzResource(resource), role);
+	}
+
+	/**
+	 * Determine if the user's is in the specified role.
+	 * 
+	 * @see <code>{@link org.glassfish.security.services.api.authorization.RoleMappingService}</code>
+	 */
+	@Override
+	public boolean isUserInRole(String appContext, AzSubject subject, AzResource resource, String role) {
+		boolean result = false;
+
+		// Validate inputs
+		if (subject == null) throw new IllegalArgumentException(
+				localStrings.getLocalString("service.subject_null", "The supplied Subject is null."));
+		if (resource == null) throw new IllegalArgumentException(
+				localStrings.getLocalString("service.resource_null", "The supplied Resource is null."));
+
+		// Make sure provider and config have been setup...
+		checkServiceAvailability();
+
+		// Call provider - AzEnvironment and AzAttributeResolver are placeholders
+		result = provider.isUserInRole(appContext, subject, resource, role, new AzEnvironmentImpl(), attributeResolvers);
+
+		// Display and return results
+		if (isDebug()) {
+			logger.log(DEBUG_LEVEL, "Role Mapping Service result {0}"
+					+ " for role {1} with resource {2} using subject {3} in context {4}.",
+					new String[]{ Boolean.toString(result), role,
+						resource.toString(), subject.toString(), appContext});
+		}
+		return result;
+	}
+
+	/**
+	 * Find an existing <code>RoleDeploymentContext</code>, or create a new one if one does not
+	 * already exist for the specified application context.
+	 * 
+	 * @see <code>{@link org.glassfish.security.services.api.authorization.RoleMappingService}</code>
+	 */
+	@Override
+	public RoleMappingService.RoleDeploymentContext findOrCreateDeploymentContext(String appContext) {
+		checkServiceAvailability();
+		return provider.findOrCreateDeploymentContext(appContext);
+	}
+
+	/**
+	 * Handle lookup of role mapping service configuration and initialization.
+	 * If no service or provider is configured the service run-time will throw exceptions.
+	 * 
+	 * Addresses alternate configuration handling until adopt @Proxiable support. 
+	 */
+	@Override
+	public void postConstruct() {
+		org.glassfish.security.services.config.RoleMappingService roleConfiguration =
+				ServiceFactory.getSecurityServiceConfiguration(
+						domain, org.glassfish.security.services.config.RoleMappingService.class);
+		initialize(roleConfiguration);
+	}
+
+	//
+	// Log Messages
+	//
+
+	@LogMessageInfo(
+			message = "Role Mapping Service has successfully initialized.",
+			level = "INFO")
+	private static final String ROLEMAPSVC_INITIALIZED = "SEC-SVCS-00150";
+
+	@LogMessageInfo(
+			message = "Role Mapping Service initialization failed, exception {0}, message {1}",
+			level = "WARNING")
+	private static final String ROLEMAPSVC_INIT_FAILED = "SEC-SVCS-00151";
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/common/AttributeImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/common/AttributeImpl.java
new file mode 100755
index 0000000..1be4012
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/common/AttributeImpl.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.common;
+
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.TreeSet;
+import java.util.Set;
+
+import org.glassfish.security.services.api.common.Attribute;
+
+
+public class AttributeImpl implements Attribute {
+
+	private String name = null;
+	private Set<String> values = new TreeSet<String>();
+	
+	protected AttributeImpl() {}
+	
+	public AttributeImpl(String name) {
+		this.name = name;
+	}
+	
+	public AttributeImpl(String name, String value) {
+		this(name);
+		addValue(value);
+	}
+	
+	public AttributeImpl(String name, Set<String> values) {
+		this(name);
+		addValues(values);
+	}
+	
+	public AttributeImpl(String name, String[] values) {
+		this(name);
+		addValues(values);
+	}
+
+	public int getValueCount() { return values.size(); }
+
+	public String getName() { return name; }
+
+	public String getValue() {
+		if(getValueCount() == 0) {
+			return null;
+		}
+		Iterator<String> i = values.iterator();
+		return i.next();
+	}
+
+	public Set<String> getValues() { return values; }
+
+	public String[] getValuesAsArray() { return values.toArray(new String[0]); }
+	
+	public void addValue(String value) {
+		if (value != null && !value.trim().equals("")) {
+			values.add(value);
+		}
+	}
+	
+	public void addValues(Set<String> values) {
+		addValues(values.toArray(new String[0]));
+	}
+	
+	public void addValues(String[] values) {
+		for (int i = 0; i < values.length; i++) {
+			addValue(values[i]);
+		}
+	}
+	
+	public void removeValue(String value) {
+		values.remove(value);
+	}
+	
+	public void removeValues(Set<String> values) {
+		this.values.removeAll(values);
+	}
+	
+	public void removeValues(String[] values) {
+		this.values.removeAll(Arrays.asList(values));
+	}
+	
+	public void clear() {
+		values.clear();
+	}
+	
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/common/AttributesImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/common/AttributesImpl.java
new file mode 100755
index 0000000..11dc23e
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/common/AttributesImpl.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.common;
+
+
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.glassfish.security.services.api.common.Attribute;
+import org.glassfish.security.services.api.common.Attributes;
+
+
+public class AttributesImpl implements Attributes {
+
+	private final TreeMap<String, Attribute> attributes;
+
+    public AttributesImpl() {
+        attributes = new TreeMap<String, Attribute>();
+    }
+
+    /**
+     * Copy constructor
+     */
+    public AttributesImpl( AttributesImpl other ) {
+        if ( null == other ) {
+            throw new NullPointerException( "Given illegal null AttributesImpl." );
+        }
+        attributes = new TreeMap<String, Attribute>( other.attributes );
+    }
+
+    public int getAttributeCount() {
+		return attributes.size();
+	}
+
+	public Set<String> getAttributeNames() {
+		return attributes.keySet();
+	}
+
+	public Attribute getAttribute(String name) {
+		return attributes.get(name);
+	}
+
+	public String getAttributeValue(String name) {
+		Attribute a = attributes.get(name);
+		if(a != null) {
+			return a.getValue();
+		}
+		return null;
+	}
+
+	public Set<String> getAttributeValues(String name) {
+		Attribute a = attributes.get(name);
+		if(a != null) {
+			return a.getValues();
+		}
+		return null;
+	}
+
+	public String[] getAttributeValuesAsArray(String name) {
+		Attribute a = attributes.get(name);
+		if(a != null) {
+			return a.getValuesAsArray();
+		}
+		return null;
+	}
+
+	public void addAttribute(String name, String value, boolean replace) {
+		Attribute a = attributes.get(name);
+		if(a != null && !replace) {
+			a.addValue(value);
+		}
+		else {
+			attributes.put(name, new AttributeImpl(name, value));
+		}
+	}
+
+	public void addAttribute(String name, Set<String> values, boolean replace) {
+		Attribute a = attributes.get(name);
+		if(a != null && !replace) {
+			a.addValues(values);
+		}
+		else {
+			attributes.put(name, new AttributeImpl(name, values));
+		}
+	}
+
+	public void addAttribute(String name, String[] values, boolean replace) {
+		Attribute a = attributes.get(name);
+		if(a != null && !replace) {
+			a.addValues(values);
+		}
+		else {
+			attributes.put(name, new AttributeImpl(name, values));
+		}
+	}
+
+	public void removeAttribute(String name) {
+		attributes.remove(name);
+	}
+
+	public void removeAttributeValue(String name, String value) {
+		Attribute a = attributes.get(name);
+		if (a != null) {
+			a.removeValue(value);
+		}
+	}
+
+	public void removeAttributeValues(String name, Set<String> values) {
+		Attribute a = attributes.get(name);
+		if (a != null) {
+			a.removeValues(values);
+		}
+	}
+
+	public void removeAttributeValues(String name, String[] values) {
+		Attribute a = attributes.get(name);
+		if (a != null) {
+			a.removeValues(values);
+		}
+	}
+
+	public void removeAllAttributeValues(String name) {
+		Attribute a = attributes.get(name);
+		if (a != null) {
+			a.clear();
+		}
+	}
+
+	public void clear() {
+		attributes.clear();
+
+	}
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/context/SecurityContextServiceImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/context/SecurityContextServiceImpl.java
new file mode 100755
index 0000000..e0f863a
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/impl/context/SecurityContextServiceImpl.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.context;
+
+
+import org.glassfish.security.services.api.common.Attributes;
+import org.glassfish.security.services.api.context.SecurityContextService;
+import org.glassfish.security.services.impl.common.AttributesImpl;
+
+import javax.inject.Singleton;
+import org.jvnet.hk2.annotations.Service;
+
+@Service
+@Singleton
+public class SecurityContextServiceImpl implements SecurityContextService {
+
+	private Attributes envAttributes = new AttributesImpl();
+	
+	public Attributes getEnvironmentAttributes() {
+		return envAttributes;
+	}
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/AuthorizationProviderConfig.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/AuthorizationProviderConfig.java
new file mode 100644
index 0000000..564dc43
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/AuthorizationProviderConfig.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.provider.authorization;
+
+import java.beans.PropertyVetoException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.validation.constraints.NotNull;
+
+import org.glassfish.security.services.config.SecurityProviderConfig;
+
+import org.jvnet.hk2.config.Attribute;
+import org.jvnet.hk2.config.Configured;
+import org.jvnet.hk2.config.DuckTyped;
+import org.jvnet.hk2.config.Element;
+import org.jvnet.hk2.config.types.Property;
+import org.jvnet.hk2.config.types.PropertyBag;
+
+import com.sun.enterprise.config.serverbeans.customvalidators.JavaClassName;
+
+
+@Configured
+public interface AuthorizationProviderConfig extends SecurityProviderConfig, PropertyBag {
+
+    
+    /**
+     * Gets the class name of the authorization provider.
+     */
+    @Attribute(required=false)
+    @NotNull
+    @JavaClassName
+    public String getProviderClass();
+    public void setProviderClass(String value) throws PropertyVetoException;
+    
+    /**
+     * Configuration parameter indicating if the provider support policy deploy or not
+     * @return true support policy deploy
+     */
+    @Attribute(defaultValue = "true")
+    boolean getSupportPolicyDeploy();
+    void setSupportPolicyDeploy(boolean value) throws PropertyVetoException;
+
+    /**
+     * configuration parameter to indicate the version of the provider
+     * @return version of the provider
+     */
+    @Attribute(required=false)
+    String getVersion();
+    void setVersion(String value) throws PropertyVetoException;
+    
+    
+    /**
+     * Gets the properties of the LoginModule.
+     */
+    @Element
+    List<Property> getProperty();
+    
+    /**
+     * Gets the options of the LoginModule for use with JAAS Configuration.
+     */
+    @DuckTyped
+    Map<String,?> getProviderOptions();
+
+    class Duck {
+        /**
+         * Gets the options of the LoginModule for use with JAAS Configuration.
+         */
+        public static Map<String,?> getProviderOptions(AuthorizationProviderConfig config) {
+            Map<String,String> providerOptions = new HashMap<String,String>();
+            for (Property prop : config.getProperty()) {
+                providerOptions.put(prop.getName(), prop.getValue());
+            }
+            return providerOptions;
+        }
+    }
+
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/RoleMappingProviderConfig.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/RoleMappingProviderConfig.java
new file mode 100644
index 0000000..4a227a2
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/RoleMappingProviderConfig.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.provider.authorization;
+
+import java.beans.PropertyVetoException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.validation.constraints.NotNull;
+
+import org.glassfish.security.services.config.SecurityProviderConfig;
+
+import org.jvnet.hk2.config.Attribute;
+import org.jvnet.hk2.config.Configured;
+import org.jvnet.hk2.config.DuckTyped;
+import org.jvnet.hk2.config.Element;
+import org.jvnet.hk2.config.types.Property;
+import org.jvnet.hk2.config.types.PropertyBag;
+
+import com.sun.enterprise.config.serverbeans.customvalidators.JavaClassName;
+
+@Configured
+public interface RoleMappingProviderConfig extends SecurityProviderConfig, PropertyBag {
+
+	/**
+	 * Gets the class name of the role provider.
+	 */
+	@Attribute(required=false)
+	@NotNull
+	@JavaClassName
+	public String getProviderClass();
+	public void setProviderClass(String value) throws PropertyVetoException;
+
+	/**
+	 * Indicates if the provider supports role deployment.
+	 */
+	@Attribute(defaultValue = "true")
+	boolean getSupportRoleDeploy();
+	void setSupportRoleDeploy(boolean value) throws PropertyVetoException;
+
+	/**
+	 * Gets the version of the provider.
+	 */
+	@Attribute(required=false)
+	String getVersion();
+	void setVersion(String value) throws PropertyVetoException;
+
+	/**
+	 * Gets the properties of the provider.
+	 */
+	@Element
+	List<Property> getProperty();
+
+	/**
+	 * Gets the options of the provider.
+	 */
+	@DuckTyped
+	Map<String,?> getProviderOptions();
+
+	class Duck {
+		/**
+		 * Gets the options of the provider by looking at the properties.
+		 */
+		public static Map<String,?> getProviderOptions(RoleMappingProviderConfig config) {
+			Map<String,String> providerOptions = new HashMap<String,String>();
+			for (Property prop : config.getProperty()) {
+				providerOptions.put(prop.getName(), prop.getValue());
+			}
+			return providerOptions;
+		}
+	}
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/SimpleAuthorizationProviderImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/SimpleAuthorizationProviderImpl.java
new file mode 100644
index 0000000..df1d0c4
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/SimpleAuthorizationProviderImpl.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.provider.authorization;
+
+import com.sun.enterprise.config.serverbeans.Domain;
+import com.sun.enterprise.config.serverbeans.SecureAdmin;
+import com.sun.enterprise.config.serverbeans.SecureAdminPrincipal;
+import java.net.URI;
+import java.security.Principal;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.inject.Inject;
+import org.glassfish.api.admin.ServerEnvironment;
+import org.glassfish.logging.annotation.LogMessageInfo;
+
+import org.glassfish.security.services.api.authorization.*;
+import org.glassfish.security.services.api.authorization.AzResult.Decision;
+import org.glassfish.security.services.api.authorization.AzResult.Status;
+import org.glassfish.security.services.api.authorization.AuthorizationService.PolicyDeploymentContext;
+import org.glassfish.security.services.api.authorization.AuthorizationAdminConstants;
+import org.glassfish.security.services.common.Secure;
+import org.glassfish.security.services.config.SecurityProvider;
+import org.glassfish.security.services.spi.authorization.AuthorizationProvider;
+import org.glassfish.security.services.impl.ServiceLogging;
+import org.glassfish.security.services.impl.authorization.AzResultImpl;
+import org.glassfish.security.services.impl.authorization.AzObligationsImpl;
+
+import org.jvnet.hk2.annotations.Service;
+import org.glassfish.hk2.api.PerLookup;
+import org.glassfish.hk2.api.ServiceLocator;
+
+@Service (name="simpleAuthorization")
+@PerLookup
+@Secure(accessPermissionName = "security/service/authorization/provider/simple")
+public class SimpleAuthorizationProviderImpl implements AuthorizationProvider{
+
+    private final static Level DEBUG_LEVEL = Level.FINER;
+    private static final Logger _logger =
+        Logger.getLogger(ServiceLogging.SEC_PROV_LOGGER,ServiceLogging.SHARED_LOGMESSAGE_RESOURCE);
+    
+    private AuthorizationProviderConfig cfg; 
+    private boolean deployable;
+    private String version;
+    
+    @Inject
+    private ServerEnvironment serverEnv;
+    
+    @Inject
+    private ServiceLocator serviceLocator;
+    
+    private Domain domain = null;
+    
+    private SecureAdmin secureAdmin = null;
+    
+    private Decider decider;
+    
+    @Override
+    public void initialize(SecurityProvider providerConfig) {
+                
+        cfg = (AuthorizationProviderConfig)providerConfig.getSecurityProviderConfig().get(0);        
+        deployable = cfg.getSupportPolicyDeploy();
+        version = cfg.getVersion();
+        domain = serviceLocator.getService(Domain.class);
+        secureAdmin = domain.getSecureAdmin();
+        if (isDebug()) {
+            _logger.log(DEBUG_LEVEL, "provide to do policy deploy: " + deployable);
+            _logger.log(DEBUG_LEVEL, "provide version to use: " + version);
+        }
+    }
+    
+    protected Decider createDecider() {
+        return new Decider();
+    }
+    
+    private synchronized Decider getDecider() {
+        if (decider == null) {
+            decider = createDecider();
+            if (isDebug()) {
+                _logger.log(DEBUG_LEVEL, "Created SimpleAuthorizationProviderImpl Decider of type {0}", decider.getClass().getName());
+            }
+        }
+        return decider;
+    }
+
+    private boolean isDebug() {
+        return _logger.isLoggable(DEBUG_LEVEL);
+    }
+    
+    @Override
+    public AzResult getAuthorizationDecision(
+        AzSubject subject,
+        AzResource resource,
+        AzAction action,
+        AzEnvironment environment,
+        List<AzAttributeResolver> attributeResolvers ) {
+
+        //TODO: get user roles from Rolemapper, and do the policy  evaluation
+        if ( ! isAdminResource(resource)) {
+            /*
+             * Log a loud warning if the resource name lacks the correct
+             * scheme, but go ahead anyway and make the authorization decision.
+             */
+            final String resourceName = resource.getUri() == null ? "null" : resource.getUri().toASCIIString();
+            _logger.log(Level.WARNING, ATZPROV_BAD_RESOURCE, resourceName);
+            _logger.log(Level.WARNING, "IllegalArgumentException", new IllegalArgumentException(resourceName));
+        }
+        return getAdminDecision(subject, resource, action, environment);
+    }
+    
+    private boolean isAdminResource(final AzResource resource) {
+        final URI resourceURI = resource.getUri();
+        return "admin".equals(resourceURI.getScheme());
+    }
+    
+    private AzResult getAdminDecision(
+            final AzSubject subject,
+            final AzResource resource,
+            final AzAction action,
+            final AzEnvironment environment) {
+        if (isDebug()) {
+            _logger.log(DEBUG_LEVEL, "");
+        }
+        AzResult rtn = new AzResultImpl(getDecider().decide(subject, resource, action, environment), 
+                Status.OK, new AzObligationsImpl());
+        
+        return rtn;
+    }
+
+    @Override
+    public PolicyDeploymentContext findOrCreateDeploymentContext(String appContext) {
+
+        return null;
+    }
+    
+    /**
+     * Chooses what authorization decision to render.
+     * 
+     * We always require that the user be an administrator, established 
+     * (for open-source) by having a Principal with name asadmin.
+     * 
+     * Beyond that, there are historical requirements for authenticated admin access:
+     *  
+     * - "External" users (CLI, browser, JMX)
+     *   - can perform all actions locally on the DAS
+     *   - can perform all actions remotely on the DAS if secure admin has been enabled [1]
+     *   - JMX users can perform read-only actions on a non-DAS instance,
+     *     remotely if secure admin has been enabled and always locally
+     * 
+     * - Selected local commands can act locally on the local DAS or local instance
+     *   using the local password mechanism (stop-local-instance, for example)
+     * 
+     * - A server in the same domain can perform all actions in a local or remote server
+     * 
+     * - A client (typically run in a shell created by the DAS) can perform all actions 
+     *   on a local or remote DAS if it uses the admin token mechanism to authenticate
+     * 
+     * [1] Note that any attempted remote access that is not permitted has 
+     * already been rejected during authentication.
+     * 
+     * For enforcing read-only access we assume that any action other than the literal "read"
+     * makes some change in the system.
+     */
+    protected class Decider {
+        
+        protected Decision decide(final AzSubject subject, final AzResource resource,
+                final AzAction action, final AzEnvironment env) {
+            /*
+             * Basically, if the subject has one of the "special" principals
+             * (token, local password, etc.) then we accept it for any action
+             * on the DAS and on instances.  Otherwise, it's a person and
+             * we allow full access on the DAS but read-only on instances.
+             */
+            Decision result = 
+                    isSubjectTrustedForDASAndInstances(subject)
+                   
+                    || // Looks external.  Allow full access on DAS, read-only on instance.
+                   
+                    (isSubjectAnAdministrator(subject)
+                    && ( serverEnv.isDas()
+                        || isActionRead(action)
+                       )
+                   ) ? Decision.PERMIT : Decision.DENY;
+            
+            return result;
+        }
+        
+        protected String getAdminGroupName() {
+            return AuthorizationAdminConstants.ADMIN_GROUP;
+        }
+        private boolean isSubjectTrustedForDASAndInstances(final AzSubject subject) {
+            final Set<String> principalNames = new HashSet<String>();
+            for (Principal p : subject.getSubject().getPrincipals()) {
+                principalNames.add(p.getName());
+            }
+            principalNames.retainAll(AuthorizationAdminConstants.TRUSTED_FOR_DAS_OR_INSTANCE);
+            return ! principalNames.isEmpty();
+        }
+        
+        private boolean isActionRead(final AzAction action) {
+            return "read".equals(action.getAction());
+        }
+
+        private boolean isSubjectAnAdministrator(final AzSubject subject) {
+            return isPrincipalType(subject, getAdminGroupName()) ||
+                    hasSecureAdminPrincipal(subject);
+        }
+
+        private boolean isPrincipalType(final AzSubject subject, final String type) {
+            for (Principal p : subject.getSubject().getPrincipals()) {
+                if (type.equals(p.getName())) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        
+        private boolean hasSecureAdminPrincipal(final AzSubject subject) {
+            /*
+             * If the subject has a principal with a name that matches a
+             * name in the secure admin principals then it's most likely the
+             * DAS sending a request to an instance, in which case it's
+             * an administrator.
+             */
+            if (secureAdmin == null) {
+                return false;
+            }
+            for (Principal p : subject.getSubject().getPrincipals()) {
+                for (SecureAdminPrincipal sap : secureAdmin.getSecureAdminPrincipal()) {
+                    if (sap.getDn().equals(p.getName())) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+	@LogMessageInfo(
+			message = "Authorization Provider supplied an invalid resource: {0}",
+			level = "WARNING")
+	private static final String ATZPROV_BAD_RESOURCE = "SEC-PROV-00100";
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/SimpleRoleMappingProviderImpl.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/SimpleRoleMappingProviderImpl.java
new file mode 100644
index 0000000..f9ffb3b
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/provider/authorization/SimpleRoleMappingProviderImpl.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.provider.authorization;
+
+import java.security.Principal;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.glassfish.hk2.api.PerLookup;
+import org.jvnet.hk2.annotations.Service;
+
+import org.glassfish.security.services.api.authorization.AuthorizationAdminConstants;
+import org.glassfish.security.services.api.authorization.AzAttributeResolver;
+import org.glassfish.security.services.api.authorization.AzEnvironment;
+import org.glassfish.security.services.api.authorization.AzResource;
+import org.glassfish.security.services.api.authorization.AzSubject;
+import org.glassfish.security.services.api.authorization.RoleMappingService;
+import org.glassfish.security.services.common.Secure;
+import org.glassfish.security.services.config.SecurityProvider;
+import org.glassfish.security.services.impl.ServiceLogging;
+import org.glassfish.security.services.spi.authorization.RoleMappingProvider;
+
+import org.glassfish.logging.annotation.LogMessageInfo;
+
+@Service (name="simpleRoleMapping")
+@Secure(accessPermissionName="security/service/rolemapper/provider/simple")
+@PerLookup
+public class SimpleRoleMappingProviderImpl implements RoleMappingProvider {
+	private static final Level DEBUG_LEVEL = Level.FINER;
+	private static final Logger _logger =
+			Logger.getLogger(ServiceLogging.SEC_PROV_LOGGER,ServiceLogging.SHARED_LOGMESSAGE_RESOURCE);
+
+	private static final String ADMIN = "Admin";
+
+	private RoleMappingProviderConfig cfg; 
+	private boolean deployable;
+	private String version;
+	private Map<String, ?> options;
+
+	private boolean isDebug() {
+		return _logger.isLoggable(DEBUG_LEVEL);
+	}
+
+	private boolean isAdminResource(AzResource resource) {
+		return "admin".equals(resource.getUri().getScheme());
+	}
+
+	private boolean containsAdminGroup(AzSubject subject) {
+		// Only checking for principal name
+		for (Principal p : subject.getSubject().getPrincipals()) {
+			if (AuthorizationAdminConstants.ADMIN_GROUP.equals(p.getName())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	@Override
+	public void initialize(SecurityProvider providerConfig) {
+		cfg = (RoleMappingProviderConfig)providerConfig.getSecurityProviderConfig().get(0);        
+		deployable = cfg.getSupportRoleDeploy();
+		version = cfg.getVersion();
+		options = cfg.getProviderOptions();
+		if (isDebug()) {
+			_logger.log(DEBUG_LEVEL, "provider deploy:  " + deployable);
+			_logger.log(DEBUG_LEVEL, "provider version: " + version);
+			_logger.log(DEBUG_LEVEL, "provider options: " + options);
+		}
+	}
+
+	@Override
+	public boolean isUserInRole(String appContext, AzSubject subject, AzResource resource, String role, AzEnvironment environment, List<AzAttributeResolver> resolvers) {
+		boolean result = false;
+		if (isDebug()) _logger.log(DEBUG_LEVEL, "isUserInRole() - " + role);
+
+		if (!isAdminResource(resource)) {
+			// Log a warning if the resource is not correct
+			final String resourceName = resource.getUri() == null ? "null" : resource.getUri().toASCIIString();
+			_logger.log(Level.WARNING, ROLEPROV_BAD_RESOURCE, resourceName);
+			_logger.log(Level.WARNING, "IllegalArgumentException", new IllegalArgumentException(resourceName));
+		}
+
+		// Only support for admin role 
+		if (ADMIN.equals(role)) {
+			result = containsAdminGroup(subject);
+		}
+
+		if (isDebug()) _logger.log(DEBUG_LEVEL, "isUserInRole() - returning " + result);
+		return result;
+	}
+
+	@Override
+	public RoleMappingService.RoleDeploymentContext findOrCreateDeploymentContext(String appContext) {
+		// Not Supported
+		return null;
+	}
+
+	@LogMessageInfo(
+			message = "Role Mapping Provider supplied an invalid resource: {0}",
+			level = "WARNING")
+	private static final String ROLEPROV_BAD_RESOURCE = "SEC-PROV-00150";
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/SecurityProvider.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/SecurityProvider.java
new file mode 100644
index 0000000..1d44576
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/SecurityProvider.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.spi;
+
+/**
+ * Base interface used by all security providers
+ */
+public interface SecurityProvider {
+    /**
+     * Initialize the security provider instance with the specific security provider configuration.
+     */
+    public void initialize(org.glassfish.security.services.config.SecurityProvider providerConfig);
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authentication/UserStoreException.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authentication/UserStoreException.java
new file mode 100755
index 0000000..a821cc3
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authentication/UserStoreException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.spi.authentication;
+
+import java.security.GeneralSecurityException;
+
+public class UserStoreException extends GeneralSecurityException {
+
+    private static final long serialVersionUID = 2747414489750791081L;
+    
+
+    public UserStoreException(String msg) {
+        super(msg);
+    }
+
+    public UserStoreException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authentication/UserStoreProvider.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authentication/UserStoreProvider.java
new file mode 100755
index 0000000..b7c126a
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authentication/UserStoreProvider.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.spi.authentication;
+
+import java.util.Set;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+
+import org.glassfish.security.services.api.common.Attributes;
+
+/*
+ * Provider interface for authentication service.
+ */
+
+public interface UserStoreProvider {
+	
+	/*
+	 * Represents a user entry in the store
+	 */
+	public interface UserEntry {
+		public String getName();
+		public String getDN();
+		public String getUid();
+		public String getStoreId();
+		public Set<GroupEntry> getGroups();
+		public Attributes getAttributes();
+	}
+	
+	/*
+	 * Represents a group entry in the store
+	 */
+	public interface GroupEntry {
+		public String getName();
+		public String getDN();
+		public String getUid();
+		public String getStoreId();
+		public Set<String> getMembers();
+	}
+	
+	/*
+	 * Page-able Result Set
+	 */
+	public interface ResultSet<T> {
+		public boolean hasNext();
+		public T getNext();
+		public void close();
+	}
+
+	/**
+	 * Get the unique store ID for this user store.  This value must be unique across all
+	 * stores configured into the system or which might be propogated into the system via
+	 * SSO, etc.  If this USP aggregates multiple underlying stores, the user IDs returned
+	 * by the provider must be sufficient to uniquely identify users across all of the
+	 * underlying stores.
+	 * 
+	 * @return The store ID for this USP.
+	 */
+	public String getStoreId();
+	
+	/**
+	 * Determine if authentication is supported and enabled by this USP.
+	 * 
+	 * @return True or false.
+	 */
+	public boolean isAuthenticationEnabled();
+	
+	/**
+	 * Determine if user lookup is supported and enabled by this USP.
+	 * 
+	 * @return True or false.
+	 */
+	public boolean isUserLookupEnabled();
+	
+	/**
+	 * Determine if user update (CRUD operations) is supported and enabled by this USP.
+	 * 
+	 * @return True or false.
+	 */
+	public boolean isUserUpdateEnabled();
+
+	/**
+	 * Authenticate using credentials supplied in the given CallbackHandler.  All USPs must support
+	 * at least NameCallback and PasswordCallback.  The only other callback type expected to be commonly
+	 * used is X509Certificate, but it's possible to imagine, e.g., KerberosToken or PasswordDigest.
+	 * 
+	 * @param cbh
+	 * @param isGetGroups Whether or not to return the user's groups.
+	 * @param attributeNames Names of attributes to return, or null for no attributes.
+	 * @return If successful, a UserEntry representing the authenticated user, otherwise throws an exception.
+	 * @throws LoginException
+	 */
+	public UserEntry authenticate(CallbackHandler cbh, boolean isGetGroups, Set<String> attributeNames) throws LoginException;
+	
+	/*
+	 * User Lookup
+	 */
+	
+	/**
+	 * Lookup users by name.  Since name is not necessarily unique, more than one entry may be returned.
+	 * Group membership and selected attributes can also be requested, but requesting these may be inefficient
+	 * if more than one user is matched.
+	 * 
+	 * @param name The user name to searech for.
+	 * @param isGetGroups Whether or not to return users' groups.
+	 * @param attributeNames Names of attributes to return, or null for no attributes.
+	 * @return The Set of UserEntrys found.
+	 * 
+	 * @throws UserStoreException
+	 */
+	public ResultSet<UserEntry> lookupUsersByName(String name, boolean isGetGroups, Set<String> attributeNames) throws UserStoreException;
+	
+	/**
+	 * Lookup a user by unique ID.  Returns the corresponding UserEntry if found.
+	 * Group membership and selected attributes can also be requested.
+	 * 
+	 * @param uid
+	 * @param isGetGroups Whether or not to return users' groups.
+	 * @param attributeNames Names of attributes to return, or null for no attributes.
+	 * @return The UserEntry (if found).
+	 * 
+	 * @throws UserStoreException
+	 */
+	public UserEntry lookupUserByUid(String uid, boolean isGetGroups, Set<String> attributeNames) throws UserStoreException;
+	
+	/*
+	 * Group Lookup
+	 */
+
+	/**
+	 * Get the GroupEntry(s) for the specified group name.
+	 * 
+	 * @param name The name to search on, may include wildcards (e.g., a*, *b, etc.)
+	 * @return ResultSet of the GroupEntries matching the specified name.
+	 * 
+	 * @throws UserStoreException
+	 */
+	public ResultSet<GroupEntry> lookupGroupsByName(String name) throws UserStoreException;
+
+	/**
+	 * Get the GroupEntry for the specified group.
+	 * 
+	 * @param uid The UID of the group to return.
+	 * @return GroupEntry corresponding to the group UID.
+	 * 
+	 * @throws UserStoreException
+	 */
+	public GroupEntry lookupGroupByUid(String uid) throws UserStoreException;
+	
+	/*
+	 * User CRUD
+	 */
+	
+	/**
+	 * Create a new user and return the unique ID assigned.
+	 * 
+	 * @param name Name of the new user entry.
+	 * @param pwd Password to set on the new entry.
+	 * @param attributes Attributes to set on the entry (or null if none).
+	 * @return Returns the UID assigned to the new entry (can be used for subsequent operations)
+	 * 
+	 * @throws UserStoreException
+	 */
+	public String /*uid*/ createUser(String name, char[] pwd, Attributes attributes) throws UserStoreException;
+	
+	/**
+	 * Remove the specified user.
+	 * 
+	 * @param uid UID of the user to remove.
+	 * 
+	 * @throws UserStoreException
+	 */
+	public void deleteUser(String uid) throws UserStoreException;
+	
+	/**
+	 * Change the password for the specified user.  If old password is provided, verify before changing.
+	 * 
+	 * @param uid UID of user whose password should be changed.
+	 * @param oldPwd Old password, if verification desired, or null.  If provided, must be valid.
+	 * @param newPwd New password to set.
+	 * 
+	 * @throws UserStoreException
+	 */
+	public void changePassword(String uid, char[] oldPwd, char[] newPwd) throws UserStoreException;  // setPassword(String uid, char[] pwd)?  password reset?
+	
+	/**
+	 * Add the given attribute values to the user entry.
+	 * 
+	 * @param uid
+	 * @param attributes
+	 * @param replace
+	 * @throws UserStoreException
+	 */
+	public void addAttributeValues(String uid, Attributes attributes, boolean replace) throws UserStoreException;
+	
+	/**
+	 * Remove the given attribute values from the user entry.
+	 * 
+	 * @param uid
+	 * @param attributes
+	 * @throws UserStoreException
+	 */
+	public void removeAttributeValues(String uid, Attributes attributes) throws UserStoreException;
+	
+	/**
+	 * Remove the given attributes from the user entry.
+	 * 
+	 * @param uid
+	 * @param attributeNames
+	 * @throws UserStoreException
+	 */
+	public void removeAttributes(String uid, Set<String> attributeNames) throws UserStoreException;
+	
+	/*
+	 * Group CRUD
+	 */
+	
+	/**
+	 * Create a new group.
+	 * 
+	 * @param groupName
+	 * @return The UID for the newly created group
+	 * @throws UserStoreException
+	 */
+	public String /*uid*/ createGroup(String groupName) throws UserStoreException;
+	
+	/**
+	 * Delete a group.
+	 * 
+	 * @param uid UID of group to delete.
+	 * @throws UserStoreException
+	 */
+	public void deleteGroup(String uid) throws UserStoreException;
+	
+	/**
+	 * Add the specified user to the set of groups.
+	 * 
+	 * @param uid
+	 * @param groups
+	 * @throws UserStoreException
+	 */
+	public void addUserToGroups(String uid, Set<String> groups) throws UserStoreException;
+	
+	/**
+	 * Remove the specified user from the set of groups.
+	 * 
+	 * @param uid
+	 * @param groups
+	 * @throws UserStoreException
+	 */
+	public void removeUserFromGroups(String uid, Set<String> groups) throws UserStoreException;
+	
+	/**
+	 * Add the set of users to the specified group.
+	 * 
+	 * @param uids
+	 * @param group
+	 * @throws UserStoreException
+	 */
+	public void addUsersToGroup(Set<String> uids, String group) throws UserStoreException;
+	
+	/**
+	 * Remove the set of users from the specified group.
+	 * 
+	 * @param uids
+	 * @param group
+	 * @throws UserStoreException
+	 */
+	public void removeUsersFromGroup(Set<String> uids, String group) throws UserStoreException;
+
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authorization/AuthorizationProvider.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authorization/AuthorizationProvider.java
new file mode 100644
index 0000000..bc216b7
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authorization/AuthorizationProvider.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.spi.authorization;
+
+import org.glassfish.security.services.api.authorization.*;
+import org.glassfish.security.services.spi.SecurityProvider;
+
+import org.jvnet.hk2.annotations.Contract;
+
+import java.util.List;
+
+/**
+ * <code>AuthorizationProvider</code> instances are used by a
+ * <code>{@link org.glassfish.security.services.api.authorization.AuthorizationService}</code>
+ * to make access authorization decisions. This is part of a plug-in mechanism,
+ * which allows access decisions to deferred to an configured implementation.
+ */
+@Contract
+public interface AuthorizationProvider extends SecurityProvider {
+
+
+    /**
+     * Evaluates the specified subject, resource, action, and environment against the body of
+     * policy managed by this provider and returns an access control result.
+     *
+     * @param subject The attributes collection representing the Subject for which an authorization
+     * decision is requested.
+     * @param resource The attributes collection representing the resource for which access is
+     * being requested.
+     * @param action  The attributes collection representing the action, with respect to the resource,
+     * for which access is being requested.  A null action is interpreted as all
+     * actions, however all actions may also be represented by the AzAction instance.
+     * See <code>{@link org.glassfish.security.services.api.authorization.AzAction}</code>.
+     * @param environment The attributes collection representing the environment, or context,
+     *                    in which the access decision is being requested, null if none.
+     * @param attributeResolvers The ordered list of attribute resolvers, for
+     * run time determination of missing attributes, null if none.
+     * @return The AzResult indicating the result of the access decision.
+     * @throws IllegalArgumentException Given null or illegal subject or resource
+     * @throws IllegalStateException Provider was not initialized.
+     * @see AuthorizationService#getAuthorizationDecision
+     */
+    AzResult getAuthorizationDecision(
+        AzSubject subject,
+        AzResource resource,
+        AzAction action,
+        AzEnvironment environment,
+        List<AzAttributeResolver> attributeResolvers );
+
+
+    /**
+     * Finds an existing PolicyDeploymentContext, or create a new one if one does not
+     * already exist for the specified appContext.  The context will be returned in
+     * an "open" state, and will stay that way until commit() or delete() is called.
+     *
+     * @param appContext The application context for which the PolicyDeploymentContext
+     * is desired.
+     * @return The resulting PolicyDeploymentContext,
+     * null if this provider does not support this feature.
+     * @throws IllegalStateException Provider was not initialized, if this method is supported.
+     * @see AuthorizationService#findOrCreateDeploymentContext(String)
+     */
+    AuthorizationService.PolicyDeploymentContext findOrCreateDeploymentContext(
+        String appContext);
+}
diff --git a/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authorization/RoleMappingProvider.java b/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authorization/RoleMappingProvider.java
new file mode 100644
index 0000000..c98919f
--- /dev/null
+++ b/nucleus/security/services/src/main/java/org/glassfish/security/services/spi/authorization/RoleMappingProvider.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.spi.authorization;
+
+import java.util.List;
+
+import org.glassfish.security.services.api.authorization.AzAttributeResolver;
+import org.glassfish.security.services.api.authorization.AzEnvironment;
+import org.glassfish.security.services.api.authorization.AzResource;
+import org.glassfish.security.services.api.authorization.AzSubject;
+import org.glassfish.security.services.api.authorization.RoleMappingService;
+import org.glassfish.security.services.spi.SecurityProvider;
+
+import org.jvnet.hk2.annotations.Contract;
+
+/**
+ * <code>RoleMappingProvider</code> instances are used by the
+ * <code>{@link org.glassfish.security.services.api.authorization.RoleMappingService}</code>
+ * to evaluate role policy conditions.
+ * 
+ * The security provider is part of a plug-in mechanism which allows decisions
+ * to be handled by a configured implementation.
+ */
+@Contract
+public interface RoleMappingProvider extends SecurityProvider {
+
+	/**
+	 * Determine whether the user (<code>AzSubject</code>) has the indicated role
+	 * for a given resource (<code>AzResource</code>) and application context.
+	 *
+	 * @param appContext The application context for the query (can be null).
+	 * @param subject The target <code>Subject</code>.
+	 * @param resource The <code>URI</code> resource for the query.
+	 * @param role The target role.
+	 * @param environment The attributes collection representing the environment.
+	 * @param attributeResolvers The ordered list of attribute resolvers.
+	 *
+	 * @see {@link org.glassfish.security.services.api.authorization.RoleMappingService#isUserInRole(String, AzSubject, AzResource, String)}
+	 */
+	public boolean isUserInRole(String appContext,
+			AzSubject subject,
+			AzResource resource,
+			String role,
+			AzEnvironment environment,
+			List<AzAttributeResolver> attributeResolvers);
+
+	/**
+	 * Find an existing <code>RoleDeploymentContext</code>, or create a new one if one does not
+	 * already exist for the specified application context. 
+	 *
+	 * @param appContext The application context for which the <code>RoleDeploymentContext</code> is desired.
+	 * 
+	 * @see {@link org.glassfish.security.services.api.authorization.RoleMappingService#findOrCreateDeploymentContext(String)}
+	 */
+	public RoleMappingService.RoleDeploymentContext findOrCreateDeploymentContext(String appContext);
+}
diff --git a/nucleus/security/services/src/main/resources/org/glassfish/security/services/commands/LocalStrings.properties b/nucleus/security/services/src/main/resources/org/glassfish/security/services/commands/LocalStrings.properties
new file mode 100644
index 0000000..b5cf654
--- /dev/null
+++ b/nucleus/security/services/src/main/resources/org/glassfish/security/services/commands/LocalStrings.properties
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+#LDAP Admin Access
+ldap.ok=LDAP server at {0} is accessible.
+ldap.na=LDAP server at {0} could not be accessed. Exception {1} was thrown with this message: {2}.
+ldap.realm.setup=The LDAP Auth Realm {0} was configured correctly in admin server''s configuration.
+config.to.ldap=Auth Realm named {0} will be configured for given LDAP. Any existing realm with that name will be renamed to {1}. The renamed auth realm can be removed.
+ldap.noExistingAtnProvider=This command modifies the authentication service provider named {0} but no such provider is configured.
+ldap.noExistingAtnService=This command modifies the authentication service named {0} but no such service is configured.
+ldap.fileRealmProviderNotLoginModuleType=The file realm provider {0} exists in the service {1} but must be of type LoginModule and is of type {2} instead.
+ldap.authProviderConfigOK=The authentication service provider {0} was reconfigured correctly.
+ldap.noAuthProviderConfig=The authentication service provider {0} must contain a LoginModule config named {1} but did not.
diff --git a/nucleus/security/services/src/main/resources/org/glassfish/security/services/impl/authorization/LocalStrings.properties b/nucleus/security/services/src/main/resources/org/glassfish/security/services/impl/authorization/LocalStrings.properties
new file mode 100644
index 0000000..a83dc29
--- /dev/null
+++ b/nucleus/security/services/src/main/resources/org/glassfish/security/services/impl/authorization/LocalStrings.properties
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+service.subject_null=The supplied Subject is null.
+service.resource_null=The supplied Resource is null.
+service.permission_null=The supplied Permission is null.
+service.resolver_null=The supplied Attribute Resolver is null.
+
+service.role.init_failed=Role Mapping Service initialization failed, exception {0}, message {1}
+service.role.not_avail=The Role Mapping Service is not available.
+service.role.not_config=The Role Mapping Service was not configured properly.
+service.role.not_provider=Role Mapping Provider {0} not found.
+
+service.atz.init_failed=Authorization Service initialization failed, exception {0}, message {1}
+service.atz.not_avail=The Authorization service is not available.
+service.atz.never_init=Authorization Service never initialized.
+service.atz.not_config=The Authorization service is not configured in the domain configuration file.
+service.atz.no_prov_config=No provider configured for the Authorization service in the domain configuration file.
+service.atz.not_provider=Authorization Provider {0} not found.
diff --git a/nucleus/security/services/src/test/java/org/glassfish/security/services/api/authorization/SimpleAtzProviderTest.java b/nucleus/security/services/src/test/java/org/glassfish/security/services/api/authorization/SimpleAtzProviderTest.java
new file mode 100644
index 0000000..362d6e4
--- /dev/null
+++ b/nucleus/security/services/src/test/java/org/glassfish/security/services/api/authorization/SimpleAtzProviderTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+
+import org.glassfish.security.services.impl.authorization.*;
+import java.net.URI;
+
+import javax.security.auth.Subject;
+import org.glassfish.security.common.PrincipalImpl;
+import org.glassfish.security.services.api.common.Attributes;
+import org.glassfish.security.services.api.context.SecurityContextService;
+import org.glassfish.security.services.impl.authorization.AuthorizationServiceImpl;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.jvnet.hk2.testing.junit.HK2Runner;
+
+import org.glassfish.security.services.spi.authorization.AuthorizationProvider;
+
+public class SimpleAtzProviderTest extends HK2Runner {
+    
+    private AuthorizationProvider simpleAtzPrv = null;
+    private SecurityContextService contextService = null;
+    
+    
+    @Before
+    public void before() {
+        super.before();
+        
+        String pf = System.getProperty("java.security.policy");
+        System.out.println("policy file = " + pf);
+        String bd = System.getProperty("build.dir");
+        System.out.println("build dir = " + bd);
+
+        String apsd = System.getProperty("appserver_dir");
+        System.out.println("appserver dir = " + apsd);
+
+        String local = System.getProperty("localRepository");
+        System.out.println("local repository dir = " + local);
+
+        simpleAtzPrv = testLocator.getService(AuthorizationProvider.class, "simpleAuthorization");
+        contextService = testLocator.getService(SecurityContextService.class);
+
+        Assert.assertNotNull(simpleAtzPrv);
+        Assert.assertNotNull(contextService);
+        
+        contextService.getEnvironmentAttributes().addAttribute(
+                AuthorizationAdminConstants.ISDAS_ATTRIBUTE, "true", true);
+    }
+    
+    @Test
+    public void testService() throws Exception {
+        final AuthorizationService authorizationService = new AuthorizationServiceImpl();
+        Assert.assertNotNull(simpleAtzPrv);
+        final AzEnvironment env = new AzEnvironmentImpl();
+        final Attributes attrs = contextService.getEnvironmentAttributes();
+        for (String attrName : attrs.getAttributeNames()) {
+            env.addAttribute(attrName, attrs.getAttributeValue(attrName), true);
+        }
+        AzSubject azS = authorizationService.makeAzSubject(adminSubject());
+        AzResult rt = simpleAtzPrv.getAuthorizationDecision(
+                azS,
+                authorizationService.makeAzResource(URI.create("admin://some/path")),
+                authorizationService.makeAzAction("read"),
+                env,
+                null
+              );
+        
+        AzResult.Decision ds = rt.getDecision();
+        
+        Assert.assertEquals(AzResult.Decision.PERMIT, ds);
+
+    }
+    
+    private Subject adminSubject() {
+        final Subject result = new Subject();
+        result.getPrincipals().add(new PrincipalImpl("asadmin"));
+        return result;
+    }
+}
diff --git a/nucleus/security/services/src/test/java/org/glassfish/security/services/api/authorization/SimpleRoleProviderTest.java b/nucleus/security/services/src/test/java/org/glassfish/security/services/api/authorization/SimpleRoleProviderTest.java
new file mode 100644
index 0000000..b2e3c8f
--- /dev/null
+++ b/nucleus/security/services/src/test/java/org/glassfish/security/services/api/authorization/SimpleRoleProviderTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.api.authorization;
+
+import java.net.URI;
+import javax.security.auth.Subject;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.jvnet.hk2.testing.junit.HK2Runner;
+
+import org.glassfish.security.common.Group;
+import org.glassfish.security.common.PrincipalImpl;
+import org.glassfish.security.services.impl.authorization.AuthorizationServiceImpl;
+import org.glassfish.security.services.spi.authorization.RoleMappingProvider;
+
+
+public class SimpleRoleProviderTest extends HK2Runner {
+
+	private AuthorizationService authorizationService = new AuthorizationServiceImpl();
+	private RoleMappingProvider simpleRoleProvider = null;
+
+	@Before
+	public void before() {
+		super.before();
+
+		simpleRoleProvider = testLocator.getService(RoleMappingProvider.class, "simpleRoleMapping");
+	}
+
+	@Test
+	public void testProviderAdmin() throws Exception {
+		Assert.assertNotNull(simpleRoleProvider);
+		boolean result = simpleRoleProvider.isUserInRole(null,
+				authorizationService.makeAzSubject(adminSubject()),
+				authorizationService.makeAzResource(URI.create("admin://my/respath")),
+				"Admin", null, null);
+		Assert.assertEquals(true, result);
+	}
+
+	private Subject adminSubject() {
+		Subject result = new Subject();
+		result.getPrincipals().add(new PrincipalImpl("admin"));
+		result.getPrincipals().add(new Group("asadmin"));
+		return result;
+	}
+
+	@Test
+	public void testProviderNonAdmin() throws Exception {
+		Assert.assertNotNull(simpleRoleProvider);
+		boolean result = simpleRoleProvider.isUserInRole(null,
+				authorizationService.makeAzSubject(nonAdminSubject()),
+				authorizationService.makeAzResource(URI.create("admin://negative")),
+				"Admin", null, null);
+		Assert.assertEquals(false, result);
+	}
+
+	private Subject nonAdminSubject() {
+		Subject result = new Subject();
+		result.getPrincipals().add(new PrincipalImpl("joe"));
+		result.getPrincipals().add(new Group("myGroup"));
+		return result;
+	}
+
+	@Test
+	public void testProviderNonAdminRole() throws Exception {
+		Assert.assertNotNull(simpleRoleProvider);
+		boolean result = simpleRoleProvider.isUserInRole(null,
+				authorizationService.makeAzSubject(adminSubject()),
+				authorizationService.makeAzResource(URI.create("foo://other")), // Warning Message
+				"otherRole", null, null);
+		Assert.assertEquals(false, result);
+	}
+}
diff --git a/nucleus/security/services/src/test/java/org/glassfish/security/services/common/SecurePermTest.java b/nucleus/security/services/src/test/java/org/glassfish/security/services/common/SecurePermTest.java
new file mode 100644
index 0000000..e89f00d
--- /dev/null
+++ b/nucleus/security/services/src/test/java/org/glassfish/security/services/common/SecurePermTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import java.security.Permission;
+
+import junit.framework.Assert;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SecurePermTest {
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testEqualsObject() {
+		
+
+		Permission perm1 = new SecureServiceAccessPermission("a/b/c", "read,write");
+		
+		Permission perm2 = new SecureServiceAccessPermission("a/b/c/d", "read,write");
+		Assert.assertFalse(perm1.equals(perm2));
+		
+		Permission p3 = null;
+		Assert.assertFalse(perm1.equals(p3));
+		
+
+		Permission p5 = new SecureServiceAccessPermission("a/b/c");
+		Assert.assertFalse(perm1.equals(p5));
+	}
+
+	@Test
+	public void testEquals1() {
+		Permission p1 = new SecureServiceAccessPermission("a/b/c", "read,write");
+		Permission p2 = new SecureServiceAccessPermission("a/b/c/", "read,write");
+		Assert.assertFalse(p1.equals(p2));
+		Assert.assertFalse(p1.implies(p2));
+		
+	}
+	
+	@Test
+	public void testImpliesPermission() {
+		Permission p1 = new SecureServiceAccessPermission("a", "read");
+		Permission p2 = new SecureServiceAccessPermission("b", "read");
+		Assert.assertFalse(p1.implies(p2));
+		
+		Permission p3 = new SecureServiceAccessPermission("a", "read,write");
+		Assert.assertTrue(p3.implies(p1));
+	}
+
+	@Test
+	public void testImpliesWild() {
+		Permission p1 = new SecureServiceAccessPermission("a/*", "read");
+		
+		Permission p2 = new SecureServiceAccessPermission("a/b", "read");
+		Assert.assertTrue(p1.implies(p2));
+		
+		Permission p3 = new SecureServiceAccessPermission("a/b/c", "read");
+		Assert.assertTrue(p1.implies(p3));
+		
+		
+		Permission p11 = new SecureServiceAccessPermission("a/b/*", "read");
+		Assert.assertTrue(p11.implies(p3));
+		
+		Assert.assertFalse(p11.implies(p1));
+		Assert.assertFalse(p11.implies(p2));
+		
+		Assert.assertTrue(p11.implies(p11));
+	}
+
+   @Test
+    public void testImpliesWild1() {
+        Permission p1 = new SecureServiceAccessPermission("a/*", null);
+        Permission p2 = new SecureServiceAccessPermission("a/default", null);
+        Assert.assertTrue(p1.implies(p2));
+   }
+	
+	@Test
+	public void testImpliesActions() {
+		Permission p1 = new SecureServiceAccessPermission("a", "read,write");
+		Permission p2 = new SecureServiceAccessPermission("a", "read");
+		Assert.assertTrue(p1.implies(p2));
+		
+		Permission p3 = new SecureServiceAccessPermission("a", "write");
+		Assert.assertTrue(p1.implies(p3));
+	}
+
+
+}
diff --git a/nucleus/security/services/src/test/java/org/glassfish/security/services/common/SubjectUtilTest.java b/nucleus/security/services/src/test/java/org/glassfish/security/services/common/SubjectUtilTest.java
new file mode 100644
index 0000000..1014937
--- /dev/null
+++ b/nucleus/security/services/src/test/java/org/glassfish/security/services/common/SubjectUtilTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.common;
+
+import org.junit.Test;
+import javax.security.auth.Subject;
+
+import java.security.Principal;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.glassfish.security.common.PrincipalImpl;
+
+import junit.framework.Assert;
+
+public class SubjectUtilTest {
+
+    private static final String USERNAME = "john";
+    private static final String USERNAME2 = "John";
+    private static final String[] GROUPS = {"g1", "g2"}; 
+    
+    private boolean debug = false;
+    
+    @Test
+    public void testUserNameUtil() {
+        
+        Subject sub = createSub(USERNAME, GROUPS);
+        
+        List<String> usernames = SubjectUtil.getUsernamesFromSubject(sub);
+        
+        if (debug)
+            System.out.println("user list =" + usernames);
+        
+        Assert.assertEquals(1, usernames.size());
+    }
+
+    
+    @Test
+    public void testGroupNameUtil() {
+
+        Subject sub = createSub(USERNAME, GROUPS);
+        
+        List<String> groupnames = SubjectUtil.getGroupnamesFromSubject(sub);
+        
+        if (debug)
+            System.out.println("group list =" + groupnames);
+
+        Assert.assertEquals(2, groupnames.size());
+    }
+
+    @Test
+    public void testUserNameUtil_empty() {
+        
+        Subject sub = createSub(null, GROUPS);
+        
+        List<String> usernames = SubjectUtil.getUsernamesFromSubject(sub);
+        
+        Assert.assertEquals(0, usernames.size());
+    }
+
+    
+    @Test
+    public void testGroupNameUtil_empty() {
+
+        Subject sub = createSub(USERNAME, null);
+        
+        List<String> groupnames = SubjectUtil.getGroupnamesFromSubject(sub);
+        
+        Assert.assertEquals(0, groupnames.size());
+
+    }
+    
+    @Test
+    public void testUserNameUtil_multi() {
+        
+        Subject sub = createSub(USERNAME, GROUPS);
+        sub.getPrincipals().add(new PrincipalImpl(USERNAME2));
+        
+        List<String> usernames = SubjectUtil.getUsernamesFromSubject(sub);
+        
+        if (debug)
+            System.out.println("user list =" + usernames);
+        
+        Assert.assertEquals(2, usernames.size());
+    }
+
+
+    
+    public static Subject createSub(String username, String[] groups) {
+        
+        Set<Principal> pset = new HashSet<Principal>();
+        
+        if (username != null) {
+            Principal u = new PrincipalImpl(username);
+            pset.add(u);
+        }
+        
+        if (groups != null) {
+            for (String g : groups) {
+                if (g != null) {
+                    Principal p = new org.glassfish.security.common.Group(g);
+                    pset.add(p);
+                }
+            }
+        }
+        
+        
+        Set prvSet = new HashSet();
+
+        Set<Object> pubSet = new HashSet<Object>();
+        
+        Subject sub = new Subject(false, pset, pubSet, prvSet);
+        
+        return sub;
+
+    }
+
+}
diff --git a/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/PasswordAliasTest.java b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/PasswordAliasTest.java
new file mode 100644
index 0000000..eae816c
--- /dev/null
+++ b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/PasswordAliasTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.KeyStore;
+import org.glassfish.api.admin.PasswordAliasStore;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ *
+ * @author tjquinn
+ */
+public class PasswordAliasTest {
+    
+    private static final char[] TEST_STORE_PW = "dontChangeIt".toCharArray();
+    
+    private static File storeFile;
+    private static PasswordAliasStore store;
+    
+    @BeforeClass
+    public static void createStore() throws Exception {
+        storeFile = File.createTempFile("pwAliasStore", "jks");
+        final KeyStore ks = KeyStore.getInstance("JCEKS");
+        ks.load(null, TEST_STORE_PW);
+        final OutputStream os = new BufferedOutputStream(new FileOutputStream(storeFile));
+        ks.store(os, TEST_STORE_PW);
+        os.close();
+        
+        store = JCEKSPasswordAliasStore.newInstance(storeFile.getAbsolutePath(), TEST_STORE_PW);
+        
+        System.out.println("Created temporary store " + storeFile.getAbsolutePath());
+    }
+    
+    @AfterClass
+    public static void deleteStore() throws Exception {
+        if ( ! storeFile.delete()) {
+            throw new IOException("Error cleaning up test alias store file " + storeFile.getAbsolutePath());
+        }
+    }
+    
+    @Test
+    public void checkShortPW() {
+        checkStoreAndGetPWByAlias("aliasFoo", "123456");
+    }
+    
+    @Test
+    public void checkLongPW() {
+        checkStoreAndGetPWByAlias("aliasBar", "12345678901234567890");
+    }
+    
+    private void checkStoreAndGetPWByAlias(final String alias, final String pw) {
+        store.put(alias, pw.toCharArray());
+        final String retrievedPW = new String(store.get(alias));
+        Assert.assertEquals("Retrieved password failed to match stored password", 
+                getBytesInHex(pw.getBytes()), 
+                getBytesInHex(retrievedPW.getBytes()));
+    }
+    
+    private static String getBytesInHex(final byte[] bytes) {
+        StringBuilder sb = new StringBuilder();
+        for (byte b: bytes) {
+             sb.append(String.format("%02X", b));
+        }
+        return sb.toString();
+    }
+}
diff --git a/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/AuthorizationServiceImplTest.java b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/AuthorizationServiceImplTest.java
new file mode 100644
index 0000000..d7ad9b0
--- /dev/null
+++ b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/AuthorizationServiceImplTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import org.glassfish.security.services.api.authorization.*;
+import org.glassfish.security.services.api.common.Attribute;
+import org.glassfish.security.services.impl.common.AttributeImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.security.auth.Subject;
+import java.net.URI;
+import java.security.AllPermission;
+import java.util.ArrayList;
+import java.util.List;
+
+import static junit.framework.Assert.*;
+import static org.glassfish.security.services.impl.authorization.AuthorizationServiceImpl.InitializationState.*;
+
+/**
+ * @see AuthorizationServiceImpl
+ */
+public class AuthorizationServiceImplTest {
+    private AuthorizationServiceImpl impl;
+
+
+    @Before
+    public void setUp() throws Exception {
+        impl = new AuthorizationServiceImpl();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        impl = null;
+    }
+
+    @Test
+    public void testInitialize() throws Exception {
+
+        assertSame( "NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState() );
+
+        try {
+            impl.initialize(null);
+            fail( "Expected initialize to fail." );
+        } catch ( RuntimeException e ) {
+        }
+
+        assertSame( "FAILED_INIT", FAILED_INIT, impl.getInitializationState() );
+        assertNotNull( "getReasonInitializationFailed", impl.getReasonInitializationFailed() );
+    }
+
+    @Test
+    public void testIsPermissionGranted() throws Exception {
+
+        assertSame( "NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState() );
+
+        // Does not require service initialization
+        impl.isPermissionGranted( new Subject(), new AllPermission() );
+    }
+
+    @Test
+    public void testIsAuthorized() throws Exception {
+
+        assertSame( "NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState() );
+
+        try {
+            impl.isAuthorized(
+                new Subject(),
+                new URI( "admin:///tenants/tenant/mytenant" ),
+                "update" );
+            fail( "Expected fail not initialized." );
+        } catch ( RuntimeException e ) {
+        }
+
+        assertSame("NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState());
+        assertNotNull( "getReasonInitializationFailed", impl.getReasonInitializationFailed() );
+    }
+
+    @Test
+    public void testGetAuthorizationDecision() throws Exception {
+
+        assertSame( "NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState() );
+
+        try {
+            impl.getAuthorizationDecision(
+                new AzSubjectImpl( new Subject() ),
+                new AzResourceImpl( new URI( "admin:///tenants/tenant/mytenant" ) ),
+                new AzActionImpl( "update" ) );
+            fail( "Expected fail not initialized." );
+        } catch ( RuntimeException e ) {
+        }
+
+        assertSame("NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState());
+        assertNotNull( "getReasonInitializationFailed", impl.getReasonInitializationFailed() );
+    }
+
+    @Test
+    public void testMakeAzSubject() throws Exception {
+        try {
+            impl.makeAzSubject(null);
+            fail( "Expected fail with null." );
+        } catch ( IllegalArgumentException e ) {
+        }
+
+        Subject s = new Subject();
+        assertSame("Subject", s, impl.makeAzSubject(s).getSubject());
+    }
+
+    @Test
+    public void testMakeAzResource() throws Exception {
+        try {
+            impl.makeAzResource(null);
+            fail( "Expected fail with null." );
+        } catch ( IllegalArgumentException e ) {
+        }
+
+        URI u = new URI( "admin:///" );
+        assertSame("URI", u, impl.makeAzResource(u).getUri());
+    }
+
+    @Test
+    public void testMakeAzAction() throws Exception {
+        AzAction azAction;
+
+        azAction = impl.makeAzAction( null );
+        assertNotNull( azAction );
+        assertNull( "Null", azAction.getAction() );
+
+
+        String action = "update";
+        azAction = impl.makeAzAction( action );
+        assertNotNull(azAction);
+        assertEquals("action", action, azAction.getAction());
+    }
+
+    @Test
+    public void testFindOrCreateDeploymentContext() throws Exception {
+
+        assertSame( "NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState() );
+
+        try {
+            impl.findOrCreateDeploymentContext("foo");
+            fail( "Expected fail not initialized." );
+        } catch ( RuntimeException e ) {
+        }
+
+        assertSame("NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState());
+        assertNotNull("getReasonInitializationFailed", impl.getReasonInitializationFailed());
+    }
+
+    @Test
+    public void testAttributeResolvers() throws Exception {
+        assertEquals( "initial", 0 , impl.getAttributeResolvers().size() );
+
+        final AzAttributeResolver testAr1 = new TestAttributeResolver( new AttributeImpl("1") );
+        final AzAttributeResolver testAr2 = new TestAttributeResolver( new AttributeImpl("2") );
+
+        assertTrue( "append 1", impl.appendAttributeResolver( testAr1 ) );
+        assertFalse( "append 1", impl.appendAttributeResolver( testAr1 ) );
+        assertTrue( "append 2", impl.appendAttributeResolver( testAr2 ) );
+        assertFalse( "append 2", impl.appendAttributeResolver( testAr2 ) );
+
+        List<AzAttributeResolver> arList = impl.getAttributeResolvers();
+        assertEquals( "size after append", 2, arList.size());
+        assertEquals( "append 1", "1", arList.get(0).resolve(null,null,null).getName() );
+        assertEquals( "append 2", "2", arList.get(1).resolve(null,null,null).getName() );
+
+        final AzAttributeResolver testAr3 = new TestAttributeResolver( new AttributeImpl("3") );
+        final AzAttributeResolver testAr4 = new TestAttributeResolver( new AttributeImpl("4") );
+        List<AzAttributeResolver> tempList = new ArrayList<AzAttributeResolver>();
+        tempList.add(testAr3);
+        tempList.add(testAr4);
+        impl.setAttributeResolvers( tempList );
+
+        List<AzAttributeResolver> arList2 = impl.getAttributeResolvers();
+        assertEquals("after get list 2", 2, arList2.size());
+        assertEquals("append 3", "3", arList2.get(0).resolve(null, null, null).getName());
+        assertEquals( "append 4", "4", arList2.get(1).resolve(null,null,null).getName() );
+
+        assertTrue( "removeAllAttributeResolvers", impl.removeAllAttributeResolvers() );
+        assertFalse( "removeAllAttributeResolvers", impl.removeAllAttributeResolvers() );
+
+        assertEquals( "final", 0 , impl.getAttributeResolvers().size() );
+    }
+
+
+    /**
+     * Fake test class
+     */
+    private static class TestAttributeResolver implements AzAttributeResolver {
+
+        final Attribute attr;
+
+        private TestAttributeResolver(Attribute attr) {
+            this.attr = attr;
+        }
+
+        @Override
+        public Attribute resolve(
+            String attributeName,
+            AzAttributes collection,
+            AzEnvironment environment) {
+            return this.attr;
+        }
+    }
+}
diff --git a/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/AzActionImplTest.java b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/AzActionImplTest.java
new file mode 100644
index 0000000..7e2e6ba
--- /dev/null
+++ b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/AzActionImplTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+
+/**
+ * @see AzActionImpl
+ */
+public class AzActionImplTest {
+    @Test
+    public void testToString() throws Exception {
+
+        AzActionImpl nullAction = new AzActionImpl(null);
+        assertEquals( "null Action", "*", nullAction.toString() );
+
+        AzActionImpl createAction = new AzActionImpl("create");
+        assertEquals( "non-null Action", "create", createAction.toString() );
+    }
+}
diff --git a/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/AzResourceImplTest.java b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/AzResourceImplTest.java
new file mode 100644
index 0000000..5a4a99d
--- /dev/null
+++ b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/AzResourceImplTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import org.glassfish.security.services.api.common.Attribute;
+import org.glassfish.security.services.api.common.Attributes;
+import org.glassfish.security.services.impl.common.AttributesImpl;
+import org.junit.Test;
+
+import java.net.URI;
+import java.util.BitSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import static org.glassfish.security.services.impl.authorization.AzResourceImpl.addAttributesFromUriQuery;
+import static org.glassfish.security.services.impl.authorization.AzResourceImpl.decodeURI;
+import static junit.framework.Assert.*;
+
+/**
+ * @see AzResourceImpl
+ */
+public class AzResourceImplTest {
+    @Test
+    public void testGetters() throws Exception {
+        URI uri;
+        AzResourceImpl impl;
+
+        // Null
+        try {
+            new AzResourceImpl(null);
+            fail( "Expected exception" );
+        } catch (IllegalArgumentException e) {
+        }
+
+        // Doesn't care about scheme
+        uri = new URI( "http://foo" );
+        impl = new AzResourceImpl(uri);
+        assertSame( "non-admin OK", uri, impl.getUri() );
+
+        // Empty domain (i.e. default)
+        uri = new URI( "admin:///tenants/tenant/zirka?locked=true%3D" );
+        impl = new AzResourceImpl(uri);
+
+        // Test getters
+        assertEquals("URI", uri, impl.getUri());
+        assertEquals("toString", "admin:///tenants/tenant/zirka?locked=true%3D", impl.toString());
+
+        // Non-empty domain, empty path
+        uri = new URI( "admin://myDomain?locked=true%3D" );
+        impl = new AzResourceImpl(uri);
+
+        // Test getters
+        assertEquals("URI", uri, impl.getUri());
+        assertEquals("toString", "admin://myDomain?locked=true%3D", impl.toString());
+    }
+
+    @Test
+    public void testAddAttributesFromUriQuery() throws Exception {
+        URI uri = new URI( "admin:///tenants/tenant/zirka?locked=true" );
+        Attributes attributes = new AttributesImpl();
+        Attribute attribute;
+        Set<String> values;
+        Iterator<String> iter;
+        BitSet bitset;
+
+        final boolean REPLACE = true;
+
+        // Null
+        try {
+            addAttributesFromUriQuery( null, attributes, REPLACE );
+            fail( "Expected IllegalArgumentException from null URI." );
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            addAttributesFromUriQuery( uri, null, REPLACE );
+            fail( "Expected IllegalArgumentException from null Attributes." );
+        } catch (IllegalArgumentException e) {
+        }
+
+        assertEquals( "Empty attributes", 0, attributes.getAttributeCount() );
+
+        // No params
+        uri = new URI( "admin:///tenants/tenant/zirka" );
+        addAttributesFromUriQuery( uri, attributes, !REPLACE );
+        assertEquals( "Empty attributes", 0, attributes.getAttributeCount() );
+
+        // 1 param
+        uri = new URI( "admin:///tenants/tenant/zirka?name1=value1" );
+        addAttributesFromUriQuery( uri, attributes, !REPLACE );
+        assertEquals("Attributes count", 1, attributes.getAttributeCount());
+        assertNotNull("attribute", attribute = attributes.getAttribute("name1"));
+        values = attribute.getValues();
+        assertEquals("Values count", 1, values.size());
+        iter = values.iterator();
+        assertTrue( iter.hasNext() );
+        assertEquals("Values value", "value1", iter.next());
+        assertFalse( iter.hasNext() );
+
+        // Repeat, no dup value
+        addAttributesFromUriQuery( uri, attributes, !REPLACE );
+        assertEquals("Attributes count", 1, attributes.getAttributeCount());
+        assertNotNull("attribute", attribute = attributes.getAttribute("name1"));
+        values = attribute.getValues();
+        assertEquals("Values count", 1, values.size());
+        iter = values.iterator();
+        assertTrue( "iterator", iter.hasNext() );
+        assertEquals("Values value", "value1", iter.next());
+        assertFalse("iterator", iter.hasNext());
+
+        // New value
+        uri = new URI( "admin:///tenants/tenant/boris?name1=value2" );
+        addAttributesFromUriQuery( uri, attributes, !REPLACE );
+        assertEquals("Attributes count", 1, attributes.getAttributeCount());
+        assertNotNull("attribute", attribute = attributes.getAttribute("name1"));
+        values = attribute.getValues();
+        assertEquals("Values count", 2, values.size());
+        bitset = new BitSet(2);
+        for ( String v : values ) {
+            if ( "value1".equals(v) && !bitset.get(0) ) {
+                bitset.set(0);
+            } else if ( "value2".equals(v) && !bitset.get(1) ) {
+                bitset.set(1);
+            } else {
+                fail( "Unexpected attribute value " + v );
+            }
+        }
+
+        // Replace attribute
+        uri = new URI( "admin:///tenants/tenant/lucky?name1=value3" );
+        addAttributesFromUriQuery( uri, attributes, REPLACE );
+        assertEquals("Attributes count", 1, attributes.getAttributeCount());
+        assertNotNull("attribute", attribute = attributes.getAttribute("name1"));
+        values = attribute.getValues();
+        assertEquals("Values count", 1, values.size());
+        iter = values.iterator();
+        assertTrue( "iterator", iter.hasNext() );
+        assertEquals("Values value", "value3", iter.next());
+        assertFalse("iterator", iter.hasNext());
+
+        // New attribute
+        uri = new URI( "admin:///tenants/tenant/lucky?name2=value21&name2=value22" );
+        addAttributesFromUriQuery( uri, attributes, !REPLACE );
+        assertEquals("Attributes count", 2, attributes.getAttributeCount());
+        assertNotNull("attribute", attributes.getAttribute("name1"));
+        assertNotNull("attribute", attribute = attributes.getAttribute("name2"));
+        values = attribute.getValues();
+        assertEquals("Values count", 2, values.size());
+        bitset = new BitSet(2);
+        for ( String v : values ) {
+            if ( "value21".equals(v) && !bitset.get(0) ) {
+                bitset.set(0);
+            } else if ( "value22".equals(v) && !bitset.get(1) ) {
+                bitset.set(1);
+            } else {
+                fail( "Unexpected attribute value " + v );
+            }
+        }
+
+        // Encoded attribute
+        attributes = new AttributesImpl();
+        uri = new URI( "admin:///tenants/tenant/lucky?na%3Dme2=val%26ue1&na%3Dme2=val%3Due2" );
+        addAttributesFromUriQuery( uri, attributes, !REPLACE );
+        assertEquals("Attributes count", 1, attributes.getAttributeCount());
+        assertNotNull("attribute", attribute = attributes.getAttribute("na=me2"));
+        values = attribute.getValues();
+        assertEquals("Values count", 2, values.size());
+        bitset = new BitSet(2);
+        for ( String v : values ) {
+            if ( "val&ue1".equals(v) && !bitset.get(0) ) {
+                bitset.set(0);
+            } else if ( "val=ue2".equals(v) && !bitset.get(1) ) {
+                bitset.set(1);
+            } else {
+                fail( "Unexpected attribute value " + v );
+            }
+        }
+    }
+
+    @Test
+    public void testdecodeURI() throws Exception {
+        assertNull( "Expected null", decodeURI(null) );
+
+        assertEquals( "decoded",
+            "#($^&#&(*$C@#$*&^@#*&(|}|}{|}dfaj;",
+            decodeURI( "%23(%24%5E%26%23%26(*%24C%40%23%24*%26%5E%40%23*%26(%7C%7D%7C%7D%7B%7C%7Ddfaj%3B" ) );
+    }
+}
diff --git a/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/RoleMappingServiceImplTest.java b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/RoleMappingServiceImplTest.java
new file mode 100644
index 0000000..f9a56ea
--- /dev/null
+++ b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/authorization/RoleMappingServiceImplTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.authorization;
+
+import java.net.URI;
+import javax.security.auth.Subject;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static junit.framework.Assert.*;
+
+import org.glassfish.security.services.api.authorization.AuthorizationService;
+import static org.glassfish.security.services.impl.authorization.RoleMappingServiceImpl.InitializationState.*;
+
+/**
+ * @see RoleMappingServiceImpl
+ */
+public class RoleMappingServiceImplTest {
+
+	// Use Authorization for creating the Az typed arguments on Role Service
+	private AuthorizationService authorizationService = new AuthorizationServiceImpl();
+	private RoleMappingServiceImpl impl;
+
+	@Before
+	public void setUp() throws Exception {
+		impl = new RoleMappingServiceImpl();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		impl = null;
+	}
+
+	@Test
+	public void testInitialize() throws Exception {
+		assertSame( "NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState() );
+		try {
+			impl.initialize(null);
+		} catch ( RuntimeException e ) {
+			fail( "Expected service to allow no specified configuration" );
+		}
+
+		try {
+			impl.isUserInRole("test",
+					authorizationService.makeAzSubject(new Subject()),
+					authorizationService.makeAzResource(URI.create("test://test")),
+					"aRole");
+			fail( "Expected fail illegal state exception." );
+		} catch ( IllegalStateException e ) {
+			assertNotNull("Service fails at run-time", e);
+		}
+
+		// The service will fail internally to prevent method calls
+		assertSame( "FAILED_INIT", FAILED_INIT, impl.getInitializationState() );
+		assertNotNull( "getReasonInitializationFailed", impl.getReasonInitializationFailed() );
+	}
+
+	@Test
+	public void testIsUserRole() throws Exception {
+		assertSame( "NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState() );
+		try {
+			impl.isUserInRole("test",
+					authorizationService.makeAzSubject(new Subject()),
+					authorizationService.makeAzResource(URI.create("test://test")),
+					"aRole");
+			fail( "Expected fail not initialized." );
+		} catch ( RuntimeException e ) {
+		}
+
+		assertSame("NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState());
+		assertNotNull( "getReasonInitializationFailed", impl.getReasonInitializationFailed() );
+	}
+
+	@Test
+	public void testIsUserRoleNoAzArgs() throws Exception {
+		assertSame( "NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState() );
+		try {
+			impl.isUserInRole("test",
+					new Subject(),
+					URI.create("test://test"),
+					"aRole");
+			fail( "Expected fail not initialized." );
+		} catch ( RuntimeException e ) {
+		}
+
+		assertSame("NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState());
+		assertNotNull( "getReasonInitializationFailed", impl.getReasonInitializationFailed() );
+	}
+
+	@Test
+	public void testIsUserRoleNullArgs() throws Exception {
+		// Arguments checked before service state
+		try {
+			impl.isUserInRole("test",
+					null,
+					authorizationService.makeAzResource(URI.create("test://test")),
+					"aRole");
+			fail( "Expected fail illegal argument." );
+		} catch ( IllegalArgumentException e ) {
+			assertNotNull("Subject null test", e);
+		}
+		try {
+			impl.isUserInRole("test",
+					authorizationService.makeAzSubject(new Subject()),
+					null,
+					"aRole");
+			fail( "Expected fail illegal argument." );
+		} catch ( IllegalArgumentException e ) {
+			assertNotNull("Resource null test", e);
+		}
+	}
+
+	@Test
+	public void testIsUserRoleNoAzArgsNullArgs() throws Exception {
+		// Arguments checked before service state
+		try {
+			impl.isUserInRole("test",
+					null,
+					URI.create("test://test"),
+					"aRole");
+			fail( "Expected fail illegal argument." );
+		} catch ( IllegalArgumentException e ) {
+			assertNotNull("Subject null test", e);
+		}
+		try {
+			impl.isUserInRole("test",
+					new Subject(),
+					null,
+					"aRole");
+			fail( "Expected fail illegal argument." );
+		} catch ( IllegalArgumentException e ) {
+			assertNotNull("Subject null test", e);
+		}
+	}
+
+	@Test
+	public void testFindOrCreateDeploymentContext() throws Exception {
+		assertSame( "NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState() );
+		try {
+			impl.findOrCreateDeploymentContext("test");
+			fail( "Expected fail not initialized." );
+		} catch ( RuntimeException e ) {
+		}
+
+		assertSame("NOT_INITIALIZED", NOT_INITIALIZED, impl.getInitializationState());
+		assertNotNull("getReasonInitializationFailed", impl.getReasonInitializationFailed());
+	}
+}
diff --git a/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/common/AttributeTest.java b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/common/AttributeTest.java
new file mode 100644
index 0000000..f3ba767
--- /dev/null
+++ b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/common/AttributeTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.common;
+
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.glassfish.security.services.api.common.Attribute;
+
+
+public class AttributeTest {
+
+    
+    @Test
+    public void testAttribute() {
+        
+        String attName = "test";
+        Attribute att = new AttributeImpl(attName);
+        att.addValue("value1");
+        att.addValue("value2");
+
+        Set<String> vs = att.getValues();
+        Assert.assertEquals(2, att.getValueCount());
+        Assert.assertTrue(vs.contains("value1"));
+        Assert.assertTrue(vs.contains("value2"));
+    }
+
+    @Test
+    public void testAttributeNullValue() {
+        
+        String attName = "testnull";
+        Attribute att = new AttributeImpl(attName);
+        att.addValue(null);
+
+        Set<String> vs = att.getValues();
+        Assert.assertTrue(vs.isEmpty());
+    }
+    
+    
+    @Test
+    public void testAttributeNullValue1() {
+        
+        String attName = "testnull1";
+        Attribute att = new AttributeImpl(attName);
+        att.addValue(null);
+        att.addValue("value1");
+
+        Set<String> vs = att.getValues();
+        Assert.assertEquals(1, att.getValueCount());
+        Assert.assertTrue(vs.contains("value1"));        
+    }
+
+    @Test
+    public void testAttributeEmptyValue() {
+        
+        String attName = "testEmpty";
+        Attribute att = new AttributeImpl(attName);
+        att.addValue("");
+
+        Set<String> vs = att.getValues();
+        Assert.assertTrue(vs.isEmpty());
+    }
+
+
+}
diff --git a/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/common/AttributesTest.java b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/common/AttributesTest.java
new file mode 100644
index 0000000..3cec850
--- /dev/null
+++ b/nucleus/security/services/src/test/java/org/glassfish/security/services/impl/common/AttributesTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.security.services.impl.common;
+
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+import org.glassfish.security.services.api.common.Attributes;
+
+
+
+public class AttributesTest {
+
+    @Test
+    public void testAttributes() {
+        
+        String attName = "test";
+        Attributes att = new AttributesImpl();
+        att.addAttribute(attName, "value1", false);
+        att.addAttribute(attName, "value2", false);
+        
+        Set<String> vs = att.getAttributeValues(attName);
+        Assert.assertEquals(2, vs.size());
+        Assert.assertTrue(vs.contains("value1"));
+        Assert.assertTrue(vs.contains("value2"));
+    }
+
+
+    @Test
+    public void testAttributesReplace() {
+        
+        String attName = "test";
+        Attributes att = new AttributesImpl();
+        att.addAttribute(attName, "value1", false);
+        att.addAttribute(attName, "value2", true);
+        
+        Set<String> vs = att.getAttributeValues(attName);
+        Assert.assertEquals(1, vs.size());
+        Assert.assertFalse(vs.contains("value1"));
+        Assert.assertTrue(vs.contains("value2"));
+    }
+
+    @Test
+    public void testAttributesNull() {
+        
+        String attName = "test";
+        Attributes att = new AttributesImpl();
+        att.addAttribute(attName, (String)null, false);
+        
+        Set<String> vs = att.getAttributeValues(attName);
+        Assert.assertEquals(0, vs.size());
+    }
+
+    @Test
+    public void testAttributesEmpty() {
+        
+        String attName = "test";
+        Attributes att = new AttributesImpl();
+        att.addAttribute(attName, "", false);
+        
+        Set<String> vs = att.getAttributeValues(attName);
+        Assert.assertEquals(0, vs.size());
+    }
+
+}
diff --git a/nucleus/security/ssl-impl/osgi.bundle b/nucleus/security/ssl-impl/osgi.bundle
new file mode 100644
index 0000000..87aad9d
--- /dev/null
+++ b/nucleus/security/ssl-impl/osgi.bundle
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+-exportcontents: \
+                        com.sun.enterprise.security.ssl.manager; \
+                        com.sun.enterprise.server.pluggable; version=${project.osgi.version}
+
+DynamicImport-Package: \
+                        com.sun.enterprise.security.store
+
diff --git a/nucleus/security/ssl-impl/pom.xml b/nucleus/security/ssl-impl/pom.xml
new file mode 100644
index 0000000..21cbd09
--- /dev/null
+++ b/nucleus/security/ssl-impl/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>nucleus-security</artifactId>
+        <groupId>org.glassfish.main.security</groupId>
+        <version>5.0.1-SNAPSHOT</version>
+    </parent>
+    <artifactId>ssl-impl</artifactId>
+    <packaging>glassfish-jar</packaging>
+    
+    <version>5.0.1-SNAPSHOT</version>
+    <name>GlassFish SSL Implementation Module</name>
+    <developers>
+        <developer>
+            <id>nasradu8</id>
+            <name>Sudarsan Sridhar</name>
+            <organization>Oracle, Inc.</organization>
+            <roles>
+                <role>developer</role>
+            </roles>
+        </developer>
+    </developers>
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>internal-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>common-util</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency> <!-- for FindBugs -->
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>simple-glassfish-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.hk2</groupId>
+            <artifactId>hk2-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.annotations</groupId>
+            <artifactId>logging-annotation-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/impl/MasterPasswordImpl.java b/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/impl/MasterPasswordImpl.java
new file mode 100644
index 0000000..184fa9f
--- /dev/null
+++ b/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/impl/MasterPasswordImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.ssl.impl;
+
+import com.sun.enterprise.security.store.IdentityManagement;
+import com.sun.enterprise.security.store.PasswordAdapter;
+import java.io.IOException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.glassfish.security.common.MasterPassword;
+import org.jvnet.hk2.annotations.Optional;
+import org.jvnet.hk2.annotations.Service;
+
+/**
+ * A contract to pass the Glassfish master password between the admin module and
+ * the security module.
+ *
+ * @author Sudarsan Sridhar
+ */
+@Service(name="Security SSL Password Provider Service")
+@Singleton
+public class MasterPasswordImpl implements MasterPassword {
+
+    @Inject @Optional IdentityManagement idm;
+
+    @Override
+    public PasswordAdapter getMasterPasswordAdapter() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException {
+        char pw[] = idm == null ? null : idm.getMasterPassword();
+        return new PasswordAdapter(pw);
+    }
+    
+    public char[] getMasterPassword() {
+        return idm == null ? null : idm.getMasterPassword();
+    }
+}
diff --git a/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/impl/SecuritySupportImpl.java b/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/impl/SecuritySupportImpl.java
new file mode 100644
index 0000000..8044706
--- /dev/null
+++ b/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/impl/SecuritySupportImpl.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.ssl.impl;
+
+import com.sun.enterprise.security.ssl.manager.UnifiedX509KeyManager;
+import com.sun.enterprise.security.ssl.manager.UnifiedX509TrustManager;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.security.KeyStore;
+import java.security.Provider;
+
+//V3:Commented import com.sun.enterprise.config.ConfigContext;
+import com.sun.enterprise.server.pluggable.SecuritySupport;
+import java.io.IOException;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Key;
+import java.security.Permission;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.PropertyPermission;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+import org.glassfish.api.admin.ProcessEnvironment;
+import org.glassfish.api.admin.ProcessEnvironment.ProcessType;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.internal.embedded.Server;
+import org.glassfish.internal.api.Globals;
+import org.glassfish.logging.annotation.LogMessageInfo;
+import org.glassfish.logging.annotation.LogMessagesResourceBundle;
+import org.glassfish.logging.annotation.LoggerInfo;
+
+import javax.inject.Inject;
+import org.jvnet.hk2.annotations.Service;
+
+import javax.inject.Singleton;
+
+/**
+ * This implements SecuritySupport used in PluggableFeatureFactory.
+ * @author Shing Wai Chan
+ */
+// TODO: when we have two SecuritySupport implementations,
+// we create Habitat we'll select which SecuritySupport implementation to use.
+@Service
+@Singleton
+public class SecuritySupportImpl extends SecuritySupport {
+    private static final String DEFAULT_KEYSTORE_PASS = "changeit";
+    private static final String DEFAULT_TRUSTSTORE_PASS = "changeit";
+    
+    @LogMessagesResourceBundle
+    public static final String SHARED_LOGMESSAGE_RESOURCE = "com.sun.enterprise.security.ssl.LogMessages";
+    
+    @LoggerInfo(subsystem = "SECURITY - SSL", description = "Security - SSL", publish = true)
+    public static final String SEC_SSL_LOGGER = "javax.enterprise.system.security.ssl";
+
+    protected static final Logger _logger =
+            Logger.getLogger(SEC_SSL_LOGGER, SHARED_LOGMESSAGE_RESOURCE);
+    
+    @LogMessageInfo(
+			message = "The SSL certificate has expired: {0}",
+			level = "SEVERE",
+			cause = "Certificate expired.",
+			action = "Check the expiration date of the certicate.")
+	private static final String SSL_CERT_EXPIRED = "NCLS-SECURITY-05054";
+    
+    private static boolean initialized = false;
+    protected static final List<KeyStore> keyStores = new ArrayList<KeyStore>();
+    protected static final List<KeyStore> trustStores = new ArrayList<KeyStore>();
+    protected static final List<char[]> keyStorePasswords = new ArrayList<char[]>();
+    protected static final List<String> tokenNames = new ArrayList<String>();
+    private MasterPasswordImpl masterPasswordHelper = null;
+    private static boolean instantiated = false;
+    private Date initDate = new Date();
+
+    @Inject
+    private ServiceLocator habitat;
+    @Inject
+    private ProcessEnvironment penv;
+
+    public SecuritySupportImpl() {
+        this(true);
+    }
+
+    protected SecuritySupportImpl(boolean init) {
+        if (init) {
+            initJKS();
+        }
+    }
+
+    private void initJKS() {
+        String keyStoreFileName = null;
+        String trustStoreFileName = null;
+
+        keyStoreFileName = System.getProperty(keyStoreProp);
+        trustStoreFileName = System.getProperty(trustStoreProp);
+
+        char[] keyStorePass = null;
+        char[] trustStorePass = null;
+        if (!isInstantiated()) {
+            if (habitat == null) {
+                habitat = Globals.getDefaultHabitat();
+            }
+            if (masterPasswordHelper == null && habitat != null) {
+                masterPasswordHelper = habitat.getService(MasterPasswordImpl.class);
+            }
+            if (masterPasswordHelper != null) {
+                keyStorePass = masterPasswordHelper.getMasterPassword();
+                trustStorePass = keyStorePass;
+            }
+        }
+        if (penv == null && habitat != null) {
+            penv = habitat.getService(ProcessEnvironment.class);
+        }
+        /*
+         * If we don't have a keystore password yet check the properties.
+         * Always do so for the app client case whether the passwords have been
+         * found from master password helper or not.
+         */
+        if (keyStorePass == null || isACC()) {
+            final String keyStorePassOverride = System.getProperty(KEYSTORE_PASS_PROP, DEFAULT_KEYSTORE_PASS);
+            if (keyStorePassOverride != null) {
+                keyStorePass = keyStorePassOverride.toCharArray();
+            }
+            final String trustStorePassOverride = System.getProperty(TRUSTSTORE_PASS_PROP, DEFAULT_TRUSTSTORE_PASS);
+            if (trustStorePassOverride != null){
+                trustStorePass = trustStorePassOverride.toCharArray();
+            }
+        }
+
+        if (!initialized) {
+            loadStores(
+                    null,
+                    null,
+                    keyStoreFileName,
+                    keyStorePass,
+                    System.getProperty(KEYSTORE_TYPE_PROP, KeyStore.getDefaultType()),
+                    trustStoreFileName,
+                    trustStorePass,
+                    System.getProperty(TRUSTSTORE_TYPE_PROP, KeyStore.getDefaultType()));
+            Arrays.fill(keyStorePass, ' ');
+            Arrays.fill(trustStorePass, ' ');
+            initialized = true;
+        }
+    }
+
+    private boolean isEmbeddedServer() {
+        List<String> servers = Server.getServerNames();
+        if (!servers.isEmpty()) {
+            return true;
+        }
+        return false;
+    }
+
+    private static synchronized boolean isInstantiated() {
+        if (!instantiated) {
+            instantiated = true;
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * This method will load keystore and truststore and add into
+     * corresponding list.
+     * @param tokenName
+     * @param provider
+     * @param keyStorePass
+     * @param keyStoreFile
+     * @param keyStoreType
+     * @param trustStorePass
+     * @param trustStoreFile
+     * @param trustStoreType
+     */
+    /*protected synchronized static void loadStores(String tokenName, 
+    String storeType, Provider provider,
+    String keyStoreFile, String keyStorePass,
+    String trustStoreFile, String trustStorePass) {*/
+    protected synchronized static void loadStores(
+            String tokenName,
+            Provider provider,
+            String keyStoreFile,
+            char[] keyStorePass,
+            String keyStoreType,
+            String trustStoreFile,
+            char[] trustStorePass,
+            String trustStoreType) {
+
+        try {
+            KeyStore keyStore = loadKS(keyStoreType, provider, keyStoreFile,
+                    keyStorePass);
+            KeyStore trustStore = loadKS(trustStoreType, provider, trustStoreFile,
+                    trustStorePass);
+            keyStores.add(keyStore);
+            trustStores.add(trustStore);
+            keyStorePasswords.add(Arrays.copyOf(keyStorePass, keyStorePass.length));
+            tokenNames.add(tokenName);
+        } catch (Exception ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    /**
+     * This method load keystore with given keystore file and
+     * keystore password for a given keystore type and provider.
+     * It always return a non-null keystore.
+     * @param keyStoreType
+     * @param provider
+     * @param keyStoreFile
+     * @param keyStorePass
+     * @retun keystore loaded
+     */
+    private static KeyStore loadKS(String keyStoreType, Provider provider,
+            String keyStoreFile, char[] keyStorePass)
+            throws Exception {
+        KeyStore ks = null;
+        if (provider != null) {
+            ks = KeyStore.getInstance(keyStoreType, provider);
+        } else {
+            ks = KeyStore.getInstance(keyStoreType);
+        }
+        char[] passphrase = keyStorePass;
+
+        FileInputStream istream = null;
+        BufferedInputStream bstream = null;
+        try {
+            if (keyStoreFile != null) {
+                if (_logger.isLoggable(Level.FINE)) {
+                    _logger.log(Level.FINE, "Loading keystoreFile = {0}, keystorePass = {1}",
+                            new Object[]{keyStoreFile, keyStorePass});
+                }
+                istream = new FileInputStream(keyStoreFile);
+                bstream = new BufferedInputStream(istream);
+            }
+
+            ks.load(bstream, passphrase);
+        } finally {
+            if (bstream != null) {
+                bstream.close();
+            }
+            if (istream != null) {
+                istream.close();
+            }
+        }
+        return ks;
+    }
+
+    // --- implements SecuritySupport ---
+    /**
+     * This method returns an array of keystores containing keys and
+     * certificates.
+     */
+    public KeyStore[] getKeyStores() {
+        return keyStores.toArray(new KeyStore[keyStores.size()]);
+    }
+
+    public KeyStore loadNullStore(String type, int index) throws KeyStoreException,
+            IOException, NoSuchAlgorithmException, CertificateException {
+        KeyStore ret = KeyStore.getInstance(type);
+        ret.load(null, keyStorePasswords.get(index));
+        return ret;
+    }
+
+    public KeyManager[] getKeyManagers(String algorithm) throws IOException,
+            KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
+        KeyStore[] kstores = getKeyStores();
+        ArrayList<KeyManager> keyManagers = new ArrayList<KeyManager>();
+        for (int i = 0; i < kstores.length; i++) {
+            checkCertificateDates(kstores[i]);
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+                    (algorithm != null) ? algorithm : KeyManagerFactory.getDefaultAlgorithm());
+            kmf.init(kstores[i], keyStorePasswords.get(i));
+            KeyManager[] kmgrs = kmf.getKeyManagers();
+            if (kmgrs != null) {
+                keyManagers.addAll(Arrays.asList(kmgrs));
+            }
+        }
+
+        KeyManager keyManager = new UnifiedX509KeyManager(
+                keyManagers.toArray(new X509KeyManager[keyManagers.size()]),
+                getTokenNames());
+        return new KeyManager[]{keyManager};
+    }
+
+    public TrustManager[] getTrustManagers(String algorithm) throws IOException,
+            KeyStoreException, NoSuchAlgorithmException {
+        KeyStore[] tstores = getTrustStores();
+        ArrayList<TrustManager> trustManagers = new ArrayList<TrustManager>();
+        for (KeyStore tstore : tstores) {
+            checkCertificateDates(tstore);
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+                    (algorithm != null) ? algorithm : TrustManagerFactory.getDefaultAlgorithm());
+            tmf.init(tstore);
+            TrustManager[] tmgrs = tmf.getTrustManagers();
+            if (tmgrs != null) {
+                trustManagers.addAll(Arrays.asList(tmgrs));
+            }
+        }
+        TrustManager trustManager;
+        if (trustManagers.size() == 1) {
+            trustManager = trustManagers.get(0);
+        } else {
+            trustManager = new UnifiedX509TrustManager(trustManagers.toArray(new X509TrustManager[trustManagers.size()]));
+        }
+        return new TrustManager[]{trustManager};
+    }
+    /*
+     * Check X509 certificates in a store for expiration.
+     */
+
+    private void checkCertificateDates(KeyStore store)
+            throws KeyStoreException {
+
+        Enumeration<String> aliases = store.aliases();
+        while (aliases.hasMoreElements()) {
+            Certificate cert = store.getCertificate(aliases.nextElement());
+            if (cert instanceof X509Certificate) {
+                if (((X509Certificate) cert).getNotAfter().before(initDate)) {
+                    _logger.log(Level.SEVERE, SSL_CERT_EXPIRED, cert);
+                }
+            }
+        }
+    }
+
+    /**
+     * This method returns an array of truststores containing certificates.
+     */
+    public KeyStore[] getTrustStores() {
+        return trustStores.toArray(new KeyStore[trustStores.size()]);
+    }
+
+    public boolean verifyMasterPassword(final char[] masterPass) {
+        return Arrays.equals(masterPass, keyStorePasswords.get(0));
+    }
+
+    /**
+     * This method returns an array of token names in order corresponding to
+     * array of keystores.
+     */
+    public String[] getTokenNames() {
+        return tokenNames.toArray(new String[tokenNames.size()]);
+    }
+
+    /**
+     * @param  token 
+     * @return a keystore
+     */
+    public KeyStore getKeyStore(String token) {
+        int idx = getTokenIndex(token);
+        if (idx < 0) {
+            return null;
+        }
+        return keyStores.get(idx);
+    }
+
+    /**
+     * @param  token 
+     * @return a truststore
+     */
+    public KeyStore getTrustStore(String token) {
+        int idx = getTokenIndex(token);
+        if (idx < 0) {
+            return null;
+        }
+        return trustStores.get(idx);
+    }
+
+    /**
+     * @return returned index 
+     */
+    private int getTokenIndex(String token) {
+        int idx = -1;
+        if (token != null) {
+            idx = tokenNames.indexOf(token);
+            if (idx < 0 && _logger.isLoggable(Level.FINEST)) {
+                _logger.log(Level.FINEST, "token {0} is not found", token);
+            }
+        }
+        return idx;
+    }
+
+    public void synchronizeKeyFile(Object configContext, String fileRealmName) throws Exception {
+        //throw new UnsupportedOperationException("Not supported yet in V3.");
+    }
+
+    public void checkPermission(String key) {
+        try {
+            // Checking a random permission to check if it is server.
+            if(isEmbeddedServer() || habitat == null
+                    || isACC() || isNotServerORACC()){
+                return;
+            }
+            Permission perm = new RuntimePermission("SSLPassword");
+            AccessController.checkPermission(perm);
+        } catch (AccessControlException e) {
+            String message = e.getMessage();
+            Permission perm = new PropertyPermission(key, "read");
+            if (message != null) {
+                message = message.replace(e.getPermission().toString(), perm.toString());
+            }
+            throw new AccessControlException(message, perm);
+        }
+    }
+
+    public boolean isACC() {
+        return (penv == null ? false : penv.getProcessType().equals(ProcessType.ACC));
+    }
+
+    public boolean isNotServerORACC() {
+        return penv.getProcessType().equals(ProcessType.Other);
+    }
+
+    public PrivateKey getPrivateKeyForAlias(String alias, int keystoreIndex) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
+        checkPermission(KEYSTORE_PASS_PROP);
+        Key key = keyStores.get(keystoreIndex).getKey(alias, keyStorePasswords.get(keystoreIndex));
+        if (key instanceof PrivateKey) {
+            return (PrivateKey) key;
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/manager/UnifiedX509KeyManager.java b/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/manager/UnifiedX509KeyManager.java
new file mode 100644
index 0000000..67546f3
--- /dev/null
+++ b/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/manager/UnifiedX509KeyManager.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.ssl.manager;
+
+import java.net.Socket;
+import java.util.ArrayList;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509KeyManager;
+
+/**
+ * This class combines an array of X509KeyManagers into one.
+ * @author Shing Wai Chan
+ **/
+public class UnifiedX509KeyManager implements X509KeyManager /* extends X509ExtendedKeyManager*/ {
+    private X509KeyManager[] mgrs = null;
+    private String[] tokenNames = null;
+
+    /**
+     * @param mgrs  
+     * @param tokenNames Array of tokenNames with order corresponding to mgrs
+     */
+    public UnifiedX509KeyManager(X509KeyManager[] mgrs, String[] tokenNames) {
+        if (mgrs == null || tokenNames == null) {
+            throw new IllegalArgumentException("Null array of X509KeyManagers or tokenNames");
+        }
+        if (mgrs.length != tokenNames.length) {
+            throw new IllegalArgumentException("Size of X509KeyManagers array and tokenNames array do not match.");
+        }
+        this.mgrs = mgrs;
+        this.tokenNames = tokenNames;
+    }
+
+    // ---------- implements X509KeyManager ----------
+    public String chooseClientAlias(String[] keyType, Principal[] issuers,
+            Socket socket) {
+        String alias = null;
+        for (int i = 0; i < mgrs.length; i++) {
+            alias = mgrs[i].chooseClientAlias(keyType, issuers, socket);
+            if (alias != null) {
+                break;
+            }
+        }
+        return alias;
+    }
+
+    public String chooseServerAlias(String keyType, Principal[] issuers,
+            Socket socket) {
+        String alias = null;
+        for (int i = 0; i < mgrs.length; i++) {
+            alias = mgrs[i].chooseServerAlias(keyType, issuers, socket);
+            if (alias != null) {
+                break;
+            }
+        }
+        return alias;
+    }
+
+    public X509Certificate[] getCertificateChain(String alias) {
+        X509Certificate[] chain = null;
+        for (int i = 0; i < mgrs.length; i++) {
+            chain = mgrs[i].getCertificateChain(alias);
+            if (chain != null) {
+                break;
+            }
+        }
+        return chain;
+    }
+
+    public String[] getClientAliases(String keyType, Principal[] issuers) {
+        ArrayList clientAliases = new ArrayList();
+        for (int i = 0; i < mgrs.length; i++) {
+            String[] clAliases = mgrs[i].getClientAliases(keyType, issuers);
+            if (clAliases != null && clAliases.length > 0) {
+                for (int j = 0; j < clAliases.length; j++) {
+                    clientAliases.add(clAliases[j]);
+                }
+            }
+        }
+
+        return (clientAliases.size() == 0) ? null :
+            (String[])clientAliases.toArray(new String[clientAliases.size()]);
+    }
+
+    public PrivateKey getPrivateKey(String alias) {
+        PrivateKey privKey  = null;
+        for (int i = 0; i < mgrs.length; i++) {
+            privKey = mgrs[i].getPrivateKey(alias);
+            if (privKey != null) {
+                break;
+            }
+        }
+        return privKey;
+    }
+
+    public String[] getServerAliases(String keyType, Principal[] issuers) {
+        ArrayList serverAliases = new ArrayList();
+        for (int i = 0; i < mgrs.length; i++) {
+            String[] serAliases = mgrs[i].getServerAliases(keyType, issuers);
+            if (serAliases != null && serAliases.length > 0) {
+                for (int j = 0; j < serAliases.length; j++) {
+                    serverAliases.add(serAliases[j]);
+                }
+            }
+        }
+
+        return (serverAliases.size() == 0) ? null :
+            (String[])serverAliases.toArray(new String[serverAliases.size()]);
+    }
+
+    // ---------- end of implements X509KeyManager ----------
+
+    public X509KeyManager[] getX509KeyManagers() {
+        X509KeyManager[] kmgrs = new X509KeyManager[mgrs.length];
+        System.arraycopy(mgrs, 0, kmgrs, 0, mgrs.length);
+        return kmgrs;
+    }
+
+    public String[] getTokenNames() {
+        String[] tokens = new String[tokenNames.length];
+        System.arraycopy(tokenNames, 0, tokens, 0, tokenNames.length);
+        return tokens;
+    }
+
+
+    public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) {
+        return chooseClientAlias(keyType, issuers, null);
+    }
+
+    public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
+        return chooseServerAlias(keyType, issuers,null);
+    }
+}
diff --git a/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/manager/UnifiedX509TrustManager.java b/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/manager/UnifiedX509TrustManager.java
new file mode 100644
index 0000000..d81c63d
--- /dev/null
+++ b/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/security/ssl/manager/UnifiedX509TrustManager.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.security.ssl.manager;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * This class combines an array of X509TrustManagers into one.
+ * @author Shing Wai Chan
+ **/
+public class UnifiedX509TrustManager implements X509TrustManager {
+    private X509TrustManager[] mgrs = null;
+    private X509Certificate[] issuers = {};
+
+    public UnifiedX509TrustManager(X509TrustManager[] mgrs) {
+        if (mgrs == null) {
+            throw new IllegalArgumentException("Null array of X509TrustManagers");
+        }
+        this.mgrs = mgrs;
+
+        HashSet tset = new HashSet(); //for uniqueness
+        for (int i = 0; i < mgrs.length; i++) {
+            X509Certificate[] tcerts = mgrs[i].getAcceptedIssuers();
+            if (tcerts != null && tcerts.length > 0) {
+                for (int j = 0; j < tcerts.length; j++) {
+                    tset.add(tcerts[j]);
+                }
+            }
+        }
+        issuers = new X509Certificate[tset.size()];
+        Iterator iter = tset.iterator();
+        for (int i = 0; iter.hasNext(); i++) {
+            issuers[i] = (X509Certificate)iter.next();
+        }
+    }
+
+    // ---------- implements X509TrustManager -----------
+    public void checkClientTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+        CertificateException cex = null;
+        for (int i = 0; i < mgrs.length; i++) {
+            try {
+                cex = null; //reset exception status
+                mgrs[i].checkClientTrusted(chain, authType);
+                break;
+            } catch(CertificateException ex) {
+                cex = ex;
+            }
+        }
+        if (cex != null) {
+            throw cex;
+        }
+    }
+
+    public void checkServerTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+        CertificateException cex = null;
+        for (int i = 0; i < mgrs.length; i++) {
+            try {
+                cex = null; //reset exception status
+                mgrs[i].checkServerTrusted(chain, authType);
+                break;
+            } catch(CertificateException ex) {
+                cex = ex;
+            }
+        }
+        if (cex != null) {
+            throw cex;
+        }
+    }
+
+    public X509Certificate[] getAcceptedIssuers() {
+        return issuers;
+    }
+}
diff --git a/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/server/pluggable/SecuritySupport.java b/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/server/pluggable/SecuritySupport.java
new file mode 100644
index 0000000..0ee72ea
--- /dev/null
+++ b/nucleus/security/ssl-impl/src/main/java/com/sun/enterprise/server/pluggable/SecuritySupport.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.enterprise.server.pluggable;
+
+import com.sun.enterprise.security.ssl.impl.SecuritySupportImpl;
+import java.io.IOException;
+import java.security.KeyStore;
+//V3:Commented import com.sun.enterprise.config.ConfigContext;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.TrustManager;
+import org.jvnet.hk2.annotations.Contract;
+
+/**
+ * SecuritySupport is part of PluggableFeature that provides access to
+ * internal services managed by application server.
+ * @author Shing Wai Chan
+ */
+@Contract
+public abstract class SecuritySupport {
+
+    public static final String KEYSTORE_PASS_PROP = "javax.net.ssl.keyStorePassword";
+    public static final String TRUSTSTORE_PASS_PROP = "javax.net.ssl.trustStorePassword";
+    public static final String KEYSTORE_TYPE_PROP = "javax.net.ssl.keyStoreType";
+    public static final String TRUSTSTORE_TYPE_PROP = "javax.net.ssl.trustStoreType";
+    public static final String keyStoreProp = "javax.net.ssl.keyStore";
+    public static final String trustStoreProp = "javax.net.ssl.trustStore";
+
+    private static volatile SecuritySupport defaultInstance = null;
+
+    public static SecuritySupport getDefaultInstance() {
+        if (defaultInstance == null) {
+            defaultInstance = new SecuritySupportImpl();
+        }
+        return defaultInstance;
+    }
+
+
+    /**
+     * This method returns an array of keystores containing keys and
+     * certificates.
+     */
+    abstract public KeyStore[] getKeyStores();
+
+    /**
+     * This method returns an array of truststores containing certificates.
+     */
+    abstract public KeyStore[] getTrustStores();
+
+    /**
+     * @param  token 
+     * @return a keystore. If token is null, return the the first keystore.
+     */
+    abstract public KeyStore getKeyStore(String token);
+
+    /**
+     * @param  token 
+     * @return a truststore. If token is null, return the first truststore.
+     */
+    abstract public KeyStore getTrustStore(String token);
+
+    /**
+     * @param type
+     * @param index
+     * @return load a null keystore of given type.
+     */
+    abstract public KeyStore loadNullStore(String type, int index) throws KeyStoreException,
+            IOException, NoSuchAlgorithmException, CertificateException;
+
+    /**
+     * @param masterPass
+     * @return result whether the given master password is correct.
+     */
+    abstract public boolean verifyMasterPassword(final char[] masterPass);
+
+    /**
+     * @param algorithm
+     * @return KeyManagers for the specified algorithm.
+     * @throws IOException
+     * @throws KeyStoreException
+     * @throws NoSuchAlgorithmException
+     * @throws UnrecoverableKeyException
+     */
+    abstract public KeyManager[] getKeyManagers(String algorithm) throws IOException,
+            KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException;
+
+    /**
+     * @param algorithm
+     * @return TrustManagers for the specified algorithm.
+     * @throws IOException
+     * @throws KeyStoreException
+     * @throws NoSuchAlgorithmException
+     */
+    abstract public TrustManager[] getTrustManagers(String algorithm) throws IOException,
+            KeyStoreException, NoSuchAlgorithmException;
+
+    /**
+     * Gets the PrivateKey for specified alias from the corresponding keystore
+     * indicated by the index.
+     *
+     * @param alias Alias for which the PrivateKey is desired.
+     * @param keystoreIndex Index of the keystore.
+     * @return
+     * @throws KeyStoreException
+     * @throws NoSuchAlgorithmException
+     * @throws UnrecoverableKeyException
+     */
+    abstract public PrivateKey getPrivateKeyForAlias(String alias, int keystoreIndex)
+            throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException;
+
+    /**
+     * This method returns an array of token names in order corresponding to
+     * array of keystores.
+     */
+    abstract public String[] getTokenNames();
+
+    /**
+     * This method synchronize key file for given realm.
+     * @param config the ConfigContextx
+     * @param fileRealmName
+     * @exception if fail to synchronize, a known exception is
+     *            com.sun.enterprise.ee.synchronization.SynchronizationException
+     */
+    /** TODO:V3:Cluster ConfigContext is no longer present so find out what this needs to be */
+    //public void synchronizeKeyFile(ConfigContext config, String fileRealmName)
+    abstract public void synchronizeKeyFile(Object configContext, String fileRealmName)
+        throws Exception;
+
+    /**
+     * Check permission for the given key.
+     * @param key
+     */
+    abstract public void checkPermission(String key);
+    
+}
diff --git a/nucleus/security/ssl-impl/src/main/resources/com/sun/logging/enterprise/system/ssl/security/LogStrings.properties b/nucleus/security/ssl-impl/src/main/resources/com/sun/logging/enterprise/system/ssl/security/LogStrings.properties
new file mode 100644
index 0000000..bfa20f7
--- /dev/null
+++ b/nucleus/security/ssl-impl/src/main/resources/com/sun/logging/enterprise/system/ssl/security/LogStrings.properties
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+java_security.expired_certificate=SEC5054: Certificate has expired: {0}
+
+SEC5054.diag.cause.1=Certificate expired
+SEC5054.diag.check.1=Please check the validity date of the certificate