Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow authenticating using Kerberos and a Principal/Password. #163

Merged

Conversation

pierresouchay
Copy link
Contributor

@pierresouchay pierresouchay commented Feb 28, 2017

This closes #66

This patch allow to authenticate using kerberos using the previous
methods (eg: keytab) or specifying user/password either in properties
or in connect method.

This allows to use GUIs for instance to connect using Kerberos without
having a sql user.

If fixes issue #66

@codecov-io
Copy link

codecov-io commented Feb 28, 2017

Codecov Report

Merging #163 into dev will increase coverage by 0.08%.
The diff coverage is 0%.

Impacted file tree graph

@@             Coverage Diff              @@
##                dev     #163      +/-   ##
============================================
+ Coverage     33.35%   33.43%   +0.08%     
- Complexity     1486     1487       +1     
============================================
  Files            97       98       +1     
  Lines         23569    23422     -147     
  Branches       3909     3845      -64     
============================================
- Hits           7862     7832      -30     
+ Misses        14141    14030     -111     
+ Partials       1566     1560       -6
Flag Coverage Δ Complexity Δ
#JDBC41 33.36% <0%> (+0.07%) 1483 <0> (ø) ⬇️
#JDBC42 33.37% <0%> (+0.11%) 1486 <0> (+7) ⬆️
Impacted Files Coverage Δ Complexity Δ
...om/microsoft/sqlserver/jdbc/SQLServerResource.java 100% <ø> (ø) 4 <0> (ø) ⬇️
...ava/com/microsoft/sqlserver/jdbc/KerbCallback.java 0% <0%> (ø) 0 <0> (?)
...m/microsoft/sqlserver/jdbc/KerbAuthentication.java 0% <0%> (ø) 0 <0> (ø) ⬇️
.../com/microsoft/sqlserver/jdbc/SQLServerJdbc41.java 33.33% <0%> (-26.67%) 0% <0%> (ø)
.../com/microsoft/sqlserver/jdbc/SQLServerJdbc42.java 25% <0%> (-25%) 0% <0%> (ø)
.../microsoft/sqlserver/jdbc/SQLServerDataSource.java 44.28% <0%> (-0.47%) 61% <0%> (ø)
...oft/sqlserver/jdbc/SQLServerParameterMetaData.java 19.78% <0%> (-0.36%) 27% <0%> (ø)
...m/microsoft/sqlserver/jdbc/SQLServerStatement.java 57.95% <0%> (-0.3%) 128% <0%> (ø)
...va/com/microsoft/sqlserver/jdbc/SQLServerBlob.java 26.34% <0%> (-0.26%) 13% <0%> (ø)
.../microsoft/sqlserver/jdbc/SQLServerConnection.java 41.1% <0%> (-0.24%) 227% <0%> (ø)
... and 14 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f3d22ac...115c7e9. Read the comment docs.

@pierresouchay
Copy link
Contributor Author

pierresouchay commented Feb 28, 2017

A few notes:
connecting with a user does not requires the full realm as long as default_realm is properly set in /etc/krb5.conf file (for instance, if default_realm = AD.EXAMPLE.COM then, if the username has no "@" within, it will be assumed that its name is user@AD.EXAMPLE.COM

Using a fully qualified username (for instance user@AD.EXAMPLE.COM) works as well.

In the case where a keytab is used, the callback won't even be called.

The global Kerberos mechanism may be enchanced as the Driver always retry even when the password is not valid (thus the return added).

For Another Review: A possible improvement would be to stop trying when login() does fails (we don't need to wait for timeout in that case) with a proper error message.

This commit should solve issue #66

@pierresouchay
Copy link
Contributor Author

The second commit also fixes issues with authentication taking a very long time even when Kerberos authentication is completely broken (eg: wrong keytab or wrong password)

@Suraiya-Hameed
Copy link
Contributor

@pierresouchay Can you open this PR in dev branch?

@pierresouchay pierresouchay changed the base branch from master to dev March 31, 2017 06:06
@pierresouchay
Copy link
Contributor Author

@v-suhame done

@Suraiya-Hameed Suraiya-Hameed added this to the 6.1.7 milestone Apr 3, 2017
This patch allow to authenticate using kerberos using the previous
methods (eg: keytab) or specifying user/password either in properties
or in connect method.

This allows to use GUIs for instance to connect using Kerberos without
having a sql user.
…a long time.

This commit solves this by stopping directly authentication when login() fails.

It means that if keytab is wrong OR provided principal/password are wrong, the
driver immediatly return and does not retry in a endless loop.
@pierresouchay
Copy link
Contributor Author

Updated the review to fix conflict due to #178

String message = String.format("%s due to %s (%s)", alwaysTriggered.getMessage(), le.getClass().getName(), le.getMessage());
if (callback.getUsernameRequested() != null) {
message = String.format("Login failed for Kerberos principal '%s'. %s", callback.getUsernameRequested(), message);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be consistent with the existing code, can you add this new exception error string in SQLServerResource.java?

}

private static String getAnyOf(Callback callback, Properties properties, String... names)
throws UnsupportedCallbackException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the formatter on new code.

Added translated message for Kerberos login authentication errors.
@pierresouchay
Copy link
Contributor Author

@v-suhame DONE in new patch

@Suraiya-Hameed
Copy link
Contributor

@pierresouchay Can you also push changes for IBM jre?

@Suraiya-Hameed Suraiya-Hameed added the Waiting for Response Waiting for a reply from the original poster, or affiliated party label Apr 11, 2017
@pierresouchay
Copy link
Contributor Author

@v-suhame As far as I know, there is no option on IBM JVM to disable callback according to https://www.ibm.com/support/knowledgecenter/en/SSYKE2_7.1.0/com.ibm.java.security.api.doc/jgss/com/ibm/security/auth/module/Krb5LoginModule.html

So I suspect it works on IBM JVM without changes

@Suraiya-Hameed
Copy link
Contributor

Tested PR with IBM JVM, Kerberos auth with username and password doesn't work. It looks like driver should switch between useDefaultCcache to true while using ticket and false for principal/password.

@pierresouchay
Copy link
Contributor Author

It means probably refactoring the creation of configurations according to connection parameters (and not in a static way)

For another PR?

@Suraiya-Hameed
Copy link
Contributor

Sounds good! I'll accept/merge this PR and leave the issue #66 open until it's fixed for IBM JVM.
Thanks @pierresouchay, and sorry it took so long to review and merge.

@Suraiya-Hameed Suraiya-Hameed merged commit 23676aa into microsoft:dev Apr 12, 2017
@Suraiya-Hameed Suraiya-Hameed removed the Waiting for Response Waiting for a reply from the original poster, or affiliated party label Apr 12, 2017
@pierresouchay
Copy link
Contributor Author

That's great !

IBM owners can still create their $HOME/.java.login.config file and specify the parameters of the config to make it work.

I did actually plan to use several names for instead of hardcoded default "SQLJDBCDriver" (and so remove the static initialization) -> that would be the right time to allow switching to a default configuration that enables login with username/password for IBM JVM

@pierresouchay pierresouchay deleted the kerberos-with-user_password branch April 18, 2017 07:12
@bayramgns
Copy link

Hello,

Is there a road map to develop driver for also IBM JVM to be able to use connection username and password properties for the kerberos authentication?

We can provide kerberos authentication by using keytab and login config files; it' s OK. But it would be much better to authenticate by using connection username and password properties instead of keytab and login config files as it' s used for Oracle JVM.

@pierresouchay
Copy link
Contributor Author

I did not test it, but it should work, did you try it?

@pierresouchay
Copy link
Contributor Author

@bayramgns you might try by creating a .java.login.config in your $HOME directory and putting useDefaultCcache=false it seems. Which version of IBM's JVM are you using?

@bayramgns
Copy link

@pierresouchay it works well for Oracle JVM. When you use Oracle JVM, you don' t need to use any keytab and login conf file; you only need to set up kerberos conf file and set driver connection properties. But for IBM JVM, it does not seem like that.

I use IBMSDK 7.1 and mssql-jdbc-6.2.1.jre7.jar versions.

As this change, I thought I won' t need to set any login conf property file; because you don' t need it for Oracle JVM.However, although I set login conf file as it seems below, it still does not work;

SQLJDBCDriver {
com.ibm.security.auth.module.Krb5LoginModule required
useDefaultCcache=false;
};

But when I set the login conf file like the below, it works well;

SQLJDBCDriver {
com.ibm.security.auth.module.Krb5LoginModule required
useDefaultCcache=false
useKeytab="D:/GUNES/krb5.keytab"
credsType=both
principal="XXX@YYY";
};

@bayramgns
Copy link

@pierresouchay could you check the case?

@pierresouchay
Copy link
Contributor Author

pierresouchay commented Oct 19, 2017

@bayramgns What do you mean exactly?

What are you testing?

  1. You are logged using Kerberos (for instance, a Windows session) and would like to access to a MS SQL Db?
  2. You are not logged using Kerberos and want to use keytab "D:/GUNES/krb5.keytab" ?
  3. You are not logged and want to connect using Kerberos and a login/password ?

Assuming you are in the third case, and according to this page:

https://www.ibm.com/support/knowledgecenter/en/SSYKE2_7.1.0/com.ibm.java.security.component.71.doc/security-component/jgssDocs/jaas_login_user.html

Krb5LoginModule might prompt for a principal name, password or both. Or it might not prompt for any input whatsoever. Whether or not the login is interactive depends on the options specified in the JAAS configuration file. For example, the login proceeds non-interactively when the credential type is initiator and a Kerberos TGT is to be retrieved from a default credentials cache file. On the other hand,a user is prompt for useCcache where user can specify a different credentials cache file if useDefaultCcache is set to false. If no value is entered, , a user is prompted for a password (and, perhaps, a principal name) when a TGT is to be obtained from a Kerberos KDC. When the login is interactive, the application must specify com.ibm.security.auth.callback.Krb5CallbackHandler as the callback handler when creating the login context. The callback handler is responsible for prompting for input.

I would try the following:

SQLJDBCDriver {
com.ibm.security.auth.module.Krb5LoginModule required
useDefaultCcache=false
credsType=both
};

I don't have a Windows machine nor IBM JVM to test now, can you test this configuration and tell me whether it works?

Current default configurations are the following:
https://github.com/Microsoft/mssql-jdbc/blob/dev/src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java#L26

@bayramgns
Copy link

@pierresouchay I have good news :) It worked by using IBM Java Version 8. I used to work with IBM Java 7 version before and it was getting KerberosException.

My purpose is connect to an MS SQL DB by authenticating with Kerberos protocol.I don' t want to use keytab file for username and password. I just want to set username and password connection properties instead of using keytab file.

When using IBM Java 7, you have to create a keytab file and also provide "useKeytab" and "principal" properties in "SQLJDBCDriver .conf" file; otherwise it does not work.

But when using IBM Java 8, it works by setting connection username/password properties(no need to create keytab file) and using a "SQLJDBCDriver .conf" file as you mentioned above (no need to provide useKeytab and principal properties).

Anyway, I have no problem any more :) Thanks for help :)

@pierresouchay
Copy link
Contributor Author

@bayramgns Ok, that's good news, can you try without the config file as well (I mean simply delete the file)?

If it does not work, we might try setting those properties in the conf, so people you not even have to create the jaas config file.

@bayramgns
Copy link

@pierresouchay , it does not work without the jaas config file. I' ve removed the auth login config jvm parameter and tried; but got "com.ibm.security.krb5.KrbException, status code: 31" exception.

I guess the default value of "useDefaultCcache (true)" in JaasConfiguration class causes the error.

Sounds great if you develop for setting these properties in the conf and no need to have jaas config file any more :)

@kmohanarangam
Copy link

kmohanarangam commented Mar 1, 2018

@pierresouchay @bayramgns 'But when using IBM Java 8, it works by setting connection username/password properties" - I tried the same. However, the driver picks up the logged in user instead of the userName and password provided in the connection string. Is your "run as" user and the username on the connection string one and the same?

@lilgreenbird lilgreenbird added this to Closed/Merged PRs in MSSQL JDBC Apr 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
MSSQL JDBC
  
Closed/Merged PRs
Development

Successfully merging this pull request may close these issues.

Use provided username and password for JavaKerberos
7 participants