http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
new file mode 100644
index 0000000..a7da2eb
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
@@ -0,0 +1,334 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.spring;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authentication.LoginCredentials;
+import org.apache.nifi.authentication.LoginIdentityProvider;
+import 
org.apache.nifi.authentication.LoginIdentityProviderConfigurationContext;
+import 
org.apache.nifi.authentication.LoginIdentityProviderInitializationContext;
+import org.apache.nifi.authentication.LoginIdentityProviderLookup;
+import org.apache.nifi.authentication.annotation.LoginIdentityProviderContext;
+import org.apache.nifi.authentication.generated.LoginIdentityProviders;
+import org.apache.nifi.authentication.generated.Property;
+import org.apache.nifi.authentication.generated.Provider;
+import org.apache.nifi.authorization.exception.ProviderCreationException;
+import org.apache.nifi.authorization.exception.ProviderDestructionException;
+import org.apache.nifi.nar.ExtensionManager;
+import org.apache.nifi.nar.NarCloseable;
+import org.apache.nifi.util.NiFiProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.xml.sax.SAXException;
+
+/**
+ *
+ */
+public class LoginIdentityProviderFactoryBean implements FactoryBean, 
ApplicationContextAware, DisposableBean, LoginIdentityProviderLookup {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(LoginIdentityProviderFactoryBean.class);
+    private static final String LOGIN_IDENTITY_PROVIDERS_XSD = 
"/login-identity-providers.xsd";
+    private static final String JAXB_GENERATED_PATH = 
"org.apache.nifi.authentication.generated";
+    private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
+
+    /**
+     * Load the JAXBContext.
+     */
+    private static JAXBContext initializeJaxbContext() {
+        try {
+            return JAXBContext.newInstance(JAXB_GENERATED_PATH, 
LoginIdentityProviderFactoryBean.class.getClassLoader());
+        } catch (JAXBException e) {
+            throw new RuntimeException("Unable to create JAXBContext.");
+        }
+    }
+
+    private ApplicationContext context;
+    private NiFiProperties properties;
+    private LoginIdentityProvider loginIdentityProvider;
+    private final Map<String, LoginIdentityProvider> loginIdentityProviders = 
new HashMap<>();
+
+    @Override
+    public LoginIdentityProvider getLoginIdentityProvider(String identifier) {
+        return loginIdentityProviders.get(identifier);
+    }
+
+    @Override
+    public Object getObject() throws Exception {
+        if (loginIdentityProvider == null) {
+            // look up the login identity provider to use
+            final String loginIdentityProviderIdentifier = 
properties.getProperty(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER);
+
+            // ensure the login identity provider class name was specified
+            if (StringUtils.isNotBlank(loginIdentityProviderIdentifier)) {
+                final LoginIdentityProviders 
loginIdentityProviderConfiguration = loadLoginIdentityProvidersConfiguration();
+
+                // create each login identity provider
+                for (final Provider provider : 
loginIdentityProviderConfiguration.getProvider()) {
+                    loginIdentityProviders.put(provider.getIdentifier(), 
createLoginIdentityProvider(provider.getIdentifier(), provider.getClazz()));
+                }
+
+                // configure each login identity provider
+                for (final Provider provider : 
loginIdentityProviderConfiguration.getProvider()) {
+                    final LoginIdentityProvider instance = 
loginIdentityProviders.get(provider.getIdentifier());
+                    
instance.onConfigured(loadLoginIdentityProviderConfiguration(provider));
+                }
+
+                // get the login identity provider instance
+                loginIdentityProvider = 
getLoginIdentityProvider(loginIdentityProviderIdentifier);
+
+                // ensure it was found
+                if (loginIdentityProvider == null) {
+                    throw new Exception(String.format("The specified login 
identity provider '%s' could not be found.", loginIdentityProviderIdentifier));
+                }
+            }
+        }
+
+        return loginIdentityProvider;
+    }
+
+    private LoginIdentityProviders loadLoginIdentityProvidersConfiguration() 
throws Exception {
+        final File loginIdentityProvidersConfigurationFile = 
properties.getLoginIdentityProviderConfiguraitonFile();
+
+        // load the users from the specified file
+        if (loginIdentityProvidersConfigurationFile.exists()) {
+            try {
+                // find the schema
+                final SchemaFactory schemaFactory = 
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+                final Schema schema = 
schemaFactory.newSchema(LoginIdentityProviders.class.getResource(LOGIN_IDENTITY_PROVIDERS_XSD));
+
+                // attempt to unmarshal
+                final Unmarshaller unmarshaller = 
JAXB_CONTEXT.createUnmarshaller();
+                unmarshaller.setSchema(schema);
+                final JAXBElement<LoginIdentityProviders> element = 
unmarshaller.unmarshal(new 
StreamSource(loginIdentityProvidersConfigurationFile), 
LoginIdentityProviders.class);
+                return element.getValue();
+            } catch (SAXException | JAXBException e) {
+                throw new Exception("Unable to load the login identity 
provider configuration file at: " + 
loginIdentityProvidersConfigurationFile.getAbsolutePath());
+            }
+        } else {
+            throw new Exception("Unable to find the login identity provider 
configuration file at " + 
loginIdentityProvidersConfigurationFile.getAbsolutePath());
+        }
+    }
+
+    private LoginIdentityProvider createLoginIdentityProvider(final String 
identifier, final String loginIdentityProviderClassName) throws Exception {
+        // get the classloader for the specified login identity provider
+        final ClassLoader loginIdentityProviderClassLoader = 
ExtensionManager.getClassLoader(loginIdentityProviderClassName);
+        if (loginIdentityProviderClassLoader == null) {
+            throw new Exception(String.format("The specified login identity 
provider class '%s' is not known to this nifi.", 
loginIdentityProviderClassName));
+        }
+
+        // get the current context classloader
+        final ClassLoader currentClassLoader = 
Thread.currentThread().getContextClassLoader();
+
+        final LoginIdentityProvider instance;
+        try {
+            // set the appropriate class loader
+            
Thread.currentThread().setContextClassLoader(loginIdentityProviderClassLoader);
+
+            // attempt to load the class
+            Class<?> rawLoginIdentityProviderClass = 
Class.forName(loginIdentityProviderClassName, true, 
loginIdentityProviderClassLoader);
+            Class<? extends LoginIdentityProvider> loginIdentityProviderClass 
= rawLoginIdentityProviderClass.asSubclass(LoginIdentityProvider.class);
+
+            // otherwise create a new instance
+            Constructor constructor = 
loginIdentityProviderClass.getConstructor();
+            instance = (LoginIdentityProvider) constructor.newInstance();
+
+            // method injection
+            performMethodInjection(instance, loginIdentityProviderClass);
+
+            // field injection
+            performFieldInjection(instance, loginIdentityProviderClass);
+
+            // call post construction lifecycle event
+            instance.initialize(new 
StandardLoginIdentityProviderInitializationContext(identifier, this));
+        } finally {
+            if (currentClassLoader != null) {
+                
Thread.currentThread().setContextClassLoader(currentClassLoader);
+            }
+        }
+
+        return withNarLoader(instance);
+    }
+
+    private LoginIdentityProviderConfigurationContext 
loadLoginIdentityProviderConfiguration(final Provider provider) {
+        final Map<String, String> providerProperties = new HashMap<>();
+
+        for (final Property property : provider.getProperty()) {
+            providerProperties.put(property.getName(), property.getValue());
+        }
+
+        return new 
StandardLoginIdentityProviderConfigurationContext(provider.getIdentifier(), 
providerProperties);
+    }
+
+    private void performMethodInjection(final LoginIdentityProvider instance, 
final Class loginIdentityProviderClass)
+            throws IllegalAccessException, IllegalArgumentException, 
InvocationTargetException {
+
+        for (final Method method : loginIdentityProviderClass.getMethods()) {
+            if 
(method.isAnnotationPresent(LoginIdentityProviderContext.class)) {
+                // make the method accessible
+                final boolean isAccessible = method.isAccessible();
+                method.setAccessible(true);
+
+                try {
+                    final Class<?>[] argumentTypes = 
method.getParameterTypes();
+
+                    // look for setters (single argument)
+                    if (argumentTypes.length == 1) {
+                        final Class<?> argumentType = argumentTypes[0];
+
+                        // look for well known types
+                        if 
(NiFiProperties.class.isAssignableFrom(argumentType)) {
+                            // nifi properties injection
+                            method.invoke(instance, properties);
+                        }
+                    }
+                } finally {
+                    method.setAccessible(isAccessible);
+                }
+            }
+        }
+
+        final Class parentClass = loginIdentityProviderClass.getSuperclass();
+        if (parentClass != null && 
LoginIdentityProvider.class.isAssignableFrom(parentClass)) {
+            performMethodInjection(instance, parentClass);
+        }
+    }
+
+    private void performFieldInjection(final LoginIdentityProvider instance, 
final Class loginIdentityProviderClass) throws IllegalArgumentException, 
IllegalAccessException {
+        for (final Field field : 
loginIdentityProviderClass.getDeclaredFields()) {
+            if (field.isAnnotationPresent(LoginIdentityProviderContext.class)) 
{
+                // make the method accessible
+                final boolean isAccessible = field.isAccessible();
+                field.setAccessible(true);
+
+                try {
+                    // get the type
+                    final Class<?> fieldType = field.getType();
+
+                    // only consider this field if it isn't set yet
+                    if (field.get(instance) == null) {
+                        // look for well known types
+                        if (NiFiProperties.class.isAssignableFrom(fieldType)) {
+                            // nifi properties injection
+                            field.set(instance, properties);
+                        }
+                    }
+
+                } finally {
+                    field.setAccessible(isAccessible);
+                }
+            }
+        }
+
+        final Class parentClass = loginIdentityProviderClass.getSuperclass();
+        if (parentClass != null && 
LoginIdentityProvider.class.isAssignableFrom(parentClass)) {
+            performFieldInjection(instance, parentClass);
+        }
+    }
+
+    private LoginIdentityProvider withNarLoader(final LoginIdentityProvider 
baseProvider) {
+        return new LoginIdentityProvider() {
+
+            @Override
+            public boolean supportsRegistration() {
+                try (final NarCloseable narCloseable = 
NarCloseable.withNarLoader()) {
+                    return baseProvider.supportsRegistration();
+                }
+            }
+
+            @Override
+            public void register(LoginCredentials credentials) {
+                try (final NarCloseable narCloseable = 
NarCloseable.withNarLoader()) {
+                    baseProvider.register(credentials);
+                }
+            }
+
+            @Override
+            public boolean authenticate(LoginCredentials credentials) {
+                try (final NarCloseable narCloseable = 
NarCloseable.withNarLoader()) {
+                    return baseProvider.authenticate(credentials);
+                }
+            }
+
+            @Override
+            public void initialize(LoginIdentityProviderInitializationContext 
initializationContext) throws ProviderCreationException {
+                try (final NarCloseable narCloseable = 
NarCloseable.withNarLoader()) {
+                    baseProvider.initialize(initializationContext);
+                }
+            }
+
+            @Override
+            public void onConfigured(LoginIdentityProviderConfigurationContext 
configurationContext) throws ProviderCreationException {
+                try (final NarCloseable narCloseable = 
NarCloseable.withNarLoader()) {
+                    baseProvider.onConfigured(configurationContext);
+                }
+            }
+
+            @Override
+            public void preDestruction() throws ProviderDestructionException {
+                try (final NarCloseable narCloseable = 
NarCloseable.withNarLoader()) {
+                    baseProvider.preDestruction();
+                }
+            }
+        };
+    }
+
+    @Override
+    public Class getObjectType() {
+        return LoginIdentityProvider.class;
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return true;
+    }
+
+    @Override
+    public void destroy() throws Exception {
+        if (loginIdentityProvider != null) {
+            loginIdentityProvider.preDestruction();
+        }
+    }
+
+    public void setProperties(NiFiProperties properties) {
+        this.properties = properties;
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext context) throws 
BeansException {
+        this.context = context;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/StandardLoginIdentityProviderConfigurationContext.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/StandardLoginIdentityProviderConfigurationContext.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/StandardLoginIdentityProviderConfigurationContext.java
new file mode 100644
index 0000000..5c662c7
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/StandardLoginIdentityProviderConfigurationContext.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.spring;
+
+import java.util.Collections;
+import java.util.Map;
+import 
org.apache.nifi.authentication.LoginIdentityProviderConfigurationContext;
+
+/**
+ *
+ */
+public class StandardLoginIdentityProviderConfigurationContext implements 
LoginIdentityProviderConfigurationContext {
+
+    private final String identifier;
+    private final Map<String, String> properties;
+
+    public StandardLoginIdentityProviderConfigurationContext(String 
identifier, Map<String, String> properties) {
+        this.identifier = identifier;
+        this.properties = properties;
+    }
+
+    @Override
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return Collections.unmodifiableMap(properties);
+    }
+
+    @Override
+    public String getProperty(String property) {
+        return properties.get(property);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/StandardLoginIdentityProviderInitializationContext.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/StandardLoginIdentityProviderInitializationContext.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/StandardLoginIdentityProviderInitializationContext.java
new file mode 100644
index 0000000..af54df9
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/StandardLoginIdentityProviderInitializationContext.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.spring;
+
+import 
org.apache.nifi.authentication.LoginIdentityProviderInitializationContext;
+import org.apache.nifi.authentication.LoginIdentityProviderLookup;
+
+/**
+ *
+ */
+public class StandardLoginIdentityProviderInitializationContext implements 
LoginIdentityProviderInitializationContext {
+
+    private final String identifier;
+    private final LoginIdentityProviderLookup lookup;
+
+    public StandardLoginIdentityProviderInitializationContext(String 
identifier, final LoginIdentityProviderLookup lookup) {
+        this.identifier = identifier;
+        this.lookup = lookup;
+    }
+
+    @Override
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    @Override
+    public LoginIdentityProviderLookup getAuthorityProviderLookup() {
+        return lookup;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/LoginAuthenticationRequestToken.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/LoginAuthenticationRequestToken.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/LoginAuthenticationRequestToken.java
new file mode 100644
index 0000000..d1ca4d2
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/LoginAuthenticationRequestToken.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.token;
+
+import java.util.List;
+import org.apache.nifi.authentication.LoginCredentials;
+
+/**
+ * This is an Authentication Token for requesting an ID token for accessing 
the NIFI REST API.
+ */
+public class LoginAuthenticationRequestToken extends 
NiFiAuthenticationRequestToken {
+
+    final LoginCredentials credentials;
+
+    public LoginAuthenticationRequestToken(final List<String> proxyChain, 
final LoginCredentials credentials) {
+        super(proxyChain);
+        this.credentials = credentials;
+    }
+
+    public LoginCredentials getLoginCredentials() {
+        return credentials;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/LoginAuthenticationToken.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/LoginAuthenticationToken.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/LoginAuthenticationToken.java
new file mode 100644
index 0000000..528b60b
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/LoginAuthenticationToken.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.token;
+
+import org.apache.nifi.authentication.LoginCredentials;
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+
+/**
+ * This is an Authentication Token for logging in. Once a user is 
authenticated, they can be issues an ID token.
+ */
+public class LoginAuthenticationToken extends AbstractAuthenticationToken {
+
+    final LoginCredentials credentials;
+
+    public LoginAuthenticationToken(final LoginCredentials credentials) {
+        super(null);
+        setAuthenticated(true);
+        this.credentials = credentials;
+    }
+
+    public LoginCredentials getLoginCredentials() {
+        return credentials;
+    }
+
+    @Override
+    public Object getCredentials() {
+        return credentials.getPassword();
+    }
+
+    @Override
+    public Object getPrincipal() {
+        return credentials.getUsername();
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationRequestToken.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationRequestToken.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationRequestToken.java
new file mode 100644
index 0000000..6fee4ec
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationRequestToken.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.token;
+
+import org.apache.nifi.web.security.user.NewAccountRequest;
+
+/**
+ * This is an Authentication Token for a user that is requesting 
authentication in order to submit a new account request.
+ */
+public class NewAccountAuthenticationRequestToken extends 
NiFiAuthenticationRequestToken {
+
+    final NewAccountRequest newAccountRequest;
+
+    public NewAccountAuthenticationRequestToken(final NewAccountRequest 
newAccountRequest) {
+        super(newAccountRequest.getChain());
+        this.newAccountRequest = newAccountRequest;
+    }
+
+    public String getJustification() {
+        return newAccountRequest.getJustification();
+    }
+
+    public NewAccountRequest getNewAccountRequest() {
+        return newAccountRequest;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationToken.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationToken.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationToken.java
new file mode 100644
index 0000000..5fe3a1d
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NewAccountAuthenticationToken.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.token;
+
+import org.apache.nifi.web.security.user.NewAccountRequest;
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+
+/**
+ * This is an Authentication Token for a user that has been authenticated but 
is not authorized to access the NiFi APIs. Typically, this authentication token 
is used successfully when requesting a
+ * NiFi account. Requesting any other endpoint would be rejected due to lack 
of roles.
+ */
+public class NewAccountAuthenticationToken extends AbstractAuthenticationToken 
{
+
+    final NewAccountRequest newAccountRequest;
+
+    public NewAccountAuthenticationToken(final NewAccountRequest 
newAccountRequest) {
+        super(null);
+        super.setAuthenticated(true);
+        this.newAccountRequest = newAccountRequest;
+    }
+
+    @Override
+    public Object getCredentials() {
+        return null;
+    }
+
+    @Override
+    public Object getPrincipal() {
+        return newAccountRequest;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthenticationRequestToken.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthenticationRequestToken.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthenticationRequestToken.java
new file mode 100644
index 0000000..3ae6491
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthenticationRequestToken.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.token;
+
+import java.util.Collections;
+import java.util.List;
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+
+/**
+ * An authentication token that is used as an authentication request. The 
request chain is specified during creation and is used authenticate the 
user(s). If the user is authenticated, the token is
+ * used to authorized the user(s).
+ */
+public class NiFiAuthenticationRequestToken extends 
AbstractAuthenticationToken {
+
+    private final List<String> chain;
+
+    public NiFiAuthenticationRequestToken(final List<String> chain) {
+        super(null);
+        this.chain = chain;
+    }
+
+    @Override
+    public Object getCredentials() {
+        return null;
+    }
+
+    @Override
+    public Object getPrincipal() {
+        return chain;
+    }
+
+    public List<String> getChain() {
+        return Collections.unmodifiableList(chain);
+    }
+
+    @Override
+    public final void setAuthenticated(boolean authenticated) {
+        throw new IllegalArgumentException("Cannot change the authenticated 
state.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthorizationToken.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthorizationToken.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthorizationToken.java
new file mode 100644
index 0000000..0cb0353
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/token/NiFiAuthorizationToken.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.token;
+
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.core.userdetails.UserDetails;
+
+/**
+ * An authentication token that represents an Authenticated and Authorized 
user of the NiFi Apis. The authorities are based off the specified UserDetails.
+ */
+public class NiFiAuthorizationToken extends AbstractAuthenticationToken {
+
+    final UserDetails nifiUserDetails;
+
+    public NiFiAuthorizationToken(final UserDetails nifiUserDetails) {
+        super(nifiUserDetails.getAuthorities());
+        super.setAuthenticated(true);
+        setDetails(nifiUserDetails);
+        this.nifiUserDetails = nifiUserDetails;
+    }
+
+    @Override
+    public Object getCredentials() {
+        return nifiUserDetails.getPassword();
+    }
+
+    @Override
+    public Object getPrincipal() {
+        return nifiUserDetails;
+    }
+
+    @Override
+    public final void setAuthenticated(boolean authenticated) {
+        throw new IllegalArgumentException("Cannot change the authenticated 
state.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NewAccountRequest.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NewAccountRequest.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NewAccountRequest.java
new file mode 100644
index 0000000..3ec147a
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NewAccountRequest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.user;
+
+import java.util.List;
+
+/**
+ *
+ */
+public class NewAccountRequest {
+
+    private final List<String> chain;
+    private final String justification;
+
+    public NewAccountRequest(final List<String> chain, final String 
justification) {
+        this.chain = chain;
+        this.justification = justification;
+    }
+
+    public List<String> getChain() {
+        return chain;
+    }
+
+    public String getJustification() {
+        return justification;
+    }
+
+    public String getUsername() {
+        // the end user is the first item in the chain
+        return chain.get(0);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NiFiUserDetails.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NiFiUserDetails.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NiFiUserDetails.java
index c69b1e6..5645f78 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NiFiUserDetails.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NiFiUserDetails.java
@@ -76,7 +76,6 @@ public class NiFiUserDetails implements UserDetails {
         return user.getDn();
     }
 
-    // TODO: not sure how to handle these yet
     @Override
     public boolean isAccountNonExpired() {
         return true;

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NiFiUserUtils.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NiFiUserUtils.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NiFiUserUtils.java
index bf1fe43..341663e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NiFiUserUtils.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/user/NiFiUserUtils.java
@@ -25,8 +25,7 @@ import 
org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 
 /**
- * Utility methods for retrieving information about the current application
- * user.
+ * Utility methods for retrieving information about the current application 
user.
  *
  */
 public final class NiFiUserUtils {
@@ -58,8 +57,7 @@ public final class NiFiUserUtils {
     }
 
     /**
-     * Returns the current NiFiUser or null if the current user is not a
-     * NiFiUser.
+     * Returns the current NiFiUser or null if the current user is not a 
NiFiUser.
      *
      * @return user
      */
@@ -79,6 +77,27 @@ public final class NiFiUserUtils {
         return user;
     }
 
+    /**
+     * Returns the NewAccountRequest or null if this is not a new account 
request.
+     *
+     * @return new account request
+     */
+    public static NewAccountRequest getNewAccountRequest() {
+        NewAccountRequest newAccountRequest = null;
+
+        // obtain the principal in the current authentication
+        final SecurityContext context = SecurityContextHolder.getContext();
+        final Authentication authentication = context.getAuthentication();
+        if (authentication != null) {
+            Object principal = authentication.getPrincipal();
+            if (principal instanceof NewAccountRequest) {
+                newAccountRequest = (NewAccountRequest) principal;
+            }
+        }
+
+        return newAccountRequest;
+    }
+
     public static String getNiFiUserName() {
         // get the nifi user to extract the username
         NiFiUser user = NiFiUserUtils.getNiFiUser();

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationFilter.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationFilter.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationFilter.java
index 72baecb..e57a5ac 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationFilter.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationFilter.java
@@ -17,114 +17,40 @@
 package org.apache.nifi.web.security.x509;
 
 import org.apache.nifi.web.security.x509.ocsp.OcspCertificateValidator;
-import java.io.IOException;
-import java.io.PrintWriter;
 import java.security.cert.CertificateExpiredException;
 import java.security.cert.CertificateNotYetValidException;
 import java.security.cert.X509Certificate;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
+import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import org.apache.nifi.admin.service.AdministrationException;
-import org.apache.nifi.admin.service.UserService;
-import org.apache.nifi.web.security.DnUtils;
-import org.apache.nifi.web.security.UntrustedProxyException;
-import org.apache.nifi.util.NiFiProperties;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.security.authentication.AccountStatusException;
-import 
org.springframework.security.authentication.AuthenticationServiceException;
+import org.apache.nifi.web.security.NiFiAuthenticationFilter;
+import org.apache.nifi.web.security.ProxiedEntitiesUtils;
+import org.apache.nifi.web.security.token.NewAccountAuthenticationRequestToken;
+import org.apache.nifi.web.security.token.NiFiAuthenticationRequestToken;
+import org.apache.nifi.web.security.user.NewAccountRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import 
org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
 import 
org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
 
 /**
- * Custom X509 filter that will inspect the HTTP headers for a proxied user
- * before extracting the user details from the client certificate.
+ * Custom X509 filter that will inspect the HTTP headers for a proxied user 
before extracting the user details from the client certificate.
  */
-public class X509AuthenticationFilter extends 
AbstractPreAuthenticatedProcessingFilter {
+public class X509AuthenticationFilter extends NiFiAuthenticationFilter {
 
-    public static final String PROXY_ENTITIES_CHAIN = "X-ProxiedEntitiesChain";
-    public static final String PROXY_ENTITIES_ACCEPTED = 
"X-ProxiedEntitiesAccepted";
-    public static final String PROXY_ENTITIES_DETAILS = 
"X-ProxiedEntitiesDetails";
+    private static final Logger logger = 
LoggerFactory.getLogger(X509AuthenticationFilter.class);
 
-    private final X509CertificateExtractor certificateExtractor = new 
X509CertificateExtractor();
-    private final X509PrincipalExtractor principalExtractor = new 
SubjectDnX509PrincipalExtractor();
+    private X509PrincipalExtractor principalExtractor;
+    private X509CertificateExtractor certificateExtractor;
     private OcspCertificateValidator certificateValidator;
-    private NiFiProperties properties;
-    private UserService userService;
 
     @Override
-    public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException {
-        final HttpServletResponse httpResponse = (HttpServletResponse) 
response;
-
-        // determine if this request is attempting to create a new account
-        if (isNewAccountRequest((HttpServletRequest) request)) {
-            // determine if this nifi supports new account requests
-            if (properties.getSupportNewAccountRequests()) {
-                // ensure there is a certificate in the request
-                X509Certificate certificate = 
certificateExtractor.extractClientCertificate((HttpServletRequest) request);
-                if (certificate != null) {
-                    // extract the principal from the certificate
-                    Object certificatePrincipal = 
principalExtractor.extractPrincipal(certificate);
-                    String principal = certificatePrincipal.toString();
-
-                    // log the new user account request
-                    logger.info("Requesting new user account for " + 
principal);
-
-                    try {
-                        // get the justification
-                        String justification = 
request.getParameter("justification");
-                        if (justification == null) {
-                            justification = StringUtils.EMPTY;
-                        }
-
-                        // create the pending user account
-                        userService.createPendingUserAccount(principal, 
justification);
-
-                        // generate a response
-                        httpResponse.setStatus(HttpServletResponse.SC_CREATED);
-                        httpResponse.setContentType("text/plain");
-
-                        // write the response message
-                        PrintWriter out = response.getWriter();
-                        out.println("Not authorized. User account created. 
Authorization pending.");
-                    } catch (IllegalArgumentException iae) {
-                        handleUserServiceError((HttpServletRequest) request, 
httpResponse, HttpServletResponse.SC_BAD_REQUEST, iae.getMessage());
-                    } catch (AdministrationException ae) {
-                        handleUserServiceError((HttpServletRequest) request, 
httpResponse, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ae.getMessage());
-                    }
-                } else {
-                    // can this really happen?
-                    handleMissingCertificate((HttpServletRequest) request, 
httpResponse);
-                }
-            } else {
-                handleUserServiceError((HttpServletRequest) request, 
httpResponse, HttpServletResponse.SC_NOT_FOUND, "This NiFi does not support new 
account requests.");
-            }
-        } else {
-            try {
-                // this not a request to create a user account - try to 
authorize
-                super.doFilter(request, response, chain);
-            } catch (AuthenticationException ae) {
-                // continue the filter chain since anonymous access should be 
supported
-                if (!properties.getNeedClientAuth()) {
-                    chain.doFilter(request, response);
-                } else {
-                    // create an appropriate response for the given exception
-                    handleUnsuccessfulAuthentication((HttpServletRequest) 
request, httpResponse, ae);
-                }
-            }
+    public Authentication attemptAuthentication(HttpServletRequest request, 
HttpServletResponse response) {
+        // only suppport x509 login when running securely
+        if (!request.isSecure()) {
+            return null;
         }
-    }
-
-    @Override
-    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
-        String principal;
-
+        
         // extract the cert
         X509Certificate certificate = 
certificateExtractor.extractClientCertificate(request);
 
@@ -135,7 +61,7 @@ public class X509AuthenticationFilter extends 
AbstractPreAuthenticatedProcessing
 
         // extract the principal
         Object certificatePrincipal = 
principalExtractor.extractPrincipal(certificate);
-        principal = DnUtils.formatProxyDn(certificatePrincipal.toString());
+        final String principal = 
ProxiedEntitiesUtils.formatProxyDn(certificatePrincipal.toString());
 
         try {
             // ensure the cert is valid
@@ -167,151 +93,25 @@ public class X509AuthenticationFilter extends 
AbstractPreAuthenticatedProcessing
             return null;
         }
 
-        // look for a proxied user
-        if (StringUtils.isNotBlank(request.getHeader(PROXY_ENTITIES_CHAIN))) {
-            principal = request.getHeader(PROXY_ENTITIES_CHAIN) + principal;
-        }
-
-        // log the request attempt - response details will be logged later
-        logger.info(String.format("Attempting request for (%s) %s %s (source 
ip: %s)", principal, request.getMethod(),
-                request.getRequestURL().toString(), request.getRemoteAddr()));
-
-        return principal;
-    }
-
-    @Override
-    protected Object getPreAuthenticatedCredentials(HttpServletRequest 
request) {
-        return certificateExtractor.extractClientCertificate(request);
-    }
-
-    @Override
-    protected void successfulAuthentication(HttpServletRequest request, 
HttpServletResponse response, Authentication authResult) {
-        if (StringUtils.isNotBlank(request.getHeader(PROXY_ENTITIES_CHAIN))) {
-            response.setHeader(PROXY_ENTITIES_ACCEPTED, 
Boolean.TRUE.toString());
-        }
-        super.successfulAuthentication(request, response, authResult);
-    }
-
-    @Override
-    protected void unsuccessfulAuthentication(HttpServletRequest request, 
HttpServletResponse response, AuthenticationException failed) {
-        if (StringUtils.isNotBlank(request.getHeader(PROXY_ENTITIES_CHAIN))) {
-            response.setHeader(PROXY_ENTITIES_DETAILS, failed.getMessage());
-        }
-        super.unsuccessfulAuthentication(request, response, failed);
-    }
-
-    /**
-     * Determines if the specified request is attempting to register a new user
-     * account.
-     *
-     * @param request http request
-     * @return true if new user
-     */
-    private boolean isNewAccountRequest(HttpServletRequest request) {
-        if ("POST".equalsIgnoreCase(request.getMethod())) {
-            String path = request.getPathInfo();
-            if (StringUtils.isNotBlank(path)) {
-                if ("/controller/users".equals(path)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Handles requests that were unable to be authorized.
-     *
-     * @param request request
-     * @param response response
-     * @param ae ex
-     * @throws IOException ex
-     */
-    private void handleUnsuccessfulAuthentication(HttpServletRequest request, 
HttpServletResponse response, AuthenticationException ae) throws IOException {
-        // set the response status
-        response.setContentType("text/plain");
-
-        // write the response message
-        PrintWriter out = response.getWriter();
-
-        // use the type of authentication exception to determine the response 
code
-        if (ae instanceof UsernameNotFoundException) {
-            if (properties.getSupportNewAccountRequests()) {
-                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
-                out.println("Not authorized.");
-            } else {
-                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
-                out.println("Access is denied.");
-            }
-        } else if (ae instanceof AccountStatusException) {
-            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
-            out.println(ae.getMessage());
-        } else if (ae instanceof UntrustedProxyException) {
-            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
-            out.println(ae.getMessage());
-        } else if (ae instanceof AuthenticationServiceException) {
-            logger.error(String.format("Unable to authorize: %s", 
ae.getMessage()), ae);
-            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-            out.println(String.format("Unable to authorize: %s", 
ae.getMessage()));
+        final List<String> proxyChain = 
ProxiedEntitiesUtils.buildProxyChain(request, principal);
+        if (isNewAccountRequest(request)) {
+            return new NewAccountAuthenticationRequestToken(new 
NewAccountRequest(proxyChain, getJustification(request)));
         } else {
-            logger.error(String.format("Unable to authorize: %s", 
ae.getMessage()), ae);
-            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
-            out.println("Access is denied.");
-        }
-
-        // log the failure
-        logger.info(String.format("Rejecting access to web api: %s", 
ae.getMessage()));
-
-        // optionally log the stack trace
-        if (logger.isDebugEnabled()) {
-            logger.debug(StringUtils.EMPTY, ae);
+            return new NiFiAuthenticationRequestToken(proxyChain);
         }
     }
 
-    private void handleUserServiceError(HttpServletRequest request, 
HttpServletResponse response, int responseCode, String message) throws 
IOException {
-        // set the response status
-        response.setContentType("text/plain");
-        response.setStatus(responseCode);
-
-        // write the response message
-        PrintWriter out = response.getWriter();
-        out.println(message);
-
-        // log the failure
-        logger.info(String.format("Unable to process request because %s", 
message));
-    }
-
-    /**
-     * Handles requests that failed because they were bad input.
-     *
-     * @param request request
-     * @param response response
-     * @throws IOException ioe
-     */
-    private void handleMissingCertificate(HttpServletRequest request, 
HttpServletResponse response) throws IOException {
-        // set the response status
-        response.setContentType("text/plain");
-        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
-
-        // write the response message
-        PrintWriter out = response.getWriter();
-        out.println("Unable to process request because the user certificate 
was not specified.");
-
-        // log the failure
-        logger.info("Unable to process request because the user certificate 
was not specified.");
-    }
-
     /* setters */
-    public void setProperties(NiFiProperties properties) {
-        this.properties = properties;
+    public void setCertificateValidator(OcspCertificateValidator 
certificateValidator) {
+        this.certificateValidator = certificateValidator;
     }
 
-    public void setUserService(UserService userService) {
-        this.userService = userService;
+    public void setPrincipalExtractor(X509PrincipalExtractor 
principalExtractor) {
+        this.principalExtractor = principalExtractor;
     }
 
-    public void setCertificateValidator(OcspCertificateValidator 
certificateValidator) {
-        this.certificateValidator = certificateValidator;
+    public void setCertificateExtractor(X509CertificateExtractor 
certificateExtractor) {
+        this.certificateExtractor = certificateExtractor;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationFilterOld.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationFilterOld.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationFilterOld.java
new file mode 100644
index 0000000..711639b
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationFilterOld.java
@@ -0,0 +1,317 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.x509;
+
+import org.apache.nifi.web.security.x509.ocsp.OcspCertificateValidator;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.nifi.admin.service.AdministrationException;
+import org.apache.nifi.admin.service.UserService;
+import org.apache.nifi.web.security.ProxiedEntitiesUtils;
+import org.apache.nifi.web.security.UntrustedProxyException;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.security.authentication.AccountStatusException;
+import 
org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import 
org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
+import 
org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
+
+/**
+ * Custom X509 filter that will inspect the HTTP headers for a proxied user
+ * before extracting the user details from the client certificate.
+ */
+public class X509AuthenticationFilterOld extends 
AbstractPreAuthenticatedProcessingFilter {
+
+    public static final String PROXY_ENTITIES_CHAIN = "X-ProxiedEntitiesChain";
+    public static final String PROXY_ENTITIES_ACCEPTED = 
"X-ProxiedEntitiesAccepted";
+    public static final String PROXY_ENTITIES_DETAILS = 
"X-ProxiedEntitiesDetails";
+
+    private final X509CertificateExtractor certificateExtractor = new 
X509CertificateExtractor();
+    private final X509PrincipalExtractor principalExtractor = new 
SubjectDnX509PrincipalExtractor();
+    private OcspCertificateValidator certificateValidator;
+    private NiFiProperties properties;
+    private UserService userService;
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException {
+        final HttpServletResponse httpResponse = (HttpServletResponse) 
response;
+
+        // determine if this request is attempting to create a new account
+        if (isNewAccountRequest((HttpServletRequest) request)) {
+            // determine if this nifi supports new account requests
+            if (properties.getSupportNewAccountRequests()) {
+                // ensure there is a certificate in the request
+                X509Certificate certificate = 
certificateExtractor.extractClientCertificate((HttpServletRequest) request);
+                if (certificate != null) {
+                    // extract the principal from the certificate
+                    Object certificatePrincipal = 
principalExtractor.extractPrincipal(certificate);
+                    String principal = certificatePrincipal.toString();
+
+                    // log the new user account request
+                    logger.info("Requesting new user account for " + 
principal);
+
+                    try {
+                        // get the justification
+                        String justification = 
request.getParameter("justification");
+                        if (justification == null) {
+                            justification = StringUtils.EMPTY;
+                        }
+
+                        // create the pending user account
+                        userService.createPendingUserAccount(principal, 
justification);
+
+                        // generate a response
+                        httpResponse.setStatus(HttpServletResponse.SC_CREATED);
+                        httpResponse.setContentType("text/plain");
+
+                        // write the response message
+                        PrintWriter out = response.getWriter();
+                        out.println("Not authorized. User account created. 
Authorization pending.");
+                    } catch (IllegalArgumentException iae) {
+                        handleUserServiceError((HttpServletRequest) request, 
httpResponse, HttpServletResponse.SC_BAD_REQUEST, iae.getMessage());
+                    } catch (AdministrationException ae) {
+                        handleUserServiceError((HttpServletRequest) request, 
httpResponse, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ae.getMessage());
+                    }
+                } else {
+                    // can this really happen?
+                    handleMissingCertificate((HttpServletRequest) request, 
httpResponse);
+                }
+            } else {
+                handleUserServiceError((HttpServletRequest) request, 
httpResponse, HttpServletResponse.SC_NOT_FOUND, "This NiFi does not support new 
account requests.");
+            }
+        } else {
+            try {
+                // this not a request to create a user account - try to 
authorize
+                super.doFilter(request, response, chain);
+            } catch (AuthenticationException ae) {
+                // continue the filter chain since anonymous access should be 
supported
+                if (!properties.getNeedClientAuth()) {
+                    chain.doFilter(request, response);
+                } else {
+                    // create an appropriate response for the given exception
+                    handleUnsuccessfulAuthentication((HttpServletRequest) 
request, httpResponse, ae);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
+        String principal;
+
+        // extract the cert
+        X509Certificate certificate = 
certificateExtractor.extractClientCertificate(request);
+
+        // ensure the cert was found
+        if (certificate == null) {
+            return null;
+        }
+
+        // extract the principal
+        Object certificatePrincipal = 
principalExtractor.extractPrincipal(certificate);
+        principal = 
ProxiedEntitiesUtils.formatProxyDn(certificatePrincipal.toString());
+
+        try {
+            // ensure the cert is valid
+            certificate.checkValidity();
+        } catch (CertificateExpiredException cee) {
+            final String message = String.format("Client certificate for (%s) 
is expired.", principal);
+            logger.info(message, cee);
+            if (logger.isDebugEnabled()) {
+                logger.debug("", cee);
+            }
+            return null;
+        } catch (CertificateNotYetValidException cnyve) {
+            final String message = String.format("Client certificate for (%s) 
is not yet valid.", principal);
+            logger.info(message, cnyve);
+            if (logger.isDebugEnabled()) {
+                logger.debug("", cnyve);
+            }
+            return null;
+        }
+
+        // validate the certificate in question
+        try {
+            certificateValidator.validate(request);
+        } catch (final Exception e) {
+            logger.info(e.getMessage());
+            if (logger.isDebugEnabled()) {
+                logger.debug("", e);
+            }
+            return null;
+        }
+
+        // look for a proxied user
+        if (StringUtils.isNotBlank(request.getHeader(PROXY_ENTITIES_CHAIN))) {
+            principal = request.getHeader(PROXY_ENTITIES_CHAIN) + principal;
+        }
+
+        // log the request attempt - response details will be logged later
+        logger.info(String.format("Attempting request for (%s) %s %s (source 
ip: %s)", principal, request.getMethod(),
+                request.getRequestURL().toString(), request.getRemoteAddr()));
+
+        return principal;
+    }
+
+    @Override
+    protected Object getPreAuthenticatedCredentials(HttpServletRequest 
request) {
+        return certificateExtractor.extractClientCertificate(request);
+    }
+
+    @Override
+    protected void successfulAuthentication(HttpServletRequest request, 
HttpServletResponse response, Authentication authResult) {
+        if (StringUtils.isNotBlank(request.getHeader(PROXY_ENTITIES_CHAIN))) {
+            response.setHeader(PROXY_ENTITIES_ACCEPTED, 
Boolean.TRUE.toString());
+        }
+        super.successfulAuthentication(request, response, authResult);
+    }
+
+    @Override
+    protected void unsuccessfulAuthentication(HttpServletRequest request, 
HttpServletResponse response, AuthenticationException failed) {
+        if (StringUtils.isNotBlank(request.getHeader(PROXY_ENTITIES_CHAIN))) {
+            response.setHeader(PROXY_ENTITIES_DETAILS, failed.getMessage());
+        }
+        super.unsuccessfulAuthentication(request, response, failed);
+    }
+
+    /**
+     * Determines if the specified request is attempting to register a new user
+     * account.
+     *
+     * @param request http request
+     * @return true if new user
+     */
+    private boolean isNewAccountRequest(HttpServletRequest request) {
+        if ("POST".equalsIgnoreCase(request.getMethod())) {
+            String path = request.getPathInfo();
+            if (StringUtils.isNotBlank(path)) {
+                if ("/controller/users".equals(path)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Handles requests that were unable to be authorized.
+     *
+     * @param request request
+     * @param response response
+     * @param ae ex
+     * @throws IOException ex
+     */
+    private void handleUnsuccessfulAuthentication(HttpServletRequest request, 
HttpServletResponse response, AuthenticationException ae) throws IOException {
+        // set the response status
+        response.setContentType("text/plain");
+
+        // write the response message
+        PrintWriter out = response.getWriter();
+
+        // use the type of authentication exception to determine the response 
code
+        if (ae instanceof UsernameNotFoundException) {
+            if (properties.getSupportNewAccountRequests()) {
+                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+                out.println("Not authorized.");
+            } else {
+                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+                out.println("Access is denied.");
+            }
+        } else if (ae instanceof AccountStatusException) {
+            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+            out.println(ae.getMessage());
+        } else if (ae instanceof UntrustedProxyException) {
+            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+            out.println(ae.getMessage());
+        } else if (ae instanceof AuthenticationServiceException) {
+            logger.error(String.format("Unable to authorize: %s", 
ae.getMessage()), ae);
+            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            out.println(String.format("Unable to authorize: %s", 
ae.getMessage()));
+        } else {
+            logger.error(String.format("Unable to authorize: %s", 
ae.getMessage()), ae);
+            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+            out.println("Access is denied.");
+        }
+
+        // log the failure
+        logger.info(String.format("Rejecting access to web api: %s", 
ae.getMessage()));
+
+        // optionally log the stack trace
+        if (logger.isDebugEnabled()) {
+            logger.debug(StringUtils.EMPTY, ae);
+        }
+    }
+
+    private void handleUserServiceError(HttpServletRequest request, 
HttpServletResponse response, int responseCode, String message) throws 
IOException {
+        // set the response status
+        response.setContentType("text/plain");
+        response.setStatus(responseCode);
+
+        // write the response message
+        PrintWriter out = response.getWriter();
+        out.println(message);
+
+        // log the failure
+        logger.info(String.format("Unable to process request because %s", 
message));
+    }
+
+    /**
+     * Handles requests that failed because they were bad input.
+     *
+     * @param request request
+     * @param response response
+     * @throws IOException ioe
+     */
+    private void handleMissingCertificate(HttpServletRequest request, 
HttpServletResponse response) throws IOException {
+        // set the response status
+        response.setContentType("text/plain");
+        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+
+        // write the response message
+        PrintWriter out = response.getWriter();
+        out.println("Unable to process request because the user certificate 
was not specified.");
+
+        // log the failure
+        logger.info("Unable to process request because the user certificate 
was not specified.");
+    }
+
+    /* setters */
+    public void setProperties(NiFiProperties properties) {
+        this.properties = properties;
+    }
+
+    public void setUserService(UserService userService) {
+        this.userService = userService;
+    }
+
+    public void setCertificateValidator(OcspCertificateValidator 
certificateValidator) {
+        this.certificateValidator = certificateValidator;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
new file mode 100644
index 0000000..df23856
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.x509;
+
+import org.apache.nifi.web.security.token.NewAccountAuthenticationRequestToken;
+import org.apache.nifi.web.security.token.NewAccountAuthenticationToken;
+import org.apache.nifi.web.security.token.NiFiAuthenticationRequestToken;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+
+/**
+ *
+ */
+public class X509AuthenticationProvider implements AuthenticationProvider {
+
+    @Override
+    public Authentication authenticate(Authentication authentication) throws 
AuthenticationException {
+        if 
(NewAccountAuthenticationRequestToken.class.isAssignableFrom(authentication.getClass()))
 {
+            return new 
NewAccountAuthenticationToken(((NewAccountAuthenticationRequestToken) 
authentication).getNewAccountRequest());
+        } else if 
(NiFiAuthenticationRequestToken.class.isAssignableFrom(authentication.getClass()))
 {
+            return authentication;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean supports(Class<?> authentication) {
+        return 
NiFiAuthenticationRequestToken.class.isAssignableFrom(authentication);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml
index fa5b9e2..5f4e1b2 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/resources/nifi-web-security-context.xml
@@ -13,71 +13,80 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 -->
-<!-- marked as lazy so that security beans are not created when applications 
runs in non-secure mode -->
-<beans default-lazy-init="true"
-       xmlns="http://www.springframework.org/schema/beans";
+<beans xmlns="http://www.springframework.org/schema/beans";
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-       xmlns:sec="http://www.springframework.org/schema/security";
-       xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
-    http://www.springframework.org/schema/security 
http://www.springframework.org/schema/security/spring-security-3.2.xsd";>
+       xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd";>
 
-    <!-- http security configuration -->
-    <sec:http create-session="stateless" auto-config="false" 
entry-point-ref="entryPoint">
+<!--    <sec:http create-session="stateless" auto-config="false" 
entry-point-ref="entryPoint">
         <sec:anonymous enabled="false"/>
         <sec:custom-filter ref="nodeAuthorizedUserFilter" 
before="PRE_AUTH_FILTER"/>
         <sec:custom-filter ref="x509Filter" position="PRE_AUTH_FILTER"/>
         <sec:custom-filter ref="anonymousFilter" position="ANONYMOUS_FILTER"/>
-    </sec:http>
+    </sec:http>-->
 
     <!-- enable method level security -->
-    <sec:global-method-security pre-post-annotations="enabled"/>
+    <!--<sec:global-method-security pre-post-annotations="enabled"/>-->
+
+    <!--<bean 
class="org.apache.nifi.web.security.NiFiSecurityWebApplicationInitializer"></bean>-->
+
+    <!-- security config -->
+<!--    <bean id="securityConfig" 
class="org.apache.nifi.web.security.NiFiSecurityConfig">
+        <property name="properties" ref="nifiProperties"/>
+        <property name="userDetailsService" ref="userAuthorizationService"/>
+        <property name="authorizedUserFilter" ref="nodeAuthorizedUserFilter"/>
+        <property name="entryPoint" ref="entryPoint"/>
+    </bean>-->
 
     <!-- entry point reference -->
-    <bean id="entryPoint" 
class="org.apache.nifi.web.security.authentication.NiFiAuthenticationEntryPoint"/>
+    <!--<bean id="entryPoint" 
class="org.apache.nifi.web.security.authentication.NiFiAuthenticationEntryPoint"/>-->
     
     <!-- authentication manager -->
-    <sec:authentication-manager alias="authenticationManager">
+<!--    <sec:authentication-manager alias="authenticationManager">
         <sec:authentication-provider ref="preauthAuthProvider"/>
-    </sec:authentication-manager>
+    </sec:authentication-manager>-->
 
     <!-- pre-authentication provider -->
-    <bean id="preauthAuthProvider" 
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
+<!--    <bean id="preauthAuthProvider" 
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
         <property name="preAuthenticatedUserDetailsService">
             <bean 
class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
                 <property name="userDetailsService" 
ref="userAuthorizationService"/>
             </bean>
         </property>
-    </bean>
+    </bean>-->
 
     <!-- user details service -->
-    <bean id="userAuthorizationService" 
class="org.apache.nifi.web.security.authorization.NiFiAuthorizationService">
+    <bean id="userDetailsService" 
class="org.apache.nifi.web.security.authorization.NiFiAuthorizationService">
         <property name="userService" ref="userService"/>
         <property name="properties" ref="nifiProperties"/>
     </bean>
-
+    
+    <!-- jwt service -->
+    <bean id="jwtService" 
class="org.apache.nifi.web.security.jwt.JwtService"></bean>
+    
+    <!-- login identity provider -->
+    <bean id="loginIdentityProvider" 
class="org.apache.nifi.web.security.spring.LoginIdentityProviderFactoryBean">
+        <property name="properties" ref="nifiProperties"/>
+    </bean>
+    
     <!-- performs ocsp certificate validation -->
-    <bean id="ocspCertificateValidator" 
class="org.apache.nifi.web.security.x509.ocsp.OcspCertificateValidator">
+<!--    <bean id="ocspCertificateValidator" 
class="org.apache.nifi.web.security.x509.ocsp.OcspCertificateValidator">
         <constructor-arg ref="nifiProperties"/>
-    </bean>
+    </bean>-->
 
     <!-- custom x509 filter for checking for proxied users -->
-    <bean id="x509Filter" 
class="org.apache.nifi.web.security.x509.X509AuthenticationFilter">
-        <property name="authenticationManager" ref="authenticationManager"/>
-        <property name="properties" ref="nifiProperties"/>
-        <property name="userService" ref="userService"/>
+<!--    <bean id="x509Filter" 
class="org.apache.nifi.web.security.x509.X509AuthenticationFilter">
         <property name="certificateValidator" ref="ocspCertificateValidator"/>
-        <property name="continueFilterChainOnUnsuccessfulAuthentication" 
value="false"/>
-    </bean>
+    </bean>-->
 
     <!-- custom filter for checking for proxied users that are already 
authenticated -->
-    <bean id="nodeAuthorizedUserFilter" 
class="org.apache.nifi.web.security.authorization.NodeAuthorizedUserFilter">
+<!--    <bean id="nodeAuthorizedUserFilter" 
class="org.apache.nifi.web.security.authorization.NodeAuthorizedUserFilter">
         <property name="properties" ref="nifiProperties"/>
-    </bean>
+    </bean>-->
 
     <!-- custom anonymous filter to assign default roles based on current 
operating mode -->
-    <bean id="anonymousFilter" 
class="org.apache.nifi.web.security.anonymous.NiFiAnonymousUserFilter">
+<!--    <bean id="anonymousFilter" 
class="org.apache.nifi.web.security.anonymous.NiFiAnonymousUserFilter">
         <property name="userService" ref="userService"/>
         <property name="properties" ref="nifiProperties"/>
-    </bean>
+    </bean>-->
     
 </beans>

http://git-wip-us.apache.org/repos/asf/nifi/blob/a40e5a07/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/xsd/login-identity-providers.xsd
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/xsd/login-identity-providers.xsd
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/xsd/login-identity-providers.xsd
new file mode 100644
index 0000000..628f390
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/xsd/login-identity-providers.xsd
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";>
+    <!-- role -->
+    <xs:complexType name="Provider">
+        <xs:sequence>
+            <xs:element name="identifier" type="NonEmptyStringType"/>
+            <xs:element name="class" type="NonEmptyStringType"/>
+            <xs:element name="property" type="Property" minOccurs="0" 
maxOccurs="unbounded" />
+        </xs:sequence>
+    </xs:complexType>
+
+    <!-- Name/Value properties-->
+    <xs:complexType name="Property">
+        <xs:simpleContent>
+            <xs:extension base="xs:string">
+                <xs:attribute name="name" 
type="NonEmptyStringType"></xs:attribute>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+
+    <xs:simpleType name="NonEmptyStringType">
+        <xs:restriction base="xs:string">
+            <xs:minLength value="1"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <!-- login identity provider -->
+    <xs:element name="loginIdentityProviders">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="provider" type="Provider" minOccurs="0" 
maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+</xs:schema>
\ No newline at end of file

Reply via email to