>
> I'm trying to build something similar to a microservice using Django and
> can't figure out how to setup the authentication part.
>
> When I say 'microservice' I mean, we have a bunch of systems like -
> example.com  , test.com  , another.com and another.test.com (a
> subdomain). I'm going to build a REST API on test.com which needs to be
> consumed by another.com. How can I enforce this restriction? And if
> later, I wanted to allow example.com to use the API (or even allow
> general public access), how can I do this?
>
> My instincts tell me that I'm missing something obvious, but I can't seem
> to figure out what to search for.
>
> Puzzled,
> Abraham V.
>

Seems like a simple question, but as with most things relating to computer
security, the answer is "it depends (on a lot of things)".

There are dozens of ways to handle this problem, and many of them have
nothing to do with Django. You have two primary lines of defense: network
controls and authentication controls. The answers aren't necessarily
obvious, although any bit of reading on how other people have approached
the problem shouldn't be difficult to track down with a quick Google.

Network controls should be where you start, if you can, since you can
filter a majority of the Internet noise here without much effort (usually).
I'll assume that you have a host firewall such as iptables or Windows
Firewall, or a hardware firewall, that is configured to only allow the
Internet to access your server on the necessary ports for serving your web
application (likely tcp/80 and/or tcp/443). If you can narrow down the
source IP addresses or IP ranges that example.com and others will be using,
you can add these as exceptions in your firewalls instead of the broad
port-based exception I just described (or better yet as a combination of
the port-based exceptions and source IP's), while dropping requests from
anywhere else. Moving up the stack, most HTTP servers will also allow you
to specify the range of source IP's that are valid when responding to
requests, but may provide a slightly weaker security posture since I would
assume the web server would not be protected by firewalls, and could be
subject to buffer-overflows, bad request exploits, etc. I'd recommend using
both strategies concurrently, keeping them in sync with a configuration
management tool. You would still be exposed if a service/host at another.com
were compromised (which is exactly how Target was compromised by an
attacker pivoting through a 3rd party vendor), but at least you've
significantly lowered your attack surface. Another option would be to hide
the entire set of microservices behind a VPN and require the consumer to
first connect to the VPN in order to gain access, which may or may not be
feasible. Plenty of permanent branch VPN solutions are available so that
individual users don't need to be bothered with setting up VPN access.
Network control is primary about controlling where and how users are
connecting at a low (network) level.

Your HTTP server should support the recommended versions of TLS (I believe
the SSL protocol is now totally deprecated and should be avoided, although
the term SSL is still commonly used to refer to TLS). I personally believe
it should just be assumed that TLS services are used by default. There's
not really any excuse not to use encrypted connections for any sort of
publicly available service over the Internet, even between two known
entities.

Moving further up the stack, we find authentication, authorization, and
accounting controls. There are two common ways to authenticate/authorize
web requests to microservices: via service account user/pass, or via an API
key/token that is given to those services. User/pass is common where a
human is directly controlling a local app that will consume those services
(and usually on an infrequent basis), and the API token is common where
there is no clear logical connection between a human and the request
(standalone services pulling data for reporting on a regular basis, etc.).
Sometimes the user credentials are only used to retrieve an API token, and
then that token is used for all API calls by an end-user application. Of
course, either method can be employed for most scenarios. Token
authentication will be a likely path for you.

Your microservices should not respond with anything other than error
messages unless the requester has validated credentials (unless you have
some API calls that are publicly accessible, in which case those calls
should succeed regardless of whether or not the requester provides
credentials). Each authentication type has it's own implementation strategy
and limitations, and will be determined by your HTTP server choice (if
using basic authentication via the HTTP server) and/or Django
authentication strategy. For example, Django REST Framework supports either
method (along with session authentication), and has library calls to
generate and assign API tokens to users, or can simply accept credential
logins (http://www.django-rest-framework.org/api-guide/authentication/).
Ensuring that your API consumers have the only copies of the tokens or user
credentials will definitely go a long way to achieve the protection you
desire, and may be your only option on a shared-host setup where you do not
have access to the HTTP server or host configuration. Use TLS whenever
possible (which should be for pretty much everything nowadays) to protect
the credentials and data transfer of the innocent.

Another note, these restrictions are heavily impacted by your consumers and
what their capabilities for connecting are. Do you have mobile users that
want to connect from anywhere in the world? Requirements like that tend to
leave network controls wide open, and you are limited to either requiring
your users to do extra work (VPN connection), and/or having them use one of
the authentication methods I mentioned.

Other more esoteric authentication/authorization methods exist (certificate
authentication, header inclusion requirements, proxies, etc.), but I'll be
here all night if I went into any sort of detail on those. ;-)

TL;DR; Lock things down with firewalls as much as possible, and look at
having non-public API resources protected by either user/pass or an API
token. All transactions should occur using SSL/TLS if credentials are
involved. There's little excuse nowadays for sites to not support SSL/TLS.
That should take care of 99% of the trouble.

Without a thorough examination of your intended infrastructure and
clientele, there isn't really a way to give you a more specific answer. If
this is really a concern and/or you are providing high-value data, I would
suggest hiring a web security consultant to recommend the best course(s) of
action.

Security is hard, and usually expensive. If it wasn't, everyone would be
doing it.

-James

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CA%2Be%2BciWSAFydb9-4%2BLHOOhn6wLSBDSw4uLskXJozbS_qRxXpXA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to