directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From plusplusjia...@apache.org
Subject directory-kerby git commit: Move TokenAuthLoginModule from integration-test module into the kerb-client module.
Date Wed, 28 Jun 2017 02:21:36 GMT
Repository: directory-kerby
Updated Branches:
  refs/heads/trunk 1976ce853 -> 87a1deea8


Move TokenAuthLoginModule from integration-test module into the kerb-client module.


Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/87a1deea
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/87a1deea
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/87a1deea

Branch: refs/heads/trunk
Commit: 87a1deea8ccdb04949a74081c033e9d16eaf4001
Parents: 1976ce8
Author: plusplusjiajia <jiajia.li@intel.com>
Authored: Wed Jun 28 10:21:04 2017 +0800
Committer: plusplusjiajia <jiajia.li@intel.com>
Committed: Wed Jun 28 10:21:04 2017 +0800

----------------------------------------------------------------------
 .../test/jaas/TokenAuthLoginModule.java         | 373 -------------------
 .../kerb/integration/test/jaas/TokenCache.java  | 119 ------
 .../integration/test/jaas/TokenJaasKrbUtil.java | 146 --------
 .../integration/test/TokenLoginTestBase.java    |   4 +-
 kerby-kerb/kerb-client/pom.xml                  |   5 +
 .../kerb/client/jaas/TokenAuthLoginModule.java  | 372 ++++++++++++++++++
 .../kerberos/kerb/client/jaas/TokenCache.java   | 119 ++++++
 .../kerb/client/jaas/TokenJaasKrbUtil.java      | 146 ++++++++
 8 files changed, 644 insertions(+), 640 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/87a1deea/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenAuthLoginModule.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenAuthLoginModule.java b/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenAuthLoginModule.java
deleted file mode 100644
index f12f9f0..0000000
--- a/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenAuthLoginModule.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- *
- */
-package org.apache.kerby.kerberos.kerb.integration.test.jaas;
-
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.KrbRuntime;
-import org.apache.kerby.kerberos.kerb.client.Krb5Conf;
-import org.apache.kerby.kerberos.kerb.client.KrbClient;
-import org.apache.kerby.kerberos.kerb.client.KrbConfig;
-import org.apache.kerby.kerberos.kerb.client.KrbTokenClient;
-import org.apache.kerby.kerberos.kerb.common.PrivateKeyReader;
-import org.apache.kerby.kerberos.kerb.provider.TokenDecoder;
-import org.apache.kerby.kerberos.kerb.provider.TokenEncoder;
-import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
-import org.apache.kerby.kerberos.kerb.type.base.KrbToken;
-import org.apache.kerby.kerberos.kerb.type.base.TokenFormat;
-import org.apache.kerby.kerberos.kerb.type.kdc.EncKdcRepPart;
-import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
-import org.apache.kerby.kerberos.provider.token.JwtAuthToken;
-import org.apache.kerby.kerberos.provider.token.JwtTokenEncoder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.nimbusds.jwt.JWT;
-import com.nimbusds.jwt.JWTParser;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.kerberos.KerberosPrincipal;
-import javax.security.auth.kerberos.KerberosTicket;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
-import java.io.File;
-import java.io.InputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.text.ParseException;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * This <code>LoginModule</code> authenticates users using token.
- * tokenStr: token-string
- * tokenCache: token-cache-file
- * armorCache: armor-cache-file
- */
-public class TokenAuthLoginModule implements LoginModule {
-    public static final String PRINCIPAL = "principal";
-    public static final String TOKEN = "token";
-    public static final String TOKEN_CACHE = "tokenCache";
-    public static final String ARMOR_CACHE = "armorCache";
-    public static final String CREDENTIAL_CACHE = "credentialCache";
-    public static final String SIGN_KEY_FILE = "signKeyFile";
-
-    private static final Logger LOG = LoggerFactory.getLogger(TokenAuthLoginModule.class);
-
-    /** initial state*/
-    private Subject subject;
-
-    /** configurable option*/
-    private String tokenCacheName = null;
-
-    /** the authentication status*/
-    private boolean succeeded = false;
-    private boolean commitSucceeded = false;
-
-    private String princName = null;
-    private String tokenStr = null;
-    private AuthToken authToken = null;
-    private KrbToken krbToken = null;
-    private File armorCache;
-    private File cCache;
-    private File signKeyFile;
-
-    private TgtTicket tgtTicket;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void initialize(Subject subject, CallbackHandler callbackHandler,
-                           Map<String, ?> sharedState, Map<String, ?> options) {
-
-        this.subject = subject;
-        /** initialize any configured options*/
-        princName = (String) options.get(PRINCIPAL);
-        tokenStr = (String) options.get(TOKEN);
-        tokenCacheName = (String) options.get(TOKEN_CACHE);
-        if ((String) options.get(ARMOR_CACHE) != null) {
-            armorCache = new File((String) options.get(ARMOR_CACHE));
-        }
-        if ((String) options.get(CREDENTIAL_CACHE) != null) {
-            cCache = new File((String) options.get(CREDENTIAL_CACHE));
-        }
-        if ((String) options.get(SIGN_KEY_FILE) != null) {
-            signKeyFile = new File((String) options.get(SIGN_KEY_FILE));
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean login() throws LoginException {
-        validateConfiguration();
-
-        succeeded = tokenLogin();
-        return succeeded;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean commit() throws LoginException {
-
-        if (!succeeded) {
-            return false;
-        } else {
-            KerberosTicket ticket = null;
-            try {
-                EncKdcRepPart encKdcRepPart = tgtTicket.getEncKdcRepPart();
-                boolean[] flags = new boolean[7];
-                int flag = encKdcRepPart.getFlags().getFlags();
-                for (int i = 6; i >= 0; i--) {
-                    flags[i] = (flag & (1 << i)) != 0;
-                }
-                Date startTime = null;
-                if (encKdcRepPart.getStartTime() != null) {
-                    startTime = encKdcRepPart.getStartTime().getValue();
-                }
-
-                ticket = new KerberosTicket(tgtTicket.getTicket().encode(),
-                    new KerberosPrincipal(tgtTicket.getClientPrincipal().getName()),
-                    new KerberosPrincipal(tgtTicket.getEncKdcRepPart().getSname().getName()),
-                    encKdcRepPart.getKey().getKeyData(),
-                    encKdcRepPart.getKey().getKeyType().getValue(),
-                    flags,
-                    encKdcRepPart.getAuthTime().getValue(),
-                    startTime,
-                    encKdcRepPart.getEndTime().getValue(),
-                    encKdcRepPart.getRenewTill().getValue(),
-                    null
-                );
-            } catch (IOException e) {
-                LOG.error("Commit Failed. " + e.toString());
-            }
-            subject.getPrivateCredentials().add(ticket);
-            if (princName != null) {
-                subject.getPrincipals().add(new KerberosPrincipal(princName));
-            }
-        }
-        commitSucceeded = true;
-        LOG.info("Commit Succeeded \n");
-        return true;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean abort() throws LoginException {
-        if (succeeded == false) {
-            return false;
-        } else if (succeeded == true && commitSucceeded == false) {
-            // login succeeded but overall authentication failed
-            succeeded = false;
-        } else {
-            // overall authentication succeeded and commit succeeded,
-            // but someone else's commit failed
-            logout();
-        }
-        return true;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean logout() throws LoginException {
-        LOG.info("\t\t[TokenAuthLoginModule]: Entering logout");
-
-        if (subject.isReadOnly()) {
-            throw new LoginException("Subject is Readonly");
-        }
-
-        for (Principal principal: subject.getPrincipals()) {
-            if (principal.getName().equals(princName)) {
-                subject.getPrincipals().remove(principal);
-            }
-        }
-        // Let us remove all Kerberos credentials stored in the Subject
-        Iterator<Object> it = subject.getPrivateCredentials().iterator();
-        while (it.hasNext()) {
-            Object o = it.next();
-            if (o instanceof KrbToken) {
-                it.remove();
-            }
-        }
-
-        cleanup();
-
-        succeeded = false;
-        commitSucceeded = false;
-
-        LOG.info("\t\t[TokenAuthLoginModule]: logged out Subject");
-        return true;
-    }
-
-    private void validateConfiguration() throws LoginException {
-
-        if (armorCache == null) {
-            throw new LoginException("An armor cache must be specified via the armorCache configuration option");
-        }
-
-        if (cCache == null) {
-            throw new LoginException("A credential cache must be specified via the credentialCache"
-            + " configuration option");
-        }
-
-        String error = "";
-        if (tokenStr == null && tokenCacheName == null) {
-            error = "useToken is specified but no token or token cache is provided";
-        } else if (tokenStr != null && tokenCacheName != null) {
-            error = "either token or token cache should be provided but not both";
-        }
-
-        if (!error.isEmpty()) {
-            throw new LoginException(error);
-        }
-    }
-
-    private boolean tokenLogin() throws LoginException {
-        if (tokenStr == null) {
-            tokenStr = TokenCache.readToken(tokenCacheName);
-            if (tokenStr == null) {
-                throw new LoginException("No valid token was found in token cache: " + tokenCacheName);
-            }
-        }
-
-        krbToken = new KrbToken();
-
-        // Sign the token.
-        if (signKeyFile != null) {
-            try {
-                TokenDecoder tokenDecoder = KrbRuntime.getTokenProvider().createTokenDecoder();
-                try {
-                    authToken = tokenDecoder.decodeFromString(tokenStr);
-                } catch (IOException e) {
-                    LOG.error("Token decode failed. " + e.toString());
-                }
-                krbToken = new KrbToken(authToken, TokenFormat.JWT);
-                TokenEncoder tokenEncoder = KrbRuntime.getTokenProvider().createTokenEncoder();
-
-                if (tokenEncoder instanceof JwtTokenEncoder) {
-                    PrivateKey signKey = null;
-                    try {
-                        InputStream is = Files.newInputStream(signKeyFile.toPath());
-                        signKey = PrivateKeyReader.loadPrivateKey(is);
-                    } catch (IOException e) {
-                        LOG.error("Failed to load private key from file: "
-                                + signKeyFile.getName());
-                    } catch (Exception e) {
-                        LOG.error(e.toString());
-                    }
-
-                    ((JwtTokenEncoder) tokenEncoder).setSignKey((RSAPrivateKey) signKey);
-                }
-
-                krbToken.setTokenValue(tokenEncoder.encodeAsBytes(authToken));
-            } catch (KrbException e) {
-                throw new RuntimeException("Failed to encode AuthToken", e);
-            }
-        } else {
-            // Otherwise just write out the token (which could be already signed)
-            krbToken.setTokenValue(tokenStr.getBytes());
-
-            try {
-                JWT jwt = JWTParser.parse(tokenStr);
-                authToken = new JwtAuthToken(jwt.getJWTClaimsSet());
-            } catch (ParseException e) {
-                // Invalid JWT encoding
-                throw new RuntimeException("Failed to parse JWT token string", e);
-            }
-        }
-
-        krbToken.setInnerToken(authToken);
-        krbToken.setTokenType();
-        krbToken.setTokenFormat(TokenFormat.JWT);
-
-        KrbClient krbClient = null;
-        try {
-            File confFile = new File(System.getProperty(Krb5Conf.KRB5_CONF));
-            KrbConfig krbConfig = new KrbConfig();
-            krbConfig.addKrb5Config(confFile);
-            krbClient = new KrbClient(krbConfig);
-            krbClient.init();
-        } catch (KrbException | IOException e) {
-            LOG.error("KrbClient init failed. " + e.toString());
-        }
-
-        KrbTokenClient tokenClient = new KrbTokenClient(krbClient);
-        try {
-            tgtTicket = tokenClient.requestTgt(krbToken,
-                armorCache.getAbsolutePath());
-        } catch (KrbException e) {
-            throwWith("Failed to do login with token: " + tokenStr, e);
-            return false;
-        }
-
-        try {
-            cCache = makeTgtCache();
-        } catch (IOException e) {
-            LOG.error("Failed to make tgtCache. " + e.toString());
-        }
-        try {
-            if (krbClient != null) {
-                krbClient.storeTicket(tgtTicket, cCache);
-            }
-        } catch (KrbException e) {
-            LOG.error("Failed to store tgtTicket to " + cCache.getName());
-        }
-        return true;
-    }
-
-    private File makeTgtCache() throws IOException {
-
-        if (!cCache.exists() && !cCache.createNewFile()) {
-            throw new IOException("Failed to create tgtcache file "
-                    + cCache.getAbsolutePath());
-        }
-        cCache.setExecutable(false);
-        cCache.setReadable(true);
-        cCache.setWritable(true);
-        return cCache;
-    }
-
-    private void cleanup() {
-        if (cCache != null && cCache.exists()) {
-            boolean delete = cCache.delete();
-            if (!delete) {
-                throw new RuntimeException("File delete error!");
-            }
-        }
-    }
-
-    private void throwWith(String error, Exception cause) throws LoginException {
-        LoginException le = new LoginException(error);
-        le.initCause(cause);
-        throw le;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/87a1deea/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenCache.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenCache.java b/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenCache.java
deleted file mode 100644
index 2db73fe..0000000
--- a/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenCache.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- *
- */
-package org.apache.kerby.kerberos.kerb.integration.test.jaas;
-
-
-import org.apache.commons.io.output.FileWriterWithEncoding;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.Writer;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.List;
-
-/**
- * This class provides APIs for converting token cache file with token string.
- */
-public class TokenCache {
-    private static final Logger LOG = LoggerFactory
-            .getLogger(TokenCache.class);
-
-    private static final String DEFAULT_TOKEN_CACHE_PATH = ".tokenauth";
-    private static final String TOKEN_CACHE_FILE = ".tokenauth.token";
-
-    /**
-     * Obtain token string from token cache file.
-     *
-     * @param tokenCacheFile The file stored token
-     * @return Token string
-     */
-    public static String readToken(String tokenCacheFile) {
-        File cacheFile;
-
-        if (tokenCacheFile != null && !tokenCacheFile.isEmpty()) {
-            cacheFile = new File(tokenCacheFile);
-            if (!cacheFile.exists()) {
-                throw new RuntimeException("Invalid token cache specified: " + tokenCacheFile);
-            }
-        } else {
-            cacheFile = getDefaultTokenCache();
-            if (!cacheFile.exists()) {
-                throw new RuntimeException("No token cache available by default");
-            }
-        }
-
-        String token = null;
-        try {
-            List<String> lines = Files.readAllLines(cacheFile.toPath(), StandardCharsets.UTF_8);
-            if (lines != null && !lines.isEmpty()) {
-                token = lines.get(0);
-            }
-        } catch (IOException ex) {
-            LOG.error("Failed to read file: " + cacheFile.getName());
-        }
-
-        return token;
-    }
-
-    /**
-     * Write the token string to token cache file.
-     *
-     * @param token The token string
-     */
-    public static void writeToken(String token, String tokenCacheFile) {
-        File cacheFile = new File(tokenCacheFile);
-
-        try {
-            Writer writer = new FileWriterWithEncoding(cacheFile, StandardCharsets.UTF_8);
-            writer.write(token);
-            writer.flush();
-            writer.close();
-            // sets read-write permissions to owner only
-            cacheFile.setReadable(false, false);
-            cacheFile.setReadable(true, true);
-            if (!cacheFile.setWritable(true, true)) {
-                throw new KrbException("Cache file is not readable.");
-            }
-        } catch (IOException ioe) {
-            // if case of any error we just delete the cache, if user-only
-            // write permissions are not properly set a security exception
-            // is thrown and the file will be deleted.
-            if (cacheFile.delete()) {
-                System.err.println("Cache file is deleted.");
-            }
-        } catch (KrbException e) {
-            LOG.error("Failed to write token to cache File. " + e.toString());
-        }
-    }
-
-    /**
-     * Get the default token cache.
-     *
-     * @return  The default token cache
-     */
-    public static File getDefaultTokenCache() {
-        String homeDir = System.getProperty("user.home", DEFAULT_TOKEN_CACHE_PATH);
-        return new File(homeDir, TOKEN_CACHE_FILE);
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/87a1deea/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenJaasKrbUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenJaasKrbUtil.java b/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenJaasKrbUtil.java
deleted file mode 100644
index 208158d..0000000
--- a/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/jaas/TokenJaasKrbUtil.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- *
- */
-package org.apache.kerby.kerberos.kerb.integration.test.jaas;
-
-import javax.security.auth.Subject;
-import javax.security.auth.kerberos.KerberosPrincipal;
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-import java.io.File;
-import java.security.Principal;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * JAAS utilities for token login.
- */
-public class TokenJaasKrbUtil {
-
-    /**
-     * Login using token cache.
-     *
-     * @param principal The client principal name
-     * @param tokenCache the token cache for login
-     * @param armorCache the armor cache for fast preauth
-     * @param ccache The file to store the tgt ticket
-     * @return the authenticated Subject
-     * @throws LoginException e
-     */
-    public static Subject loginUsingToken(
-            String principal, File tokenCache, File armorCache, File ccache, File signKeyFile)
-            throws LoginException {
-        Subject subject = new Subject(false, new HashSet<Principal>(),
-                new HashSet<Object>(), new HashSet<Object>());
-        Configuration conf = useTokenCache(principal, tokenCache, armorCache, ccache, signKeyFile);
-        String confName = "TokenCacheConf";
-        LoginContext loginContext = new LoginContext(confName, subject, null, conf);
-        loginContext.login();
-        return loginContext.getSubject();
-    }
-
-    /**
-     * Login using token string.
-     *
-     * @param principal The client principal name
-     * @param tokenStr the token string for login
-     * @param armorCache the armor cache for fast preauth
-     * @param ccache The file to store the tgt ticket
-     * @return the authenticated Subject
-     * @throws LoginException e
-     */
-    public static Subject loginUsingToken(
-            String principal, String tokenStr, File armorCache, File ccache, File signKeyFile)
-            throws LoginException {
-        Set<Principal> principals = new HashSet<Principal>();
-        principals.add(new KerberosPrincipal(principal));
-
-        Subject subject = new Subject(false, principals,
-                new HashSet<Object>(), new HashSet<Object>());
-        Configuration conf = useTokenStr(principal, tokenStr, armorCache, ccache, signKeyFile);
-        String confName = "TokenStrConf";
-        LoginContext loginContext = new LoginContext(confName, subject, null, conf);
-        loginContext.login();
-        return loginContext.getSubject();
-    }
-
-    private static Configuration useTokenCache(String principal, File tokenCache,
-                                              File armorCache, File tgtCache, File signKeyFile) {
-        return new TokenJaasConf(principal, tokenCache, armorCache, tgtCache, signKeyFile);
-    }
-
-    private static Configuration useTokenStr(String principal, String tokenStr,
-                                            File armorCache, File tgtCache, File signKeyFile) {
-        return new TokenJaasConf(principal, tokenStr, armorCache, tgtCache, signKeyFile);
-    }
-
-    /**
-     * Token Jaas config.
-     */
-    static class TokenJaasConf extends Configuration {
-        private String principal;
-        private File tokenCache;
-        private String tokenStr;
-        private File armorCache;
-        private File ccache;
-        private File signKeyFile;
-
-        TokenJaasConf(String principal, File tokenCache, File armorCache, File ccache,
-            File signKeyFile) {
-            this.principal = principal;
-            this.tokenCache = tokenCache;
-            this.armorCache = armorCache;
-            this.ccache = ccache;
-            this.signKeyFile = signKeyFile;
-        }
-
-        TokenJaasConf(String principal, String tokenStr, File armorCache, File ccache,
-            File signKeyFile) {
-            this.principal = principal;
-            this.tokenStr = tokenStr;
-            this.armorCache = armorCache;
-            this.ccache = ccache;
-            this.signKeyFile = signKeyFile;
-        }
-
-        @Override
-        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
-            Map<String, String> options = new HashMap<String, String>();
-            options.put(TokenAuthLoginModule.PRINCIPAL, principal);
-            if (tokenCache != null) {
-                options.put(TokenAuthLoginModule.TOKEN_CACHE, tokenCache.getAbsolutePath());
-            } else if (tokenStr != null) {
-                options.put(TokenAuthLoginModule.TOKEN, tokenStr);
-            }
-            options.put(TokenAuthLoginModule.ARMOR_CACHE, armorCache.getAbsolutePath());
-            options.put(TokenAuthLoginModule.CREDENTIAL_CACHE, ccache.getAbsolutePath());
-            options.put(TokenAuthLoginModule.SIGN_KEY_FILE, signKeyFile.getAbsolutePath());
-
-            return new AppConfigurationEntry[]{
-                    new AppConfigurationEntry(
-                            "org.apache.kerby.kerberos.kerb.integration.test.jaas.TokenAuthLoginModule",
-                            AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
-                            options)};
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/87a1deea/kerby-kerb/integration-test/src/test/java/org/apache/kerby/kerberos/kerb/integration/test/TokenLoginTestBase.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/integration-test/src/test/java/org/apache/kerby/kerberos/kerb/integration/test/TokenLoginTestBase.java b/kerby-kerb/integration-test/src/test/java/org/apache/kerby/kerberos/kerb/integration/test/TokenLoginTestBase.java
index 2ceaa23..0599bf4 100644
--- a/kerby-kerb/integration-test/src/test/java/org/apache/kerby/kerberos/kerb/integration/test/TokenLoginTestBase.java
+++ b/kerby-kerb/integration-test/src/test/java/org/apache/kerby/kerberos/kerb/integration/test/TokenLoginTestBase.java
@@ -21,8 +21,8 @@ package org.apache.kerby.kerberos.kerb.integration.test;
 
 import org.apache.kerby.kerberos.kerb.KrbRuntime;
 import org.apache.kerby.kerberos.kerb.common.KrbUtil;
-import org.apache.kerby.kerberos.kerb.integration.test.jaas.TokenCache;
-import org.apache.kerby.kerberos.kerb.integration.test.jaas.TokenJaasKrbUtil;
+import org.apache.kerby.kerberos.kerb.client.jaas.TokenCache;
+import org.apache.kerby.kerberos.kerb.client.jaas.TokenJaasKrbUtil;
 import org.apache.kerby.kerberos.kerb.provider.TokenEncoder;
 import org.apache.kerby.kerberos.kerb.server.KdcConfigKey;
 import org.apache.kerby.kerberos.kerb.server.LoginTestBase;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/87a1deea/kerby-kerb/kerb-client/pom.xml
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/pom.xml b/kerby-kerb/kerb-client/pom.xml
index 5fe6576..023bd6d 100644
--- a/kerby-kerb/kerb-client/pom.xml
+++ b/kerby-kerb/kerb-client/pom.xml
@@ -52,5 +52,10 @@
       <version>${slf4j.version}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.kerby</groupId>
+      <artifactId>token-provider</artifactId>
+      <version>1.0.1-SNAPSHOT</version>
+    </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/87a1deea/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenAuthLoginModule.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenAuthLoginModule.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenAuthLoginModule.java
new file mode 100644
index 0000000..4d81e3d
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenAuthLoginModule.java
@@ -0,0 +1,372 @@
+/**
+ *  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.kerby.kerberos.kerb.client.jaas;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.KrbRuntime;
+import org.apache.kerby.kerberos.kerb.client.KrbClient;
+import org.apache.kerby.kerberos.kerb.client.KrbConfig;
+import org.apache.kerby.kerberos.kerb.client.KrbTokenClient;
+import org.apache.kerby.kerberos.kerb.common.PrivateKeyReader;
+import org.apache.kerby.kerberos.kerb.provider.TokenDecoder;
+import org.apache.kerby.kerberos.kerb.provider.TokenEncoder;
+import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
+import org.apache.kerby.kerberos.kerb.type.base.KrbToken;
+import org.apache.kerby.kerberos.kerb.type.base.TokenFormat;
+import org.apache.kerby.kerberos.kerb.type.kdc.EncKdcRepPart;
+import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
+import org.apache.kerby.kerberos.provider.token.JwtAuthToken;
+import org.apache.kerby.kerberos.provider.token.JwtTokenEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.JWTParser;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KerberosTicket;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This <code>LoginModule</code> authenticates users using token.
+ * tokenStr: token-string
+ * tokenCache: token-cache-file
+ * armorCache: armor-cache-file
+ */
+public class TokenAuthLoginModule implements LoginModule {
+    public static final String PRINCIPAL = "principal";
+    public static final String TOKEN = "token";
+    public static final String TOKEN_CACHE = "tokenCache";
+    public static final String ARMOR_CACHE = "armorCache";
+    public static final String CREDENTIAL_CACHE = "credentialCache";
+    public static final String SIGN_KEY_FILE = "signKeyFile";
+
+    private static final Logger LOG = LoggerFactory.getLogger(TokenAuthLoginModule.class);
+
+    /** initial state*/
+    private Subject subject;
+
+    /** configurable option*/
+    private String tokenCacheName = null;
+
+    /** the authentication status*/
+    private boolean succeeded = false;
+    private boolean commitSucceeded = false;
+
+    private String princName = null;
+    private String tokenStr = null;
+    private AuthToken authToken = null;
+    private KrbToken krbToken = null;
+    private File armorCache;
+    private File cCache;
+    private File signKeyFile;
+
+    private TgtTicket tgtTicket;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void initialize(Subject subject, CallbackHandler callbackHandler,
+                           Map<String, ?> sharedState, Map<String, ?> options) {
+
+        this.subject = subject;
+        /** initialize any configured options*/
+        princName = (String) options.get(PRINCIPAL);
+        tokenStr = (String) options.get(TOKEN);
+        tokenCacheName = (String) options.get(TOKEN_CACHE);
+        if ((String) options.get(ARMOR_CACHE) != null) {
+            armorCache = new File((String) options.get(ARMOR_CACHE));
+        }
+        if ((String) options.get(CREDENTIAL_CACHE) != null) {
+            cCache = new File((String) options.get(CREDENTIAL_CACHE));
+        }
+        if ((String) options.get(SIGN_KEY_FILE) != null) {
+            signKeyFile = new File((String) options.get(SIGN_KEY_FILE));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean login() throws LoginException {
+        validateConfiguration();
+
+        succeeded = tokenLogin();
+        return succeeded;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean commit() throws LoginException {
+
+        if (!succeeded) {
+            return false;
+        } else {
+            KerberosTicket ticket = null;
+            try {
+                EncKdcRepPart encKdcRepPart = tgtTicket.getEncKdcRepPart();
+                boolean[] flags = new boolean[7];
+                int flag = encKdcRepPart.getFlags().getFlags();
+                for (int i = 6; i >= 0; i--) {
+                    flags[i] = (flag & (1 << i)) != 0;
+                }
+                Date startTime = null;
+                if (encKdcRepPart.getStartTime() != null) {
+                    startTime = encKdcRepPart.getStartTime().getValue();
+                }
+
+                ticket = new KerberosTicket(tgtTicket.getTicket().encode(),
+                    new KerberosPrincipal(tgtTicket.getClientPrincipal().getName()),
+                    new KerberosPrincipal(tgtTicket.getEncKdcRepPart().getSname().getName()),
+                    encKdcRepPart.getKey().getKeyData(),
+                    encKdcRepPart.getKey().getKeyType().getValue(),
+                    flags,
+                    encKdcRepPart.getAuthTime().getValue(),
+                    startTime,
+                    encKdcRepPart.getEndTime().getValue(),
+                    encKdcRepPart.getRenewTill().getValue(),
+                    null
+                );
+            } catch (IOException e) {
+                LOG.error("Commit Failed. " + e.toString());
+            }
+            subject.getPrivateCredentials().add(ticket);
+            if (princName != null) {
+                subject.getPrincipals().add(new KerberosPrincipal(princName));
+            }
+        }
+        commitSucceeded = true;
+        LOG.info("Commit Succeeded \n");
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean abort() throws LoginException {
+        if (succeeded == false) {
+            return false;
+        } else if (succeeded == true && commitSucceeded == false) {
+            // login succeeded but overall authentication failed
+            succeeded = false;
+        } else {
+            // overall authentication succeeded and commit succeeded,
+            // but someone else's commit failed
+            logout();
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean logout() throws LoginException {
+        LOG.info("\t\t[TokenAuthLoginModule]: Entering logout");
+
+        if (subject.isReadOnly()) {
+            throw new LoginException("Subject is Readonly");
+        }
+
+        for (Principal principal: subject.getPrincipals()) {
+            if (principal.getName().equals(princName)) {
+                subject.getPrincipals().remove(principal);
+            }
+        }
+        // Let us remove all Kerberos credentials stored in the Subject
+        Iterator<Object> it = subject.getPrivateCredentials().iterator();
+        while (it.hasNext()) {
+            Object o = it.next();
+            if (o instanceof KrbToken) {
+                it.remove();
+            }
+        }
+
+        cleanup();
+
+        succeeded = false;
+        commitSucceeded = false;
+
+        LOG.info("\t\t[TokenAuthLoginModule]: logged out Subject");
+        return true;
+    }
+
+    private void validateConfiguration() throws LoginException {
+
+        if (armorCache == null) {
+            throw new LoginException("An armor cache must be specified via the armorCache configuration option");
+        }
+
+        if (cCache == null) {
+            throw new LoginException("A credential cache must be specified via the credentialCache"
+            + " configuration option");
+        }
+
+        String error = "";
+        if (tokenStr == null && tokenCacheName == null) {
+            error = "useToken is specified but no token or token cache is provided";
+        } else if (tokenStr != null && tokenCacheName != null) {
+            error = "either token or token cache should be provided but not both";
+        }
+
+        if (!error.isEmpty()) {
+            throw new LoginException(error);
+        }
+    }
+
+    private boolean tokenLogin() throws LoginException {
+        if (tokenStr == null) {
+            tokenStr = TokenCache.readToken(tokenCacheName);
+            if (tokenStr == null) {
+                throw new LoginException("No valid token was found in token cache: " + tokenCacheName);
+            }
+        }
+
+        krbToken = new KrbToken();
+
+        // Sign the token.
+        if (signKeyFile != null) {
+            try {
+                TokenDecoder tokenDecoder = KrbRuntime.getTokenProvider().createTokenDecoder();
+                try {
+                    authToken = tokenDecoder.decodeFromString(tokenStr);
+                } catch (IOException e) {
+                    LOG.error("Token decode failed. " + e.toString());
+                }
+                krbToken = new KrbToken(authToken, TokenFormat.JWT);
+                TokenEncoder tokenEncoder = KrbRuntime.getTokenProvider().createTokenEncoder();
+
+                if (tokenEncoder instanceof JwtTokenEncoder) {
+                    PrivateKey signKey = null;
+                    try {
+                        InputStream is = Files.newInputStream(signKeyFile.toPath());
+                        signKey = PrivateKeyReader.loadPrivateKey(is);
+                    } catch (IOException e) {
+                        LOG.error("Failed to load private key from file: "
+                                + signKeyFile.getName());
+                    } catch (Exception e) {
+                        LOG.error(e.toString());
+                    }
+
+                    ((JwtTokenEncoder) tokenEncoder).setSignKey((RSAPrivateKey) signKey);
+                }
+
+                krbToken.setTokenValue(tokenEncoder.encodeAsBytes(authToken));
+            } catch (KrbException e) {
+                throw new RuntimeException("Failed to encode AuthToken", e);
+            }
+        } else {
+            // Otherwise just write out the token (which could be already signed)
+            krbToken.setTokenValue(tokenStr.getBytes());
+
+            try {
+                JWT jwt = JWTParser.parse(tokenStr);
+                authToken = new JwtAuthToken(jwt.getJWTClaimsSet());
+            } catch (ParseException e) {
+                // Invalid JWT encoding
+                throw new RuntimeException("Failed to parse JWT token string", e);
+            }
+        }
+
+        krbToken.setInnerToken(authToken);
+        krbToken.setTokenType();
+        krbToken.setTokenFormat(TokenFormat.JWT);
+
+        KrbClient krbClient = null;
+        try {
+            File confFile = new File(System.getProperty("java.security.krb5.conf"));
+            KrbConfig krbConfig = new KrbConfig();
+            krbConfig.addKrb5Config(confFile);
+            krbClient = new KrbClient(krbConfig);
+            krbClient.init();
+        } catch (KrbException | IOException e) {
+            LOG.error("KrbClient init failed. " + e.toString());
+        }
+
+        KrbTokenClient tokenClient = new KrbTokenClient(krbClient);
+        try {
+            tgtTicket = tokenClient.requestTgt(krbToken,
+                armorCache.getAbsolutePath());
+        } catch (KrbException e) {
+            throwWith("Failed to do login with token: " + tokenStr, e);
+            return false;
+        }
+
+        try {
+            cCache = makeTgtCache();
+        } catch (IOException e) {
+            LOG.error("Failed to make tgtCache. " + e.toString());
+        }
+        try {
+            if (krbClient != null) {
+                krbClient.storeTicket(tgtTicket, cCache);
+            }
+        } catch (KrbException e) {
+            LOG.error("Failed to store tgtTicket to " + cCache.getName());
+        }
+        return true;
+    }
+
+    private File makeTgtCache() throws IOException {
+
+        if (!cCache.exists() && !cCache.createNewFile()) {
+            throw new IOException("Failed to create tgtcache file "
+                    + cCache.getAbsolutePath());
+        }
+        cCache.setExecutable(false);
+        cCache.setReadable(true);
+        cCache.setWritable(true);
+        return cCache;
+    }
+
+    private void cleanup() {
+        if (cCache != null && cCache.exists()) {
+            boolean delete = cCache.delete();
+            if (!delete) {
+                throw new RuntimeException("File delete error!");
+            }
+        }
+    }
+
+    private void throwWith(String error, Exception cause) throws LoginException {
+        LoginException le = new LoginException(error);
+        le.initCause(cause);
+        throw le;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/87a1deea/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenCache.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenCache.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenCache.java
new file mode 100644
index 0000000..91caed7
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenCache.java
@@ -0,0 +1,119 @@
+/**
+ *  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.kerby.kerberos.kerb.client.jaas;
+
+
+import org.apache.commons.io.output.FileWriterWithEncoding;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.List;
+
+/**
+ * This class provides APIs for converting token cache file with token string.
+ */
+public class TokenCache {
+    private static final Logger LOG = LoggerFactory
+            .getLogger(TokenCache.class);
+
+    private static final String DEFAULT_TOKEN_CACHE_PATH = ".tokenauth";
+    private static final String TOKEN_CACHE_FILE = ".tokenauth.token";
+
+    /**
+     * Obtain token string from token cache file.
+     *
+     * @param tokenCacheFile The file stored token
+     * @return Token string
+     */
+    public static String readToken(String tokenCacheFile) {
+        File cacheFile;
+
+        if (tokenCacheFile != null && !tokenCacheFile.isEmpty()) {
+            cacheFile = new File(tokenCacheFile);
+            if (!cacheFile.exists()) {
+                throw new RuntimeException("Invalid token cache specified: " + tokenCacheFile);
+            }
+        } else {
+            cacheFile = getDefaultTokenCache();
+            if (!cacheFile.exists()) {
+                throw new RuntimeException("No token cache available by default");
+            }
+        }
+
+        String token = null;
+        try {
+            List<String> lines = Files.readAllLines(cacheFile.toPath(), StandardCharsets.UTF_8);
+            if (lines != null && !lines.isEmpty()) {
+                token = lines.get(0);
+            }
+        } catch (IOException ex) {
+            LOG.error("Failed to read file: " + cacheFile.getName());
+        }
+
+        return token;
+    }
+
+    /**
+     * Write the token string to token cache file.
+     *
+     * @param token The token string
+     */
+    public static void writeToken(String token, String tokenCacheFile) {
+        File cacheFile = new File(tokenCacheFile);
+
+        try {
+            Writer writer = new FileWriterWithEncoding(cacheFile, StandardCharsets.UTF_8);
+            writer.write(token);
+            writer.flush();
+            writer.close();
+            // sets read-write permissions to owner only
+            cacheFile.setReadable(false, false);
+            cacheFile.setReadable(true, true);
+            if (!cacheFile.setWritable(true, true)) {
+                throw new KrbException("Cache file is not readable.");
+            }
+        } catch (IOException ioe) {
+            // if case of any error we just delete the cache, if user-only
+            // write permissions are not properly set a security exception
+            // is thrown and the file will be deleted.
+            if (cacheFile.delete()) {
+                System.err.println("Cache file is deleted.");
+            }
+        } catch (KrbException e) {
+            LOG.error("Failed to write token to cache File. " + e.toString());
+        }
+    }
+
+    /**
+     * Get the default token cache.
+     *
+     * @return  The default token cache
+     */
+    public static File getDefaultTokenCache() {
+        String homeDir = System.getProperty("user.home", DEFAULT_TOKEN_CACHE_PATH);
+        return new File(homeDir, TOKEN_CACHE_FILE);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/87a1deea/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenJaasKrbUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenJaasKrbUtil.java b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenJaasKrbUtil.java
new file mode 100644
index 0000000..e9c91f1
--- /dev/null
+++ b/kerby-kerb/kerb-client/src/main/java/org/apache/kerby/kerberos/kerb/client/jaas/TokenJaasKrbUtil.java
@@ -0,0 +1,146 @@
+/**
+ *  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.kerby.kerberos.kerb.client.jaas;
+
+import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import java.io.File;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * JAAS utilities for token login.
+ */
+public class TokenJaasKrbUtil {
+
+    /**
+     * Login using token cache.
+     *
+     * @param principal The client principal name
+     * @param tokenCache the token cache for login
+     * @param armorCache the armor cache for fast preauth
+     * @param ccache The file to store the tgt ticket
+     * @return the authenticated Subject
+     * @throws LoginException e
+     */
+    public static Subject loginUsingToken(
+            String principal, File tokenCache, File armorCache, File ccache, File signKeyFile)
+            throws LoginException {
+        Subject subject = new Subject(false, new HashSet<Principal>(),
+                new HashSet<Object>(), new HashSet<Object>());
+        Configuration conf = useTokenCache(principal, tokenCache, armorCache, ccache, signKeyFile);
+        String confName = "TokenCacheConf";
+        LoginContext loginContext = new LoginContext(confName, subject, null, conf);
+        loginContext.login();
+        return loginContext.getSubject();
+    }
+
+    /**
+     * Login using token string.
+     *
+     * @param principal The client principal name
+     * @param tokenStr the token string for login
+     * @param armorCache the armor cache for fast preauth
+     * @param ccache The file to store the tgt ticket
+     * @return the authenticated Subject
+     * @throws LoginException e
+     */
+    public static Subject loginUsingToken(
+            String principal, String tokenStr, File armorCache, File ccache, File signKeyFile)
+            throws LoginException {
+        Set<Principal> principals = new HashSet<Principal>();
+        principals.add(new KerberosPrincipal(principal));
+
+        Subject subject = new Subject(false, principals,
+                new HashSet<Object>(), new HashSet<Object>());
+        Configuration conf = useTokenStr(principal, tokenStr, armorCache, ccache, signKeyFile);
+        String confName = "TokenStrConf";
+        LoginContext loginContext = new LoginContext(confName, subject, null, conf);
+        loginContext.login();
+        return loginContext.getSubject();
+    }
+
+    private static Configuration useTokenCache(String principal, File tokenCache,
+                                              File armorCache, File tgtCache, File signKeyFile) {
+        return new TokenJaasConf(principal, tokenCache, armorCache, tgtCache, signKeyFile);
+    }
+
+    private static Configuration useTokenStr(String principal, String tokenStr,
+                                            File armorCache, File tgtCache, File signKeyFile) {
+        return new TokenJaasConf(principal, tokenStr, armorCache, tgtCache, signKeyFile);
+    }
+
+    /**
+     * Token Jaas config.
+     */
+    static class TokenJaasConf extends Configuration {
+        private String principal;
+        private File tokenCache;
+        private String tokenStr;
+        private File armorCache;
+        private File ccache;
+        private File signKeyFile;
+
+        TokenJaasConf(String principal, File tokenCache, File armorCache, File ccache,
+            File signKeyFile) {
+            this.principal = principal;
+            this.tokenCache = tokenCache;
+            this.armorCache = armorCache;
+            this.ccache = ccache;
+            this.signKeyFile = signKeyFile;
+        }
+
+        TokenJaasConf(String principal, String tokenStr, File armorCache, File ccache,
+            File signKeyFile) {
+            this.principal = principal;
+            this.tokenStr = tokenStr;
+            this.armorCache = armorCache;
+            this.ccache = ccache;
+            this.signKeyFile = signKeyFile;
+        }
+
+        @Override
+        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+            Map<String, String> options = new HashMap<String, String>();
+            options.put(TokenAuthLoginModule.PRINCIPAL, principal);
+            if (tokenCache != null) {
+                options.put(TokenAuthLoginModule.TOKEN_CACHE, tokenCache.getAbsolutePath());
+            } else if (tokenStr != null) {
+                options.put(TokenAuthLoginModule.TOKEN, tokenStr);
+            }
+            options.put(TokenAuthLoginModule.ARMOR_CACHE, armorCache.getAbsolutePath());
+            options.put(TokenAuthLoginModule.CREDENTIAL_CACHE, ccache.getAbsolutePath());
+            options.put(TokenAuthLoginModule.SIGN_KEY_FILE, signKeyFile.getAbsolutePath());
+
+            return new AppConfigurationEntry[]{
+                    new AppConfigurationEntry(
+                            "org.apache.kerby.kerberos.kerb.client.jaas.TokenAuthLoginModule",
+                            AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                            options)};
+        }
+    }
+}


Mime
View raw message