115115import com .marklogic .client .query .StructuredQueryDefinition ;
116116import com .marklogic .client .util .RequestLogger ;
117117
118+ /*
119+ * For this test we need to have a services.keytab file that contains both service (host name) and user principal names.
120+ * Generate a services.keytab file.
121+ * Then use addent (refer to Jenkins job script) command to add "builder" user to the same services.keytab file.
122+ * Make sure that user ("builder") is in Active Directory with proper local name and password.
123+ * Jenkins script destorys cached TGT before running this test.
124+ * Copy the services.keytab file to ML Server data directory.
125+ */
126+
118127public class TestDatabaseClientKerberosFromFile extends BasicJavaClientREST {
119128
120129 private static String dbName = "TestDBClientWithKerberosFileDB" ;
@@ -132,7 +141,8 @@ public class TestDatabaseClientKerberosFromFile extends BasicJavaClientREST {
132141 private static String appServerName = "REST-Java-Client-API-ServerKerberos" ;
133142 // External security name to be set for the App Server.
134143 private static String extSecurityName = "KerberosExtSec" ;
135- private static String kdcPrincipalUser = "builder@MLTEST1.LOCAL" ;
144+ private static String kdcPrincipalUser = "builder" ;
145+ private static final String RealmName = "@MLTEST1.LOCAL" ;
136146 private static String keytabFile ;
137147 private static String principal ;
138148
@@ -144,7 +154,7 @@ public static void setUpBeforeClass() throws Exception {
144154 loadGradleProperties ();
145155 appServerHostName = getRestAppServerHostName ();
146156
147- // Modify default location if needed for services.keytab file.
157+ // Modify default location if needed for services.keytab file. Jenkins job passes in the services.keytab file.
148158 keytabFile = System .getProperty ("keytabFile" );
149159 principal = System .getProperty ("principal" , kdcPrincipalUser );
150160
@@ -164,12 +174,11 @@ public static void setUpBeforeClass() throws Exception {
164174 // Create the External Security setting.
165175 createExternalSecurityForKerberos (appServerName , extSecurityName );
166176 associateRESTServerWithKerberosExtSecurity (appServerName , extSecurityName );
167- // Set authentication to kerberos-ticket, internal security to true and external securities to be none on App Server.
168- //setAuthToKerberosAndInternalSecurityToTrue(appServerName) ;
177+
178+ String extName = principal + RealmName ;
169179 createUserRolesWithPrevilages ("test-evalKer" , "xdbc:eval" , "xdbc:eval-in" , "xdmp:eval-in" , "any-uri" , "xdbc:invoke" );
170- createRESTKerberosUser ("builder" , "Welcome123" , kdcPrincipalUser , "rest-reader" , "rest-writer" , "rest-admin" , "rest-extension-user" , "test-evalKer" );
171180
172- //createRESTUser ("builder", "Welcome123", "test-evalKer ", "rest-admin ", "rest-writer ", "rest-reader ");
181+ createRESTKerberosUser ("builder" , "Welcome123" , extName , "rest-reader " , "rest-writer " , "rest-admin " , "rest-extension-user" , "test-evalKer " );
173182 createRESTUser ("rest-admin" , "x" , "rest-admin" );
174183 }
175184
@@ -201,7 +210,7 @@ public void setUp() throws KeyManagementException, NoSuchAlgorithmException, Exc
201210 /*Pass this file's location for the gradle (thru Jenkins job)
202211 QA functional test project's build.gradle file has << systemProperty "keytabFile", System.getProperty("keytabFile") >>
203212 On gradle command line use the following syntax to pass in the location of the keytab file:
204- ./gradlew marklogic-client-api-functionaltests:test -DkeytabFile=/space/Jenkins/workspace/ services.keytab -Dprincipal=user2 .....other options
213+ ./gradlew marklogic-client-api-functionaltests:test -DkeytabFile=$WORKSPACE/java-client-api/ services.keytab -Dprincipal=builder .....other options
205214 */
206215 KerberosConfig krbConfig = new DatabaseClientFactory .KerberosConfig ().withPrincipal (principal )
207216 .withUseKeyTab (true )
@@ -252,30 +261,6 @@ public static void createAutomaticGeoIndex() throws KeyManagementException, NoSu
252261 }
253262 }
254263 }
255-
256- // Method sets REST server's "authentication" to "Kerberos-ticket" and "internal security" to false
257- // external security to be "none"
258- public static void setAuthToKerberosAndInternalSecurityToTrue (String restServerName )
259- throws Exception {
260- DefaultHttpClient client = new DefaultHttpClient ();
261-
262- client .getCredentialsProvider ().setCredentials (new AuthScope (appServerHostName , getAdminPort ()),
263- new UsernamePasswordCredentials ("admin" , "admin" ));
264- String body = "{\" group-name\" : \" Default\" , \" authentication\" :\" kerberos-ticket\" ,\" internal-security\" : \" false\" }" ;
265-
266- HttpPut put = new HttpPut ("http://" + appServerHostName + ":" + getAdminPort () + "/manage/v2/servers/" + restServerName
267- + "/properties?server-type=http" );
268- put .addHeader ("Content-type" , "application/json" );
269- put .setEntity (new StringEntity (body ));
270-
271- HttpResponse response2 = client .execute (put );
272- HttpEntity respEntity = response2 .getEntity ();
273- if (respEntity != null ) {
274- String content = EntityUtils .toString (respEntity );
275- System .out .println (content );
276- }
277- client .getConnectionManager ().shutdown ();
278- }
279264
280265 public GeoSpecialArtifact getGeoArtifact (int counter ) {
281266
@@ -1124,8 +1109,7 @@ public void testUberClientWithDbName() throws IOException, SAXException, ParserC
11241109 clientUber .release ();
11251110 }
11261111
1127- // Test DatabaseCLient with Basic Auth DIGEST auth type. Should expect an
1128- // Exception.
1112+ // Test DatabaseCLient with Basic Auth DIGEST auth type. Should expect an Exception.
11291113 @ Test
11301114 public void testWriteWithBasicAuthDigest () {
11311115 System .out .println ("Running testWriteWithBasicAuthDigest method" );
@@ -1172,4 +1156,53 @@ public void testWriteWithBasicAuthDigest() {
11721156
11731157 clientDigest .release ();
11741158 }
1159+
1160+ //Test DatabaseCLient with valid ADC user, but that user is not in the services keytab file. Should expect an Exception.
1161+ @ Test
1162+ public void testValidDCUserNotInKeytabFile () {
1163+ System .out .println ("Running testValidDCUserNotInKeytabFile method" );
1164+
1165+ // User "user2" is not in the ML Data folder's services.keytab file. But "user2" is in Active Directory and valid.
1166+ StringBuilder msg = new StringBuilder ();
1167+ try {
1168+ KerberosConfig krbConfigUser2 = new DatabaseClientFactory .KerberosConfig ().withPrincipal ("user2" )
1169+ .withUseKeyTab (true )
1170+ .withDoNotPrompt (true )
1171+ .withStoreKey (true )
1172+ .withKeyTab (keytabFile );
1173+ System .out .println ("Principal of key tab file is " + krbConfigUser2 .getPrincipal ());
1174+ client = DatabaseClientFactory .newClient (appServerHostName ,
1175+ appServerHostPort , new DatabaseClientFactory .KerberosAuthContext (krbConfigUser2 ));
1176+ } catch (Exception e ) {
1177+ msg .append (e .getMessage ());
1178+ e .printStackTrace ();
1179+ }
1180+
1181+ assertTrue ("Exception is not thrown for user2" , msg .toString ().contains ("Unable to obtain password from user" ));
1182+ }
1183+
1184+ //Test DatabaseCLient with invalid ADC user. Should expect an Exception.
1185+ @ Test
1186+ public void testInValidDCUserNotInKeytabFile () {
1187+ System .out .println ("Running testInValidDCUserNotInKeytabFile method" );
1188+
1189+ // User "builder890" is not in the ML Data folder's services.keytab file.
1190+ StringBuilder msg = new StringBuilder ();
1191+ try {
1192+ KerberosConfig krbConfigUser890 = new DatabaseClientFactory .KerberosConfig ().withPrincipal ("builder890" )
1193+ .withUseKeyTab (true )
1194+ .withDoNotPrompt (true )
1195+ .withStoreKey (true )
1196+ .withKeyTab (keytabFile );
1197+ System .out .println ("Principal of key tab file is " + krbConfigUser890 .getPrincipal ());
1198+ client = DatabaseClientFactory .newClient (appServerHostName ,
1199+ appServerHostPort , new DatabaseClientFactory .KerberosAuthContext (krbConfigUser890 ));
1200+ } catch (Exception e ) {
1201+ msg .append (e .getMessage ());
1202+ e .printStackTrace ();
1203+ }
1204+
1205+ assertTrue ("Exception is not thrown for builder890" , msg .toString ().contains ("Unable to obtain password from user" ));
1206+ }
1207+
11751208}
0 commit comments