Showing posts with label kerberos. Show all posts
Showing posts with label kerberos. Show all posts

Monday, January 29, 2018

LDap GSSContext null srcName with spring security

Leave a Comment

We try to make Windows authentication using spring security.

When we saw that we cannot authenticate our domain user with our keytab file created for our local pc, we checked our service user and see that it's password is valid. Then we checked whether we can reach from local to AD-domain. No request reached from our local as we controlled with network monitoring tool on AD-domain server machine. We also checked that outgoing traffic from our client with the command below;

netstat -oan 1 | find /I "[IP_ADDRESS_OF_AD_DOMAIN]" 

We could reach to that IP from our local, tested with telnet.

Our application.properties is like below;

app.ad-domain= example.com app.ad-server= ldap://adds.example.com.tr/ app.service-principal= HTTP/local_pc.example.com.tr@EXAMPLE.COM.TR app.keytab-location= local_pc.keytab app.ldap-search-base= OU=All Users,DC=example,DC=com app.ldap-search-filter= "(| (userPrincipalName={0}) (sAMAccountName={0}))" 

As a result we cannot get srcName of GSSContext. This gssName variable equals to null. Related SunJaasKerberosTicketValidator code block is as below;

@Override public KerberosTicketValidation run() throws Exception {     byte[] responseToken = new byte[0];     GSSName gssName = null;     GSSContext context = GSSManager.getInstance().createContext((GSSCredential) null);     boolean first = true;     while (!context.isEstablished()) {         if (first) {             kerberosTicket = tweakJdkRegression(kerberosTicket);         }         responseToken = context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length);         gssName = context.getSrcName();         if (gssName == null) {             throw new BadCredentialsException("GSSContext name of the context initiator is null");         }         first = false;     }     if (!holdOnToGSSContext) {         context.dispose();     }     return new KerberosTicketValidation(gssName.toString(), servicePrincipal, responseToken, context); } 

As we searched this GSSContext with null SrcName error, in general suggested solutions are related to keytab file . But in our problem, we cannot even reach AD server as we mentioned in the beginning.

related link: GSSContext with null SrcName

Is there any other suggestion?

Thanks...

0 Answers

Read More

Monday, December 25, 2017

Setting up a Spark SQL connection with Kerberos

Leave a Comment

I have a simple Java application that can connect and query my cluster using Hive or Impala using code like

import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;  ...  Class.forName("com.cloudera.hive.jdbc41.HS2Driver"); Connection con = DriverManager.getConnection("jdbc:hive2://myHostIP:10000/mySchemaName;hive.execution.engine=spark;AuthMech=1;KrbRealm=myHostIP;KrbHostFQDN=myHostIP;KrbServiceName=hive"); Statement stmt = con.createStatement();  ResultSet rs = stmt.executeQuery("select * from foobar"); 

But now I want to try doing the same query but with Spark SQL. I'm having a hard time figuring out how to use the Spark SQL API though. Specifically how to setup the connection. I see examples of how to setup the Spark Session but it's unclear what values I need to provide for example

  SparkSession spark = SparkSession   .builder()   .appName("Java Spark SQL basic example")   .config("spark.some.config.option", "some-value")   .getOrCreate(); 

How do I tell Spark SQL what Host and Port to use, what Schema to use, and how do I tell Spark SQL which authentication technique I'm using? For example I'm using Kerberos to authenticate.

The above Spark SQL code is from https://github.com/apache/spark/blob/master/examples/src/main/java/org/apache/spark/examples/sql/JavaSparkSQLExample.java

UPDATE:

I was able to make a little progress and I think I figured out how to tell the Spark SQL connection what Host and Port to use.

...  SparkSession spark = SparkSession .builder() .master("spark://myHostIP:10000") .appName("Java Spark Hive Example") .enableHiveSupport() .getOrCreate(); 

And I added the following dependency in my pom.xml file

<dependency>    <groupId>org.apache.spark</groupId>    <artifactId>spark-hive_2.11</artifactId>    <version>2.0.0</version> </dependency> 

With this update I can see that the connection is getting further but it appears it's now failing because I'm not authenticated. I need to figure out how to authenticate using Kerberos. Here's the relevant log data

2017-12-19 11:17:55.717  INFO 11912 --- [o-auto-1-exec-1] org.apache.spark.util.Utils              : Successfully started service 'SparkUI' on port 4040. 2017-12-19 11:17:55.717  INFO 11912 --- [o-auto-1-exec-1] org.apache.spark.ui.SparkUI              : Bound SparkUI to 0.0.0.0, and started at http://myHostIP:4040 2017-12-19 11:17:56.065  INFO 11912 --- [er-threadpool-0] s.d.c.StandaloneAppClient$ClientEndpoint : Connecting to master spark://myHostIP:10000... 2017-12-19 11:17:56.260  INFO 11912 --- [pc-connection-0] o.a.s.n.client.TransportClientFactory    : Successfully created connection to myHostIP:10000 after 113 ms (0 ms spent in bootstraps) 2017-12-19 11:17:56.354  WARN 11912 --- [huffle-client-0] o.a.s.n.server.TransportChannelHandler   : Exception in connection from myHostIP:10000  java.io.IOException: An existing connection was forcibly closed by the remote host 

0 Answers

Read More

Wednesday, March 29, 2017

Angular 2 and Spring Kerberos

Leave a Comment

Is it possible to use Kerberos in an Angular 2 application? We are using Spring which hosts our REST service and also protects the Angular 2 resources with Kerberos. We want to add roles and define what funtionality in the Angular2 application is available for certain roles. There seems to be little information around on how to do this since most of the people seem to have gone to use JWT or OAuth.

Would it be possible to use Kerberos for the initial authentication and then generate a JWT which is sent back to the browser?

At the moment I am thinking about setting up a REST endpoint /user which returns all the information about the currently logged-in user including his/her permissions. In Angular I can then read those permissions and manipulate the UI and the routes accordingly. The data coming from the server would already be protected by Kerberos and Spring. So if the user can still alter their local Angular to visit some of the protected routes, they would not see any data.

2 Answers

Answers 1

You are absolutely correct in what you have said. You would want to handle authentication through the back-end, be it Kerberos, OAuth, or whatever. Upon successful login, the backend would return a metadata response that allows the UI to configure itself appropriately. Since the backend is where the protected resources are, the UI doesn't really need to be "protected", but more so "dynamically configured" to be appropriate for a given user.

You have to decide how you want to do it, and where you want to write most of your logic. For instance, the back-end could return something as simple as a role or experience identifier (ex. Admin, User, Guest). From there, the UI would know which activities should/could be performed, which resources are available, etc. The UI would know for example that a Guest cannot add a new user, but, because Mr. Guest could get curious, the most important thing is that the back-end indeed does not allow him to modify user accounts.

Answers 2

This would be a perfect use case for JWT tokens. Once you are authenticated at server end backend service can create a JWT token with the roles of a particular user and return back the same to Angular2 app. Angular app can configure UI depending on the roles of the user. On every consecutive server calls the angular app can sends back this token, so that this token is used to find the roles of the user. Spring security allows to add the custom filter before Authentication which can be used to validate the token.

@Configuration public class WebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {      @Override     protected void configure(HttpSecurity http) throws Exception {         http.addFilterAfter(new TokenFilter(), BasicAuthenticationFilter.class);     } } 

Inside TokenFilter the JWT token can be parsed for finding the user roles and allowing the access for a particular protected resource. If anybody tries to modify the token or request a forbidden protect resource the JWT token validation would fail.

public class TokenFilter extends GenericFilterBean {      @Override     public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {         // Validate Token her for the requested url        if(validateToken(request.getHeader("auth")){             chain.doFilter(request, response);        }else{             // return 403 response     } } 
Read More

Sunday, April 3, 2016

Windows Executable File Authentication

Leave a Comment

Searching around the windows authentication methods and protocols, i decided to understand the exact difference between Negotiate, Kerberos, and NTLM used in a simple executable file before liking it with IIS and Web Authentication.

I reached to good results, BUT I still need more details about the Negotiate and Kerberos.

I have the following scenario :

I have created very simple C# windows forms application that shows a message box displays the value for :

System.Security.Principal.WindowsIdentity.GetCurrent().AuthenticationType 

Note that i'm a domain user with admin privileges on my local machine, I have the following results :

  1. When i run the exe file (double click) while i'm actively connected to the DC, i got "Negotiate".

  2. When i run the exe file (run as differnet user / using local user) while i'm actively connected to the DC, i got "NTLM".

  3. When i run the exe file using "Run as Administrator", or "Run as Different User" i got "Kerberos".

  4. When i run the exe file while i'm locally logged in using local account, i got "NTLM".

I understand that the LSA will use NTLM for local accounts. Also i understand that Active Directory uses Kerberos to authenticate domain users and computers.

My question is, why i'm getting the Negotiate Authentication Type when i run the exe using my account either by (Double Click), or "run as different user" using my Same account ?

Update : I noticed the following :

- If local user is running the exe then it is NTLM
- If domain user run the exe then it is Negotiate (If that user is local admin) but is is Kerberos (if that user is not local admin)
- If domain admin run the exe then it is Kerberos

I just a clarification about this behavior.

1 Answers

Answers 1

First off, (which you seem to understand in the question, but just to be clear) an EXE doesn't have any authentication - it is just an executable. The OS creates a process object which executes it within a logon session identified by a principal. It's this principal which has been authenticated by NTLM or Kerberos (or some other protocol).

Next, Negotiate means that when the logon session was created the Negotiate authentication package was used to decide which authentication package - Kerberos or NTLM - would be used.

When you query the WindowsIdentity.AuthenticationType value, you are ultimately calling a function in the Local Security Authority (LSA) called LsaGetLogonSessionData. This reports details of the logon session used to run the process you are executing. The way that this logon session was created probably has the largest effect on the authentication package used to verify the credentials.

When logging into Windows the first time, Winlogon.exe establishes an interactive logon by calling LsaLogonUser. It queries the authentication packages in HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Authentication Packages in order until it finds one that can authenticate the given credentials. Once an interactive logon has been established, you can create new processes using noninteractive logons under different credentials, and in this case, the LogonUser function is likely called. One of the parameters to this function is dwLogonProvider which has the following default (which is likely the one used):

LOGON32_PROVIDER_DEFAULT   Use the standard logon provider for the system.  The default security provider is negotiate, unless you pass NULL  for the domain name and the user name is not in UPN format.  In this case, the default provider is NTLM. 

So, the package reported for the logon session the process is running under depends on how the logon session was created. (It isn't clear from your question exactly how you create the logon sessions you are testing... doing "Run As" in all cases? Logoff / Logon Windows for some cases?) It also depends on which package Winlogon was able to successfully authenticate with first for the interactive logon session. Ultimately, though, note that the authentication mechanisms all call down to some authentication package, and if Negotiate is used, Kerberos is preferred, though Negotiate is what is reported.

Here is an old but still relevant diagram which shows how all the authentication fits together in Windows:

Windows Authentication Architecture

Source

Read More