If you have multiple RESTful web services running on different subdomains (accounts.site.com, training.site.com, etc) what is a good authentication mechanism when one service needs to consume another?
Human authentication is easy because they supply their login credentials and get back a JSON Web Token which is then sent with every request to authenticate them.
A machine having a username and password just seems odd so I was wondering what are some proven ways of solving this problem?
It depends on... From the service perspective the other service is just a REST client, so let's stick with these terms.
If you want access different user accounts with your REST client, then you must register your client by the service and you will get an API key. The user can give privileges to that API key, so you can do things in the name of the service users if they allow it.
On the other hand if your client wants to access only its own account, then it is just a regular user of the service and it can have username and password just like the other users.
Related
I need to build a REST API that will be used by one private SPA web application. The problem is that the REST API must be on a different server than the SPA, so it must allow CORS. For two layers of security, the API can require Basic Authentication over SSL plus check for the correct client IP address.
It will not be possible to have a user login process for the API, since it is a service used by the SPA. The user is already logged into the client that hosts the SPA. I will not have access to anything other than the user's ID, and the REST API will have no way to validate this user ID.
Because the user is logged into the client's server, the API can be restricted to requests from the SPA's IP address, but that still potentially could allow anyone on that server to use the API other than the SPA.
Is this adequate protection?
I am considering adding a third layer of protection in the way of an access token, but this would be also fairly simple to uncover. If you know the basic authentication information (easily obtainable) and your IP address matches the expected client IP, then you are able to call the API to get an access token.
Also, with an access token comes the complexity of dealing with expired tokens.
Is it impossible to completely secure an API that requires a web-based client?
How many layers of security are enough?
I am designing the authentication system for a piece of software and need some guidance on how SASL and Kerberos services interact.
Here is the situation:
I have a client/server application that is itself pretty standard: only registered users can use perform actions. As an MVP I would typically implement a pretty standard solution:
Database stores username + salted hash of passord
Authentication attempt from client over HTTP includes username/password over TLS
Backend checks that username/password are valid and returns a bearer token that can be used for the duration of the session
In this case, however, there is a complicating factor. Some users of our system use Kerberos internally for user authentication for all internal services. As a feature, we would like to integrate our software with Kerberos so that they don't have to manage an additional set of users.
A more senior engineer recommended I look into SASL so that we might support several auth protocols simultaneously; standard customers can authenticate their users with the PLAIN method (over TLS), for instance, while other customers could limit authentication to only the GSSAPI method.
Up to this point, I have a clear idea of how things might be set up to achieve the desired goals. However, there is one more complicating factor. Some of the customers that want our system's auth to support Kerberos have other resources that our system will rely on (like HDFS) that also require authentication with Kerberos.
My understanding of Kerberos is this:
A client authenticates with Kerberos's ticket granting server
Upon successful authentication a TGT is returned that can be used for any future interaction with any Kerberos service in the system
Now to the point: How can I make all of these technologies work in harmony? What I want is:
- Client logs into my server
- My server authenticates client using customer's Kerberos system
- Client is given the OK
- Client asks for something from my server
- My server needs access to customer's HDFS, which requires Kerberos auth
- Server authenticates without asking the client to authenticate again
One possible solution I see to this is the following:
Make my server itself a Kerberos user
When the server needs to perform an action on HDFS, have it authenticate using its own credentials
There is a big downside to this, though: pretend the customer's Kerberos system has two realms: one with access to HDFS and one without. If users of both reals are allowed to use my system, but only one set can use HDFS, then I will need my own logic (and potentially objects in a DB) to determine who can perform actions that will require access to HDFS and who cannot.
Any pointers are going to be super helpful; in case it isn't obvious, I am quite new to all of this.
Thanks in advance!
It's not clear exactly what your question(s) are, but I'll do my best to address everything I think you're asking.
Firstly, I just want to clear this up:
Upon successful authentication a TGT is returned that can be used for
any future interaction with any Kerberos service in the system
That's not quite correct. The TGT enables the user to request service
tickets from the KDC for specific services. The service ticket is what
gives the user access to a specific service. The TGT is used to prove the
user's identity to the KDC when requesting a service ticket.
Client asks for something from my server - My server needs access to
customer's HDFS, which requires Kerberos auth - Server authenticates
without asking the client to authenticate again
This is a common enough problem and the Kerberos solution is called delegation. You should try to use Kerberos delegation in preference to coming up with your own solution. That said, how well supported it is depends on the technology stack you're using.
There are 2 kinds of delegation supported by Kerberos. The first kind is just called "delegation" and it works by sending the user's TGT to the service along with the service ticket. The service can then use the TGT to get new service tickets from the KDC on behalf of the user. The disadvantage of this approach is that once a service gets a user's TGT, it can effectively impersonate that user to any service that the user would be able to access. You might not want the service to have that level of freedom.
The second kind of delegation is called constrained delegation (also known as services4user or S4U). With this approach, the client doesn't send it's TGT to the service, but the service is allowed to ask the KDC for a service ticket to impersonate the user anyway. The services that can do this have to be whitelisted on the KDC, along with the services that they can request tickets for. This ultimately makes for a more secure approach because the service can't impersonate that user to just any service.
A more senior engineer recommended I look into SASL so that we might
support several auth protocols simultaneously; standard customers can
authenticate their users with the PLAIN method (over TLS), for
instance, while other customers could limit authentication to only the
GSSAPI method
Yes this is a good idea. Specifically, I'd recommend that you use the exact same session authentication mechanism for all users. The only difference for Kerberos users should be the way in which they get a session. You can set up a Kerberos-protected login URL that gets them a session without challenging them for credentials. Any user that hits this URL and doesn't have Kerberos credentials can just be redirected to a login page, which ultimately gets them the same session object (once they log in).
On the back end, the credential checking logic can use SASL to pass Kerberos users through to the KDC, and others through to your local authentication mechanism. This gives you a seamless fallback mechanism for situations when Kerberos doesn't work for the Kerberos users (which can happen easily enough due to things like clock skew etc.)
There is a big downside to this, though: pretend the customer's
Kerberos system has two realms: one with access to HDFS and one
without. If users of both reals are allowed to use my system, but only
one set can use HDFS, then I will need my own logic (and potentially
objects in a DB) to determine who can perform actions that will
require access to HDFS and who cannot.
This kind of thing is exactly the reason that you should use Kerberos delegation instead of coming up with your own custom solution. With Kerberos delegation, the KDC administrator control who can access what. If your service tries to impersonate a user to HDFS, and they are not allowed to access it, that authentication step will just fail and everything will be ok.
If you try to shadow the KDC's authorization rules in your own application, sooner or later they'll get out of sync and bad things will happen.
We have a need to secure our .net web api using open id and OAuth standards. IdentityServer 3 is perfect for us as we have to use our existing user store.
Edited for more clarity:
Our company services multiple customers. Each of our customers have their own database. In our home grown client application when a customer user enters their user/password, we do a lookup to authenticate and that also determines what backend database the app connects to.
We now have a need to allow a couple of trusted partners to access our database resource for specific needs. We have created a web api for them to make specific calls. The web api needs to know what customer the partner is making the call for. The partner is calling the api from services on their side so there is no user interaction.
I am trying to determine the flow to use to accomplish this. I found some pretty good info on flows at https://gist.github.com/jawadatgithub/638c11f08ecc0d76b05c.
If I define the client using the Client Credentials flow, I don't know how for them to pass the customer they are making the calls on behalf of. I don't think we want to definate a "Client" for every partner/customer combination, but is this the correct way?
What we had thought of initially is to give an additional user/password or secret key that would tell us the customer, but I am not sure what "flow" for the client would allow this.
Any help or direction would be greatly appreciated.
In case this helps anyone else, we decided to go with a Hybrid flow for these types of requests. We considered designating a service account (user/pw) for each of our customer databases that would give this trusted 3rd part access to them by requesting tokens with the Resource Owner Password Credential flow, but decided against it. We decided against it for all the reasons the standards say not to use it for this use.
If the 3rd party wants to interact with us on the behalf of one of our customers, then they will need to build the UI on their side to redirect to us for user/pw authentication and consent.
I am creating a service provider which talks to third party IDP for authentication. But I have a concern that I have a set of dedicated machines(Desktop,tab) which are highly trusted, so is their a way in SAML that when a request is sent from such machines user is directly authenticated without the need to type username and password.
you want that user that tries to access a resource from his desktop (which is trusted) will be automatically authenticated? if this is the case, it seems that you need to identify the user using the active directory or something.
if this is the case, search a bit about Kerberos, or ADFS - it might serve your needs.
I would like to build my own REST app.
I'm planning to use oAuth as a main auth approach.
The question is: Can I use login and password as client_id and client_secret (in terms oAuth spec) ?
I don't have any third side applications, companies, sites etc... which will authenteficate my users.
I have my own REST server and JS-application.
Whole site will be made in usual(RPC) approach, but some private part will be done as RESTfull service, with enough stand-alone JS application.
UPDATED: I'm not sure that I even need full oAuth support. It seems to me that I can ask login and password on https page and then generate some token. Later i could use it to check is this user authenticated already or not. But in this case this oAuth become almost the same what we have in web aplications. I do not need oAuth to athorize users ?
I'm not consider HTTP(s) authotization because i don't want to send evrytime user and password to server.
No.
One if the main reasons OAuth exists is to allow integrations without users compromising their usernames and passwords.
If you plan on using username and password, look into xAuth as an option if you still want to sign your requests. More info: https://dev.twitter.com/docs/oauth/xauth.
But you could likely just as well go for HTTP Basic Authentication. At least if you publish your API over SSL. More info: http://en.wikipedia.org/w/index.php?title=Basic_access_authentication
I think you might get a better answer on the security site. See, for example, this question.
In any case, you need to start with a detailed assessment of what attacks you are trying to prevent and what attacks are "acceptable.". For example, if you are using HTTPS then you can probably accept the remaining danger of a man-in-the-middle attack, because it would require forging an SSL certificate. It is harder to say in general if a replay attack is acceptable.
One reasonable solution would be to create a time-limited temporary token by having the user authenticate over HTTPS with the username and password, generating a secure token with an expiration date, and then sending that token and expiration date back to the client. For example, you can create a (reasonably) secure token by taking the SHA1 hash of a secret plus the user name plus the expiration timestamp. Then the client can include the token, the user name, and the authentication timestamp in future requests and you can validate it using your secret and your clock. These need not be sent as 3 parameters; they can be concatenated into one string user|timestamp|token.
Register your application with SLI. SLI grants a unique client ID and a client secret that enables your application to authenticate to the SLI API. You must also register the redirect URI of your application for use in authentication and authorization flows.
Enable your application with specific education organizations so that the application can be approved for use in those districts.
Configure and implement the appropriate OAuth 2.0 authentication and authorization flow in your application, which includes managing sessions and authorization timeouts.