首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JSch异常:未注册名为com.sun.security.jgss.krb5.initiate的配置

JSch异常:未注册名为com.sun.security.jgss.krb5.initiate的配置
EN

Stack Overflow用户
提问于 2017-10-18 02:57:07
回答 2查看 4.5K关注 0票数 2

我正在运行这段代码,但得到一个异常。

代码语言:javascript
复制
Session session = null;  
Channel channel = null;  

JSch jsch = new JSch();  
session = jsch.getSession(ftpUserName, ftpHost, ftpPort);  
if (session == null) {  
    throw new Exception("session is null");  
}  
session.setPassword(ftpPassword);  
session.setTimeout(100000);  
session.setConfig("StrictHostKeyChecking", "no");  
session.connect();  

此代码在本地开发环境中正常工作。然而,当部署在测试环境中时,报告出现异常。测试环境为linux环境,部署中间件为weblogic11,使用jdk为oracle1.6.45。

代码语言:javascript
复制
Exception:
java.lang.IllegalArgumentException: No Configuration was registered that can handle the configuration named com.sun.security.jgss.krb5.initiate
at com.bea.common.security.jdkutils.JAASConfiguration.getAppConfigurationEntry(JAASConfiguration.java:130)
at sun.security.jgss.LoginConfigImpl.getAppConfigurationEntry(LoginConfigImpl.java:139)
at javax.security.auth.login.LoginContext.init(LoginContext.java:243)
at javax.security.auth.login.LoginContext.<init>(LoginContext.java:499)
at sun.security.jgss.GSSUtil.login(GSSUtil.java:244)
at sun.security.jgss.krb5.Krb5Util.getTicket(Krb5Util.java:136)
at sun.security.jgss.krb5.Krb5InitCredential$1.run(Krb5InitCredential.java:328)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.jgss.krb5.Krb5InitCredential.getTgt(Krb5InitCredential.java:325)
at sun.security.jgss.krb5.Krb5InitCredential.getInstance(Krb5InitCredential.java:128)
at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:106)
at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:172)
at sun.security.jgss.GSSManagerImpl.getMechanismContext(GSSManagerImpl.java:209)
at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:195)
at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:162)
at com.jcraft.jsch.jgss.GSSContextKrb5.init(GSSContextKrb5.java:129)
at com.jcraft.jsch.UserAuthGSSAPIWithMIC.start(UserAuthGSSAPIWithMIC.java:135)
at com.jcraft.jsch.Session.connect(Session.java:470)
at com.jcraft.jsch.Session.connect(Session.java:183)
at com.sinosoft.FXQ.util.SftpUtils.downloadSftpFile(SftpUtils.java:57)
at com.sinosoft.FXQ.blackList.action.BLBlackListAction.extractBlackList(BLBlackListAction.java:47)
at com.sinosoft.FXQ.task.DownBlackListDataTask.run(DownBlackListDataTask.java:93)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-18 06:27:07

正如@Chris已经回答的那样,JSch默认尝试Kerberos/GSSAPI身份验证。

由于您似乎不希望这样,请将Kerberos/GSSAPI (gssapi-with-mic)从身份验证方法(gssapi-with-mic,publickey,keyboard-interactive,password)的默认JSch列表中删除:

代码语言:javascript
复制
session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
票数 1
EN

Stack Overflow用户

发布于 2017-10-18 04:05:39

解释

您收到的错误消息属于Kerberos,这是一种网络身份验证协议。我看到,在会话配置中,您没有显式地指定身份验证协议。正因为如此,我相信,无论出于什么原因,JSch都默认为Kerberos,即使您提供的是用户名和密码。

修正

我认为解决这一问题的最简单方法是修改setConfig方法,使其包含多种身份验证协议。所有这些都已启用,并且指定了用户名和密码,您可能会在大多数环境中进行身份验证。

代码语言:javascript
复制
   Hashtable<String, String> properties = new Hashtable<String, String>();
   properties.put("PreferredAuthentications", "gssapi-with-mic,publickey,keyboard-interactive,password");
   properties.put("StrictHostKeyChecking", "no");

   session.setConfig(properties);

还不起作用?

如果上述修改不起作用,请尝试以下操作。

创建一个名为SessionUserInfo.java的新类

代码语言:javascript
复制
public class SessionUserInfo implements UserInfo, UIKeyboardInteractive {

    private String password;
    private String passPhrase;
    public SessionUserInfo() {
        password = "";
        passPhrase = "";
    }

    public SessionUserInfo (String password, String passPhrase) {
        this.password = password;
        this.passPhrase = passPhrase;
    }

    public String getPassphrase() {
        return passPhrase;
    }

    public String getPassword() {
        return password;
    }

    public boolean promptPassphrase(String phrase) {
        return true;
    }

    public boolean promptPassword(String password) {
        return false;
    }

    public boolean promptYesNo(String bool) {
        return true;
    }

    public void showMessage(String message) {
        // Do Nothing
    }
}

然后按以下方式修改代码。

代码语言:javascript
复制
 public static void downloadSftpFile(String ftpHost, String ftpUserName,  
        String ftpPassword, int ftpPort, String ftpPath, String localPath,  
        String fileName) throws Exception { 
    Session session = null;  
    Channel channel = null;  

    JSch jsch = new JSch();  
    session = jsch.getSession(ftpUserName, ftpHost, ftpPort);  
    if (session == null) {  
        throw new Exception("session is null");  
    }  
    session.setPassword(ftpPassword);  
    session.setTimeout(100000);  

   Hashtable<String, String> properties = new Hashtable<String, String>();
   properties.put("PreferredAuthentications", "gssapi-with-mic,publickey,keyboard-interactive,password");
   properties.put("StrictHostKeyChecking", "no");

   session.setConfig(properties);
   session.setUserInfo(new SessionUserInfo(ftpPassword, null));
    session.connect();  

    channel = session.openChannel("sftp");  
    channel.connect();  
    ChannelSftp chSftp = (ChannelSftp) channel;  

    String ftpFilePath = ftpPath + "/" + fileName;  
    String localFilePath = localPath + File.separatorChar + fileName;  

    try {  
        chSftp.get(ftpFilePath, localPath);  
    } catch (Exception e) {  
        e.printStackTrace(); 
        logger.info("download error.");  
        throw e;
    } finally {  
        chSftp.quit();  
        channel.disconnect();  
        session.disconnect();  
    }  
 }  

没有经过JSch代码(在GitHub BTW上可用),我相信在连接之前向会话添加用户信息POJO与将密码添加到会话本身有不同的效果。

伐木--一个事后的思考

我上面的海报用我贴出的代码解决了问题,解决了原来的海报问题。我在JSch库中查看了会话代码,并发现为JSch启用日志将对您在这里大有帮助。下面是一个启用日志记录的示例。

MyLogger类

Jsch示例中的代码

代码语言:javascript
复制
  public static class MyLogger implements com.jcraft.jsch.Logger {
    static java.util.Hashtable name=new java.util.Hashtable();
    static{
      name.put(new Integer(DEBUG), "DEBUG: ");
      name.put(new Integer(INFO), "INFO: ");
      name.put(new Integer(WARN), "WARN: ");
      name.put(new Integer(ERROR), "ERROR: ");
      name.put(new Integer(FATAL), "FATAL: ");
    }
    public boolean isEnabled(int level){
      return true;
    }
    public void log(int level, String message){
      System.err.print(name.get(new Integer(level)));
      System.err.println(message);
    }
  }

为了启用它,只需修改您的代码

代码语言:javascript
复制
Session session = null;  
Channel channel = null;  
JSch.setLogger(new MyLogger());

JSch jsch = new JSch();  
session = jsch.getSession(ftpUserName, ftpHost, ftpPort);  
if (session == null) {  
    throw new Exception("session is null");  
}  
session.setPassword(ftpPassword);  
session.setTimeout(100000);  
session.setConfig("StrictHostKeyChecking", "no");  
session.connect();  
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46802110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档