Kerberos authentication with Java EWS API - kerberos

I am making use of EWS JAVA API to connect and retrieve data from EWS. Currently I can successfully do so via NTLM authentication, providing my username and password in code:
ExchangeCredentials credentials = new WebCredentials("username", "password", "domain");
However I'd like to authenticate by Kerberos instead (i.e. no explicit password specified). To give a high level picture, the interaction would be:
User <-> MyWebApplication <-> EWS
I can get hold of the user information (username, realm/ domain) in MyWebApplication. However I am not sure how I can generate the Kerberos token and pass in the Authorization (of type Negotiate) in the HTTP header to EWS using said library.
Please let me know if someone has managed to achieve something similar. In the worst case, I am open to not using the library at all and will just write my own implementation.
(I am aware of the commercial lib from IndependentSoft but not in the position to use it)

Related

How do I get the personal access token name using the Tableau REST API

I am creating an application to interact with Tableau's REST API.
I am using Tableaus Online Server to host the workbooks/groups/users etc.
What I need is a way to let a user sign in and then interact with the REST API without having to store a username and password for server authentication.
Currently, if someone wanted to get a list of workbooks, they would need the following code
import tableauserverclient as TSC
tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', site_id='CONTENTURL')
server = TSC.Server('https://SERVER_URL', use_server_version=True)
server.auth.sign_in(tableau_auth)
Tableau does use personal access tokens and I can authenticate like this
import tableauserverclient as TSC
tableau_auth = TSC.PersonalAccessTokenAuth('TOKEN-NAME', 'TOKEN-VALUE', site_id='CONTENTURL')
server = TSC.Server('https://SERVER_URL', use_server_version=True)
server.auth.sign_in(tableau_auth)
The problem I am running into is that signing in with a username and password only returns a token value. I don't think this is meant to be the same as the personal access token, but can I use this token value to authenticate the user and do other actions with the REST API?
The structure of the signin response is
{
credentials: {
site: {id: ...},
user: {id: ...},
token: tokenValue
}
}
You can also create a personal access token manually on the tableau online server. Is there a way to get this value after signing in with a username and password?
Okay, so I kinda figured it out like a few minutes after posting this. And if anyone else gets a little confused when working with the Tableau REST API and their authentication, I hope this helps a little bit.
There is a python package called tableauserverclient and it's supposed to make interacting with the REST API easier. It does, except I don't believe there is a way to pass values to the header of the request. Which is how they manage the access tokens after signing in (and the personal access token is a completely separate thing).
So, when a user signs in, they receive an access token that can be used later to authenticate other services. But, the token needs to be passed in the header as the X-Tableau-Auth value.
So, while the TSC library simplifies and python-izes some of the requests, it doesn't allow you to utilize the access token from sign in.

Restrict front client connexion with groups / roles in a realm

I'm looking for a way to restrict user access to specific clients in a realm.
I know I can do it with client where Authorization is enabled (fine-grained authorization support) but it doesn't work when trying to connect from front (client need to be public and not confidential).
I'm using a javascript application to login from front-end.
Is there a way to enable Authorization for public client or a work around ?
Thanks.
I'm not sure if this will totally answer your question because it's still not specific enougth but it may give you some further help.
In case you're new to the topic, please see difference between public and confidential clients here.
The current best practice for public clients like HTML/Javascipt applications is to use OpenId Connect with the Authorization Code Flow + PKCE. HTTPS is of course a must have. I recommend you use a javascript openid connect adapter for this like the following for example:
https://github.com/panva/node-openid-client
Basically your authentication / authorization flow is shown here:
When the user wants to login from your frontend client application first a unique verifier is generated which is only available to the exact user / browser session. This value get's hashed as a code challege. Then the user gets redirected to the login page of your authorization server (Keycloak for example) passing some parameters like a redirect uri and the challenge.
With successful login the user get's a session at the keycloak server which also stores the hashed challenge. Then the user gets redirected to given redirect uri (a path in your application) together with a code to obtain an access token. Back in your application you application uses the original value together with the code to get the actual token. The authorization server ckecks the value against the stored challenge and geturns the access token if it matches. You see the extra verifier is to prevent that anybody compromises your code fragment to obtain a token on your behalf.
Now you have an encoded access token in your browser app. Note the token itself is normally only encoded not encrypted but it can be signed. Those signatures can later be used from your backend to ckeck the token integrity but we will come to that soon. Roles, claimes, scopes and so on included in your access token tell you the privileges of the user/identity. You can of course use them to enable/disable functions in your app, block routes etc. but in the end client protection is never really effective so your real authorization ande resource protection happens at your resource server which is your backend (node, .net core, java etc.) maybe a restful Web Api. You pass your access token as a part of the http request header with every request to the backend. Now your backend checks the token integrity (optional) expiration time etc. analyzes scopes, claimes and roles to restrict the resource access.
For example a simple GET myapi/car/{1} may only need a token or can even be annonymous while a POST myapi/cars or PUT myapi/car/{1} may need a special role or higher privileges.
Does that help you out?

Shiro: Is it possible to get the URL in doGetAuthenticationInfo(AuthenticationToken token)

I am trying to create a RESTful web service using Jersey framework on google appengine. I am using apache shiro for authentication.
Let's say I have the following scenario:
There is a admin user pre-configured which creates other user and provides the username and password offline to each of those users.
For the normal users, there are a number of REST APIs. There is one API:
GET /tokenInfo which should use username and password for authentication and return a UserId and token as response.
For all the other REST APIs, I want the credential used for authentication to be the UserId and Token instead of Username and password.
So basically it a scenario where the credential pair used for authentication varies based on the API.
How can I achieve this in shiro. From what I understand, doGetAuthenticationInfo() passes the credentials sent by the client and expects you to validate, but in this case, I need to know which API is called. So is there a way to get the URL?
If no then what other way is there to achieve this?
Sounds like you would need to create a custom filter, to build the type of token you want to pass to your realm, take a look at one of the defaults as an example:
https://shiro.apache.org/web.html#default-filters

Getting SAML token with claims from ADFS using WindowsIdentity

I have a scenario where the client uses kerberos authentication (this cannot be changed) and, thus my WCF web service only has access to the WindowsIdentity object (System.Security.Prinicpal.WindowsIdentity). The WindowsIdentity object doesn't tell me much about the user (basically just the login name). What I need are specific claims about the user (e.g. email, etc.) so that I can map the AD user to one of my systems users.
I have set up a relying trust relationship with ADFS and from my server, using username and password, I am able to retrieve a SAML token and extract the claims I want (i.e. UserNameWSTrustBinding).
With that being said, it seems that given that I have a WindowsIdentity object in hand (ultimately provided by the ADFS system) I should be possible to ask ADFS to issue me a SAML token. That is, rather than specify the username/password I provide the WindowsIdentity.
I would greatly appreciate it if someone could point me in the right direction of how to accomplish this.
Thanks much!
Edit:
I have located the following Microsoft document showing the transformation of a kerberos ticket to a SAML token. So I know its possible, I just haven't yet figured out how to accomplish it.
https://msdn.microsoft.com/en-us/library/ff359114.aspx

avoiding clear text password login for github3.py

From a post on another stackoverflow, the following was recommended.
Is there a way to avoid using cleartext, maybe supply an existing admin ssh key instead?
from github3 import login
g = login('abcd', password)
with open('~/.ssh/temp.k.pub', 'r') as fd:
key = g.create_key('abcd', fd)
print("Created {0}".format(key.title))`
So to be clear, when communicating with GitHub's API, your communications are secured over HTTPS. github3.py uses requests which performs certificate verification and properly secures the connection. That said when we authentication using basic authentication, you're sending your credentials in the headers after base 64 encoding (which is not encryption and is not secure if it is somehow intercepted).
So really, you need to consider who you're worried about "seeing" your credentials. If you're worried about your company running a proxy locally that is meant to man-in-the-middle your connection and steal your credentials that's a good use for a limited token. You can create the token via the API or via the web UI. Either way, you would then (instead of using the code you have) do the following:
g = login(token='myspecialtoken')
Then you would do everything else the same way. I haven't checked if you can create ssh keys for the user with a token, but if it won't work you'll get an error about needing to use basic authentication (your username and password).
I still want to stress, though, that using your login credentials should be fine. The difficulty of intercepting that and retrieving your credentials as an arbitrary attacker is high. If you're worried about a different situation, you should definitely look more closely into the threat level.
You can use environment variables
ie
gh_login = os.environ.get('GITHUB_LOGIN')
gh_pass = os.environ.get('GITHUB_PASS')
Then pass these into login