BITS, TakeOwnership, and Kerberos / Windows Integrated Authentication - windows-authentication

We're using BITS to upload files from machines in our retail locations to our servers. BITS will stop transferring a file if the user who owns the BITS job logs off. Therefore, we're using a Windows Service running as LocalSystem to submit the jobs to BITS and be the job owner. This allows transfers to continue 24/7.
However, it raises a question about authentication. We want the BITS server extensions in IIS to use Kerberos to authenticate the client machine. As far as I can tell, that leaves us with only 2 options, both of which are not ideal: Either we create an "ImageUploader" account and store its username/password in a config file that the Windows Service uses as credentials for the BITS job, or we ask the logged on user who creates the BITS job for his password, and then use his credentials for the BITS job. I guess the third option is not to use Kerberos, and maybe go with Basic Auth plus SSL.
I'm sure I'm wrong and there's a better option. Is there?
(By the way, here's a blurb from BITS
documentation about Service Accounts,
impersonation and BITS):
Service Accounts and BITS You can use
BITS to transfer files from a service.
The service must run as the
LocalSystem, LocalService, or
NetworkService system account. Jobs
created by the system account are
owned by that account. Because system
accounts are always logged on, BITS
transfers the files as long as the
computer is running and there is a
network connection. If a service
running under a system account
impersonates the user before calling
BITS, BITS responds as it would for
any user account (the user must be
logged on). For more details on using
a service with BITS, see the Platform
SDK.
Thanks.

Related

Storing Service bus connection string locally

I have a web app hosted in azure posting topics to a service bus queue. The connection string is stored in a secure vault and all is good.
I would like a number of windows services running worker threads on various customers local machines to pick up their own messages, they will then perform a set of tasks based on the message they receive.
How do you secure the service bus connection string for the windows service? Appsettings?
There are a couple options built into Windows Credential Manager, which is a more general app for storing passwords on a machine, and the Windows Data Protection API which helps with encryting/decrypting passwords you can store somewhere on disk. Both make use of the user's password to encrypt and decrypt the passwords.
What I would suggest as an added layer of protection is to issue the customers an Service Principal ID/Secret instead of the Service Bus queue connection string with read access to that particular secret in your Key Vault. It unlinks the dependency between the Service Bus connection string and your customers, i.e. you can rotate your keys without contacting each one, and if you issue individual Service Principals you'll be able to revoke access easily- adding the Service Principals to a security group and giving the group access to the Key Vault will make management much easier.

What is the use of the pre-auth user in SPNEGO SSO configuration?

I'm using SPNEGO in order to implement SSO solution. During the configuration, I was required to use domain user credentials in 2 steps:
In the web.xml of my application:
<init-param>
<param-name>spnego.preauth.username</param-name>
<param-value>myuser</param-value>
</init-param>
<init-param>
<param-name>spnego.preauth.password</param-name>
<param-value>mypassword</param-value>
</init-param>
In the setspn command: setspn -A <mySPN> myuser
When I used this configuration, the username of the user "myuser" was retrieved by the Java application using getRemoteUser(). So the SSO worked fine. But when I tried to open a session as other users (on the same windows server) it worked also, so I am a little bit confused. This led me to these questions:
Why did the SSO work for all the other users of the domain? Do I have to use the same user in both web.xml and setspn command? And which user to choose? What's the exact use of the SPN in the Kerberos scenario? Do I have to execute the command setspn in every windows computer or there is a way to do it just once?
This account is part of what defines the server's identity within Kerberos.
Kerberos is a symmetric-key protocol. Each user has a symmetric key that's shared between the user and the KDC, and similarly each service (acceptor) has a symmetric key that's shared between the service and the KDC.
When a user requests tickets for a specific "service principal", the KDC will return them encrypted using that service's key. So in order for a service to decrypt those Kerberos tickets, it also needs some way to know the key associated with its own service principal.
Often, the service key is generated randomly and provided through a "keytab" file. However, in Active Directory systems, most service accounts are regular user accounts which have a password – so their key can be derived from the service's password instead.
It seems that your SPNEGO module supports both methods (see lines 150-160) – it can be given a keytab or a password.
In any case, the setting has absolutely nothing to do with the clients that will be connecting to your service. It only establishes the server's own identity.
What's the exact use of the SPN in the Kerberos scenario?
It's similar to the domain name field in HTTPS certificates. For example, when a browser performs Kerberos authentication to https://example.com, it will always request a Kerberos ticket for the SPN HTTP/example.com from the KDC.
If you're familiar with OAuth2 or SAML or JWTs, I believe the Kerberos SPN would be the rough equivalent of the "audience" field in SAML assertions, or the "aud" field in JWTs.
(Note that the browser only knows your service by its SPN, and doesn't care about the actual service accounts that are used behind the scenes – e.g. Active Directory happens to map SPNs to real "user" accounts in this case, but other Kerberos implementations do it differently)
Do I have to use the same user in both web.xml and setspn command?
Yes, it needs to be the same user, because the service must be able to decrypt tickets that were issued for its SPN, so it needs to know the same symmetric key.
And which user to choose?
Create a new, dedicated account just for that service. Do not use a real "person" account.
Use a long, highly random password, and mark it as non-expiring. Additionally, make sure to enable both "Account supports Kerberos AES xxx-bit" features in the account's options (assuming your Java SPNEGO thing supports AES, which it really ought to).
Do I have to execute the command setspn in every windows computer or there is a way to do it just once?
No, it doesn't matter where you execute it, because it only edits the actual account on the domain controllers – it leaves no trace on the local machine. (Specifically, it sets the servicePrincipalName LDAP attribute for the provided account.)
Clients only recognize your service by its SPN, and they have no need to know about the account mapping that's done by the KDC behind the scenes.

How can I authenticate with the machine account during SPNego authentication?

My goal is to create a HTTPS REST service that (in concept) allows a machine account to authenticate using the less- than documented machine$ account.
I have a REST endpoint for an AD connected intranet application. Right now IIS simply echoes the thread CurrentPrincipal when I navigate using Internet Explorer.
Now I'm using the HTTPClient , using default authentication, running a my username, and that also works.
My new goal is to send the AD Connected machineAccount (that ends in the dollar sign $) so that IIS responds with the kerberos name Domain\TestServer$
I attempted creating a Windows Desktop service, running as NetworkService or LocalSystem, and I'm not clear if HttpClientHandler.UseDefaultCredentials is sufficient for running in this (unusual) context or if a different approach is needed to authenticate using the machine account.
Is a PInvoke needed? Is there anything in logonuser32 that needs to be done?

SSO using Kerberos on Windows and Linux

We have a client/server based application that is developed internally. Clients and server communicate over a TCP/IP connection with an application-specific protocol. The clients run on Windows and the server runs on Linux. All machines are in the same Active Directory/Kerberos domain/realm.
Currently, the user enters a username and password when they start the application. The server checks the username and password (authentication). Based on the username, the server also determines access to resources (authorization).
We want to add Single Sign-On (SSO) capabilities to the application. That is, we do not want the user to enter a username and password but we want to automatically logon as the current Windows user.
Of course, determining the current Windows user has to be done securely.
I have come up with the following setup:
I use SSPI (Negotiate) on Windows and GSSAPI on Linux.
When the client connects to the server, it uses AcquireCredentialsHandle (Negotiate) to get the credentials of the current Windows user.
The client uses InitializeSecurityContext (Negotiate) to generate a token based on these credentials.
The client sends the token to the server.
The server uses gss_acquire_cred() to get the credentials of the service. These are stored in a .keytab file.
The server receives the token from the client.
The server uses gss_accept_sec_context() to process the token. This call also returns the "source name", that is the current Windows user of the client.
The server uses the "source name" as the username: the server performs no additional authentication. The server still performs authorization.
This works but I do have some questions:
Is this secure? It should not be possible for the client to specify any other username than the Windows user of the client process. If a user has the credentials to create a process as another user (either legally or illegally) than this is allowed.
Should I perform additional checks to verify the username?
Are there alternative ways to achieve SSO in this setup? What are their pros and cons?
What you've described here is the correct way to authenticate the user. You should not have to worry about the user specifying a different name; that's what Kerberos takes care of for you.
If the client is able to obtain a service ticket, then they must have been able to authenticate against the KDC (Active Directory). The KDC creates a service ticket that includes the user's name, and encrypts it with the service's secret key.
The client would not be able to create a ticket for the server with a fake name, because it doesn't have the necessary key to encrypt the ticket.
Of course, this all assumes that you've set everything up correctly; the client should not have access to the service's keytab file for example, and the service should not have any principals in its key tab except its own.
There's a pretty detailed explanation of how it works here.

Network Services Account

HI All,
I have a .NET application which connects to a Web Service. Application pool for the Web service works under Network Services account. Everything was working fine till yesterday and somehow it started giving error today. When I changed the application pool account from Network Services to an Admin level account, everything started working fine.
As far as I know, Network Services account has top level privilage on the local system.
My question is, can Network Services account lose its permissions? If yes, how to give those permissions back again?
Cheers.
The Network service account has no top level privilege on the local system. True is, the Network Service account has minimum privileges like a user in the users group has.
It is most likely someone has changed the privileges for some files and/or folders on your system, so that the network sertvice account is not permitted anymore.
http://msdn.microsoft.com/en-us/library/ms684272%28VS.85%29.aspx