/* * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.io.InputStream; import java.net.Authenticator; import java.net.InetSocketAddress; import java.net.PasswordAuthentication; import java.net.URL; import java.net.URLConnection; import java.util.List; import sun.net.www.protocol.http.ntlm.NTLMAuthenticationCallback; /* * @test * @bug 8137174 * @modules java.base/sun.net.www.protocol.http.ntlm * jdk.httpserver * @summary Checks if NTLM auth works fine if security manager set * @run main/othervm/java.security.policy=NTLMAuthWithSM.policy NTLMAuthWithSM */ public class NTLMAuthWithSM { public static void main(String[] args) throws Exception { // security manager is required if (System.getSecurityManager() == null) { throw new RuntimeException("Security manager not specified"); } if (System.getProperty("os.name").startsWith("Windows")) { // disable transparent NTLM authentication on Windows NTLMAuthenticationCallback.setNTLMAuthenticationCallback( new NTLMAuthenticationCallbackImpl()); } try (LocalHttpServer server = LocalHttpServer.startServer()) { // set authenticator Authenticator.setDefault(new AuthenticatorImpl()); String url = String.format("http://localhost:%d/test/", server.getPort()); // load a document which is protected with NTML authentication System.out.println("load() called: " + url); URLConnection conn = new URL(url).openConnection(); try (BufferedReader reader = new BufferedReader( new InputStreamReader(conn.getInputStream()))) { String line = reader.readLine(); if (line == null) { throw new IOException("Couldn't read a response"); } do { System.out.println(line); } while ((line = reader.readLine()) != null); } } System.out.println("Test passed"); } private static class AuthenticatorImpl extends Authenticator { @Override public PasswordAuthentication getPasswordAuthentication() { System.out.println("getPasswordAuthentication() called, scheme: " + getRequestingScheme()); if (getRequestingScheme().equalsIgnoreCase("ntlm")) { return new PasswordAuthentication("test", "test".toCharArray()); } return null; } } // local http server which pretends to support NTLM auth static class LocalHttpServer implements HttpHandler, AutoCloseable { private final HttpServer server; private LocalHttpServer(HttpServer server) { this.server = server; } static LocalHttpServer startServer() throws IOException { HttpServer httpServer = HttpServer.create( new InetSocketAddress(0), 0); LocalHttpServer localHttpServer = new LocalHttpServer(httpServer); localHttpServer.start(); return localHttpServer; } void start() { server.createContext("/test", this); server.start(); System.out.println("HttpServer: started on port " + getPort()); } void stop() { server.stop(0); System.out.println("HttpServer: stopped"); } int getPort() { return server.getAddress().getPort(); } @Override public void handle(HttpExchange t) throws IOException { System.out.println("HttpServer: handle connection"); // read a request try (InputStream is = t.getRequestBody()) { while (is.read() > 0); } try { List<String> headers = t.getRequestHeaders() .get("Authorization"); if (headers != null && !headers.isEmpty() && headers.get(0).trim().contains("NTLM")) { byte[] output = "hello".getBytes(); t.sendResponseHeaders(200, output.length); t.getResponseBody().write(output); System.out.println("HttpServer: return 200"); } else { t.getResponseHeaders().set("WWW-Authenticate", "NTLM"); byte[] output = "forbidden".getBytes(); t.sendResponseHeaders(401, output.length); t.getResponseBody().write(output); System.out.println("HttpServer: return 401"); } } catch (IOException e) { System.out.println("HttpServer: exception: " + e); System.out.println("HttpServer: return 500"); t.sendResponseHeaders(500, 0); } finally { t.close(); } } @Override public void close() { stop(); } } private static class NTLMAuthenticationCallbackImpl extends NTLMAuthenticationCallback { // don't trust any site, so that no transparent NTLM auth happens @Override public boolean isTrustedSite(URL url) { System.out.println( "NTLMAuthenticationCallbackImpl.isTrustedSite() called: " + "return false"); return false; } } }