Keycloak Direct Grant API and Admin REST API - authentication

I am creating a mobile application which will talk to my REST Web Services, for login, GET, POST, DELETE and logout. I have been trying to figure out how to secure these REST Web Services using Keycloak. I do not want any In Browser Login on the mobile application, so I was inclined towards Direct Grant API and Admin REST API for authentication and token validations. But, now after looking at the available options on Keycloak, every request from the mobile app must be intercepted, and then make a REST call to the Keycloak module for validating the token and then return a response back to the mobile app.
Is there a better way in doing this? Some inbuilt function calls to check the token validity instead of making an HTTP call for every request from the mobile app? I think this is a huge overhead.
My server is on JBOSS. Spring, Resteasy and Keycloak-services are being used to figure out a solution for this problem.

Related

Handling mobile client Facebook SSO in Express backend

I'm trying to figure out the proper way of handling Facebook SSO, with a mobile client and an ExpressJS server using PassportJS.
Right now, I have a mobile client that's able to authenticate itself against Facebook SSO.
What's the proper way of handling authentication against my own Express server?
I'll try to explain myself here: Once the client gets the auth token from FB's APIs, he'll probably call my Express server to register the user, e.g. /api/user/register?fb_auth_token=.....
Do I then have to implement my own OAuth token logic (using Passport), so I can supply the client with some token so he can prove who he is for subsequent calls to my APIs?
Essentially give him a unique token for his user account in my DB?
Or do I simply save FB's auth token in my DB, and use that token for authentication in subsequent calls?
I know this is a bit more high level of a question than usual for this site, I'm just trying to figure out the main flow of using such SSO methods.

How to call an ADFS secured Web API function

Here's my situation. I have two different Web Applications (App1, App2), both with an implementation of WIF and AD FS. They both have Web API controllers, and all calls are secured with WIF. This means that whenever I do an unauthenticated call to my Web API functions, it's redirected to the ADFS login page. They both use the same instance of AD FS, so single-sign-on works.
However, this redirect behavior is problematic in a particular scenario. Let's say that I login through App 1. From App 1, I want to call a WebAPI function on App 2, using an HttpClient or a similar class. My call fails, because it's always redirected to the ADFS
I'm guessing it's because I need to pass my security token somehow, but I haven't figured out how. Any help about how I could do this would be greatly appreciated.
TL;DR: Can I call a Web API function secured by WIF/ADFS through a client in .NET code?
Thanks!
IMHO opinion web api is not compatible with a passive WIF redirect. This does not mean you can't protect your web api; it just means that a passive scenario is not ok for this. Web api, by its very nature calls more for an active scenario where you get your security token from your STS through code, not through the redirects of a browser (in web api there normally isn't any browser). Then your need to pass your security token along with the web api call (normally through some http header like x-authorization) There is not standard for this but some good ways are documented in a book like web api security. This means your have to write some actionfilters yourself to get the security token out of the header. I addition, I think the ThinkTecture libraries offer some off the shelf support for securing web api's.

REST API authentication for web app and mobile app

I'm having some trouble deciding how to implement authentication for a RESTful API that will be secure for consumption by both a web app and a mobile app.
Firstly, I thought to investigate HTTP Basic Authentication over HTTPS as an option. It would work well for a mobile app, where the username and password could be stored in the OS keychain securely and couldn't be intercepted in transit since the request would be over HTTPS. It's also elegant for the API since it'll be completely stateless. The problem with this is for the web app. There won't be access to such a keychain for storing the username and password, so I would need to use a cookie or localStorage, but then I'm storing the user's private details in a readily accessible place.
After more research, I found a lot of talk about HMAC authentication. The problem I see with this approach is there needs to be a shared secret that only the client and server knows. How can I get this per-user secret to a particular user in the web app, unless I have an api/login endpoint which takes username/password and gives the secret back to store in a cookie? to use in future requests. This is introducing state to the API however.
To throw another spanner into the works, I'd like to be able to restrict the API to certain applications (or, to be able to block certain apps from using the API). I can't see how this would be possible with the web app being completely public.
I don't really want to implement OAuth. It's probably overkill for my needs.
I feel as though I might not be understanding HMAC fully, so I'd welcome an explanation and how I could implement it securely with a web app and a mobile app.
Update
I ended up using HTTP Basic Auth, however instead of providing the actual username and password every request, an endpoint was implemented to exchange the username and password for an access key which is then provided for every authenticated request. Eliminates the problem of storing the username and password in the browser, but of course you could still fish out the token if you had access to the machine and use it. In hindsight, I would probably have looked at OAuth further, but it's pretty complicated for beginners.
You should use OAuth2. Here is how:
1) Mobile App
The mobile app store client credentials as you state yourself. It then uses "Resource Owner Password Credentials Grant" (see https://www.rfc-editor.org/rfc/rfc6749#section-4.3) to send those credentials. In turn it gets a (bearer) token it can use in the following requests.
2) Web site
The website uses "Authorization Code Grant" (see https://www.rfc-editor.org/rfc/rfc6749#section-4.1):
Website sees unauthorized request and redirects browser to HTML-enabled autorization endpoint in the REST api.
User authenticates with REST service
REST site redirects user back to website with access token in URL.
Website calls REST site and swaps access token to authorization token.
Here after the website uses the authorization token for accessing the REST service (on behalf of the end-user) - usually by including the token as a "bearer" token in the HTTP Authorization header.
It is not rocket science but it does take some time to understand completely.
3) Restricting API access for certain applications
In OAuth2 each client is issued a client ID and client secret (here "client" is your mobile app or website). The client must send these credentials when authorizing. Your REST service can use this to validate the calling client
I resolved this for my own API quite easily and securely without the need to expose any client credentials.
I also split the problem into 2 parts. API authentication - is this a valid request from a recognised entity (website or native app). API authorisation, is that entity allowed to use this particular endpoint and HTTP verb.
Authorisation is coded into the API using an access control list and user permissions and settings that are set up within the API code, configuration and database as required. A simple if statement in the API can test for authorisation and return the appropriate response (not authorised or the results of processing the API call).
Authentication is now just about checking to see if the call is genuine. To do this I issue self signed certificates to clients. A call to the API is made from their server whenever they want - typically when they generate their first page (or when they are performing their own app login checks). This call uses the certificates I have previously provided. If on my side I am happy the certificate is valid I can return a nonce and a time limited generated API key. This key is used in all subsequent calls to other API endpoints, in the bearer header for example, and it can be stored quite openly in an HTML form field or javascript variable or a variable within an app.
The nonce will prevent replay attacks and the API key can be stolen if someone wants - they will not be able to continue using after it expires or if the nonce changes before they make the next call.
Each API response will contain the next nonce of if the nonce doesn't match it will return an authentication error. In fact of the nonce doesn't match I kill the API key too. This will then force a genuine API user to reauthenticate using the certificates.
As long as the end user keeps those certificates safe and doesn't expose the method they use to make the initial authentication call (like making it an ajax request that can be replayed) then the API's are nice and secure.
One way of addressing the issue of user authentication to the API is by requesting an authentication token from the API when the user logs in. This token can then be used for subsequent requests. You've already touched on this approach - it's pretty sound.
With respect to restricting certain web apps. You'll want to have each web app identify itself with each request and have this authentication carried out inside your API implementation. Pretty straight forward.

Using Google's OpenID Connect as part of a SSO

I'm developing a common auth service for several different web services. The general idea is that a user goes to one of these web services and clicks on a login button and gets redirected to my auth service. Once authenticated, the auth service redirects the user back to the original web service.
To begin with, the auth service will use Google's OpenID Connect service. One idea I had was that when a user was authenticated using Google I could pass around the resulting JWT to other services to use as an auth token. Google mentions this idea in their documentation (https://developers.google.com/accounts/docs/OAuth2Login#validatinganidtoken):
One thing that makes ID tokens useful is that fact that you can pass them around different components of your app. This can be helpful because different components of your application may pass the ID token between them and use it as a lightweight authentication mechanism authenticating the app and the user.
Can anyone help me with the actual details on how this should work e.g. How do I handle log outs both on Google and from the auth service? There appeared to be some documentation on this in older OpenID Connect Session documents (-03) but it appears to have been removed.
You should not pass the ID Token that you receive to Google back to the app to use as an auth token. The ID Token will have an audience specific to your app, not the ultimate client.
If you just passed this back to clientA, then you would open it up to auth attacks where clientB could obtain an Google ID Token via your auth service and then use that token to gain access to user data in clientA.
A much better approach would be to mint your own ID Token and provide an audience designation for each app that uses your service.
Monitoring session state is not as straightforward. The easiest thing to do is for your service to wrap G+ sign-in libraries and interface with the session state api's.
https://developers.google.com/+/web/signin/session-state

RESTFul Authentication with WebAPI

I have a web service built with WebAPI that accepts JSON requests and responds accordingly. The core architecture is built but there isn't any authentication/authorization.
After a lot of googling and poking around sample projects, I'm not sure where to start. I've found a ton of material from 2008 and 2009 but not a whole lot of recent guides/workflows for WebAPI / single page apps. I think the workflow should be as follows:
Check to see if the user is logged in: How can this be done with javascript? Do I send a cookie to my webAPI? If so, do I send that cookie as a parameter in the body of the request?
Let the user log in / register: How is this data encrypted/decrypted? Surely I can't be sending passwords over the wire... is this where SSL comes in?
Provide them with access to what they have rights to access: I think I got this - I can just authorize in the controllers on a per-request basis.
Any info would be awesome.
Basically you need a token based authentication or authorization.
If you are referring to the ASP.NET WebAPI, the following project will be a great place to start:
http://thinktecture.github.com/Thinktecture.IdentityModel.45/
Even if you are not using ASP.NET WebAPI, the following video is a great introduction on how to provide authentication/authorization on RESTful web services:
http://vimeo.com/43603474
To answer some of your questions:
Check to see if the user is logged in: How can this be done with javascript? Do I send a cookie to my webAPI? If so, do I send that cookie as a parameter in the body of the request?
You can use a cookie but I normally use the header in order to avoid common XSRF attacks. Cookies are automatically included whenever a http request is sent from the browser.
is this where SSL comes in?
Yes. If you are going to go ahead with the token based approach, you can use a separate server (Identity Server) to do the authentication for you.
JavaScript clients are unique. Do you have the Web API and the page serving up JavaScript in the same domain? If not, you have same origin policy restrictions. If you have the same Web application hosting the web pages and Web API, you can use forms Authn. In that case, you don't need to send the cookie containing the authentication ticket yourself from JavaScript. Browsers do that for you and that is the cause of XSRF problem. You have to be careful about JavaScript sending credentials that the end user is not supposed to know. If JavaScript knows something, any intelligent end user can get to that knowledge. OAuth 2.0 implicit grant could be a good choice. The end user enters the credentials (password) in the authorization server which issues an access token. JavaScript gets the token and presents it to the web API but it will never have access to the credentials.