Java 如何使用 Spnego/Kerberos 和 Apache 的 HttpClient 进行身份验证?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24633380/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 13:34:59  来源:igfitidea点击:

How do I authenticate with Spnego/Kerberos and Apache's HttpClient?

javakerberosapache-httpclient-4.xspnego

提问by chris

How do I correctly setup a connection with HttpClientthat uses the logged in user's ActiveDirectorycredentials to authenticate against a website and requires Kerberos/Spnego authentication?

如何正确设置HttpClient使用登录用户ActiveDirectory凭据对网站进行身份验证并需要的连接Kerberos/Spnego authentication

采纳答案by chris

Here's an example:

下面是一个例子:

public class HttpSpnegoConnection {

    /**
     * Uses HttpClient 4.3.4 and CommonsIO 2.4
     */
    public static void main(String[] args) throws ClientProtocolException, IOException {


        String domain = "yourdomain.com";
        String kdc =  "thekdc.yourdomain.ch";
        // careful with aliases, 'somewebsite' has to be in the kerberos database
        String url = "http://somewebsite:8080/myresource/";
        // if the port does not match the kerberos database entry, skip it during the lookup
        boolean skipPortAtKerberosDatabaseLookup = true;

        File krb5Config = createKrb5Configuration(domain,kdc);

        System.out.println("Created config '"+krb5Config.getAbsolutePath()+"':");
        System.out.println(IOUtils.toString(new FileReader(krb5Config)));

        System.setProperty("java.security.krb5.conf", krb5Config.toURI().toString());
        System.setProperty("sun.security.krb5.debug", "true");
        System.setProperty("javax.security.auth.useSubjectCredsOnly","false");


        Lookup<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
            .register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(skipPortAtKerberosDatabaseLookup))
            .build();

        CloseableHttpClient client = HttpClients.custom().setDefaultAuthSchemeRegistry(authSchemeRegistry).build();
        HttpClientContext context = HttpClientContext.create();
        BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();

        // This may seem odd, but specifying 'null' as principal tells java to use the logged in user's credentials
        Credentials useJaasCreds = new Credentials() {

            public String getPassword() {
                return null;
            }

            public Principal getUserPrincipal() {
                return null;
            }

        };
        credentialsProvider.setCredentials( new AuthScope(null, -1, null), useJaasCreds );
        context.setCredentialsProvider(credentialsProvider);

        HttpGet httpget = new HttpGet(url);
        CloseableHttpResponse response = client.execute(httpget,context);
        String responseString = IOUtils.toString(response.getEntity().getContent());

        System.out.println("HTTP Response:");
        System.out.println(responseString);
    }

    /** 
        Creates a temporary krb5.conf
        [libdefaults]
            default_realm = <domain>

        [realms]
            snb.ch = {
                kdc = <kdc>
                admin_server = <kdc>
            }
     */
    private static File createKrb5Configuration(String domain, String kdc) throws IOException {
        File tempFile = File.createTempFile("krb5", "kdc");
        ArrayList<String> lines = new ArrayList<>();
        lines.add("[libdefaults]");
        lines.add("\tdefault_realm = "+domain);
        lines.add("[realms]");
        lines.add("\t"+domain+" = {");
        lines.add("\t\tkdc = "+kdc);
        lines.add("\t\tadmin_server = "+kdc);
        lines.add("\t}");
        FileWriter writer = new FileWriter(tempFile);
        IOUtils.writeLines(lines, System.lineSeparator(), writer);
        IOUtils.closeQuietly(writer);
        return tempFile;
    }

}

Depending on your AD configuration, creating and specifying the krb5.confmay be skipped.

根据您的 AD 配置,可能会跳过创建和指定krb5.conf