Does Hadoop delegation for WebHDFS REST API has dependency with Kerberos SPNEGO? - kerberos

According to documentataion for WebHDFS REST API
https://hadoop.apache.org/docs/r2.7.3/hadoop-project-dist/hadoop-hdfs/WebHDFS.html#Delegation_Token_Operations
It is mentioned when security is on there is 2 mechanism
Authentication using Kerberos SPNEGO when security is on
Authentication using Hadoop delegation token when security is on
If i choose to use second option i.e Authentication using Hadoop delegation token when security is on
Does it mean it can run without Kerberos configuration in hadoop setup?
Do i have to setup Kerberos in my hadoop configuration in this case ?

To put things in context: typically, you use SPNEGO when you start your HTTP session, then cache your credentials somehow to avoid the complex rounds of 3-way communication between client, server, and Kerberos KDC.
AFAIK, all the Hadoop UIs and REST APIs use a signed cookie after the initial SPNEGO, and it's completely transparent for you -- with the exception of WebHDFS.
Now, with WebHDFS, you have to manage your "credentials cache" explicitly:
start your session with a GET ?op=GETDELEGATIONTOKEN -- you don't present any credentials, therefore it will trigger a SPNEGO authentication, then generate a Hadoop delegation token server-side
retrieve that delegation token from the JSON result
use that token to present your session credentials explicitly in the following GET / POST / PUT, by appending &delegation=XXXXXX to all URLs
Bottom line: yes, you have to set up your Kerberos configuration on client side. The delegation token only allows you to minimize the authentication overhead.

Related

Kubernetes authentication method to use for calling the K8 apis?

i am quite new to kubernetes and I am looking towards certificate based authentication and token based authentication for calling K8 apis. To my understanding, I feel token based approach (openID + OAuth2) is better since id_token will get refreshed by refresh_token at a certain interval and it also works well with the login point(web browser) which is not the case with Certificate based approach . Any more thoughts to this ? I am working using minikube with kubernetes . Can anyone share their thoughts here ?
Prefer OpenID Connect or X509 Client Certificate-based authentication strategies over the others when authenticating users
X509 client certs: decent authentication strategy, but you'd have to address renewing and redistributing client certs on a regular basis
Static Tokens: avoid them due to their non-ephemeral nature
Bootstrap Tokens: same as static tokens above
Basic Authentication: avoid them due to credentials being transmitted over the network in cleartext
Service Account Tokens: should not be used for end-users trying to interact with Kubernetes clusters, but they are the preferred authentication strategy for applications & workloads running on Kubernetes
OpenID Connect (OIDC) Tokens: best authentication strategy for end users as OIDC integrates with your identity provider (e.g. AD, AWS IAM, GCP IAM ...etc)
I advice you to use OpenID Connect. OpenID Connect is based on OAuth 2.0. It is designed with more of an authentication focus in mind however. The explicit purpose of OIDC is to generate what is known as an id-token. The normal process of generating these tokens is much the same as it is in OAuth 2.0.
OIDC brings a step closer to providing with a user-friendly login experience and also to allow us to start restricting their access using RBAC.
Take also look on Dex which acts as a middleman in the authentication chain. It becomes the Identify Provider and issuer of ID tokens for Kubernetes but does not itself have any sense of identity. Instead, it allows you to configure an upstream Identity Provider to provide the users’ identity.
As well as any OIDC provider, Dex supports sourcing user information from GitHub, GitLab, SAML, LDAP and Microsoft. Its provider plugins greatly increase the potential for integrating with your existing user management system.
Another advantage that Dex brings is the ability to control the issuance of ID tokens, specifying the lifetime for example. It also makes it possible force your organization to re-authenticate. With Dex, you can easily revoke all tokens but there is no way to revoke a single token.
Dex also handles refresh tokens for users. When a user logs in to Dex they may be granted an id-token and a refresh token. Programs such as kubectl can use these refresh tokens to re-authenticate the user when the id-token expires. Since these tokens are issued by Dex, this allows you to stop a particular user refreshing by revoking their refresh token. This is really useful in the case of a lost laptop or phone.
Furthermore, by having a central authentication system such as Dex, you need only configure the upstream provider once.
An advantage of this setup is that if any user wants to add a new service to the SSO system, they only need to open a PR to Dex configuration. This setup also provides users with a one-button “revoke access” in the upstream identity provider to revoke their access from all of our internal services. Again this comes in very useful in the event of a security breach or lost laptop.
More information you can find here: kubernetes-single-sign-one-less-identity/, kubernetes-security-best-practices.

Keycloak Applications vs Client authentication

Hi i am a bit confused as to how to secure applications through keycloak, the website shows how to secure clients. The application which i need to secure in my setup is a desktop application which uses keycloak + keycloak-gatekeeper protected endpoints.
i managed to get it working using the following library in python
https://bitbucket.org/agriness/python-keycloak/src/master/
however, it requires me to enter the client-secret and i am wondering if this is safe?
also, when i use the browser login instead, the browser doesnt need the client secret, but goes though gatekeeper, this tells me that i am doing something wrong here.
thanks
Use public access type client (Clients doc):
Public access type is for client-side clients that need to perform a browser login. With a client-side application there is no way to keep a secret safe. Instead it is very important to restrict access by configuring correct redirect URIs for the client.
You can change access type on clients - choose client - settings tab admin interface.
in your case, I would use Access type as confidential
and Authorization Enabled > on
and you should use the secrecy key to authorize your call to keylock when you want to interact with keycloak API
Keycloak keycloak = KeycloakBuilder.builder()
.serverUrl("localhost")
.realm("myRealm")
.grantType(OAuth2Constants.PASSWORD)
.clientId("myclient")
.clientSecret("xxxx-xxxxx-xxxx-xxx")
.username("foo")//the admin user
.password("password")
.build();
keycloak.realm("myRealm").users().list();

JWT and KONG with custom authrizations

I went through this tutorial on KONG
https://getkong.org/plugins/jwt/
I have an understanding of JWT and authorization concepts. I have prototyped JWT with Spring Boot where I could put my own key value like this {"authorizations":"role_admin, role_user"}.
It is easy to do that in Spring Boot but I am not able to find information on how to do this with KONG. Anyone has any info about it?
Kong community edition can handle only the authentication process, (give or deny access to a customer).
Authorization process (what a given customer can do in your application) is handled by your application or by https://getkong.org/plugins/ee-oauth2-introspection/ oauth2 introspection plugin which is enterprise edition only
you can write your own authorization server based on X-Consumer-Username request header if user passed authentication or original token header proxied by kong
hope helps
The kong jwt plugin does not support sending custom payload parameters to the upstream api. It does however seem like you can use this plugin (I have not tested it):
https://github.com/wshirey/kong-plugin-jwt-claims-headers
Update:
If you set Kong to forward all headers you'll get the raw Authorization header with the jwt token. So you could base64 decode the jwt token and pull out the claims/payload parameters you need manually in your service.

How to create SPNEGO token to be sent in HTTP header from Kerberos TKT?

I am developing an application that requires to authenticate with proxy using negotiate. User may not have Kerberos client installed. I am trying to achieve this using MIT Kerberos Library in order to avoid platform dependecy. I have successfully got TKT using krb5_get_init_creds_password and verified it krb5_verify_init_creds. Now I want ot create SPNEGO token to be sent in HTTP header using this TKT. Can anyone tell me any API or method to create SPNEGO token?
You can use gss_init_sec_context for the purpose.
Some background:-
SPNEGO is an abstraction on top of kerberos for HTTP based communication(which does not use the security context for encryption though)
for this pupose do the following:-
Now that you have krb5_get_init_creds_password and have got the krb5 mech credential create an in memory credential cache using krb5_cc_new_unique and then initialize it.
Now use krb5_cc_store_cred to store it into that cache
Use gss_krb5_import_cred to get a GSSAPI token
Now you have all the necessary preauth info. All you need to do is to use gss_init_sec_context for create an input token.
Now here is a good part, latest MIT Kerberos libraries support SPNEGO natively. There is an OID structure called gss_OID that you need to create. For SPNEGO that is:-
static gss_OID_desc _gss_mech_spnego = { 6, (void *) "\x2b\x06\x01\x05\x05\x02" };
and then pass this as an argument to gss_init_sec_context.
If you are using an older MIT Kerberos library then I suggest you use fbopenssl for this purpose. You can check out curl source code to check out how it is done.

Jaas - Requesting Renewable Kerberos Tickets

I have a Java API that talks to the Kerberos server and performs various operations. As of now, my API requests for non-renewable tickets to the Kerberos server. From what I understand, the jaas config file has an option to set the renewTGT option to true so that a renewable ticket can be issued. However, Jaas seems to have a lot of restrictions on setting the "renewUntil" time. Can anyone please tell me how we can request for arenewable ticket and also control its renewability? Basically, is there a way we can perform a Java equivalent of the operation : kinit -R ? Thanks in advance.
As of JDK7 (1.7.0_55), JAAS Krb5LoginModule does not provide any option to request a renewable TGT when authenticating, so this is not currently possible using JAAS. You might be able to achieve this, but you would need to use the internal Kerberos classes directly, bypassing JAAS.
Internally, Krb5LoginModule instantiates a sun.security.krb5.KrbAsReqBuilder to obtain credentials using either a provided password, or a keyTab. KrbAsReqBuilder has a setOptions(KDCOptions options) method, but this is not called in the login module. If it could be accessed, you could call KDCOptions#set(KDCOptions.RENEWABLE, true), and I would then expect the returned ticket to be renewable, if the KDC is configured to allow renewable tickets.