Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices for authentication and authorization in Angular without breaking RESTful principles?

I've read quite a few SO threads about authentication and authorization with REST and Angular, but I'm still not feeling like I have a great solution for what I'm hoping to do. For some background, I'm planning to building an app in AngularJS where I want to support:

  1. Limited guest access
  2. Role-based access to the application once authenticated
  3. Authentication via APIs

All of the calls to the REST API will be required to occur over SSL. I'd like to do build the app without breaking RESTful principles, namely not keeping session state stored on the server. Of course, whatever is done vis-a-vis authorization on the client-side has to be reinforced on the server side. Since we need to pass the entire state with each request, I know I need to pass some sort of token so that the backend server receiving the REST request can both authenticate and authorize the call.

With that said, my main question is around authentication - what are the best practices here? It seems there are lots of different approaches discussed, here's just a few that I've found:

  • http://broadcast.oreilly.com/2009/12/principles-for-standardized-rest-authentication.html
  • http://frederiknakstad.com/2013/01/21/authentication-in-single-page-applications-with-angular-js/
  • http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html

There was a similar question asked (AngularJS best practice application authentication), but unless I'm misunderstanding the answer, it seems to imply that a server session should be used, which is breaking RESTful principles.

My main concern with the Amazon AWS and the George Reese article is it seems to assume that the consumer is a program, rather than an end user. A shared secret can be issued to a programmer in advance, who can then use it to encode calls here. This isn't the case here - I need to call the REST API from the app on behalf of the user.

Would this approach be enough? Let's say I have a session resource:

POST /api/session

Create a new session for a user

To create a session, you need to POST a JSON object containing the "username" and "password".

{     "email" : "[email protected]",     "password" : "password" } 

Curl Example

curl -v -X POST --data '{"username":"[email protected]","password":"password"}' "https://app.example.com/api/session" --header "Content-Type:application/json" 

Response

HTTP/1.1 201 Created {     "session": {         "id":"520138ccfa4634be08000000",         "expires":"2014-03-20T17:56:28+0000"     } } 

Status Codes

  • 201 - Created, new session established
  • 400 - Bad Request, the JSON object is not valid or required information is missing
  • 401 - Unauthorized, Check email/password combo
  • 403 - Access Denied, disabled account or license invalid

I'm leaving out the HATEOAS details for clarity. On the backend, there would be a new, limited duration session key created and associated with the user. On subsequent requests, I could pass this as part of the HTTP headers:

Authorization: MyScheme 520138ccfa4634be08000000  

Then the backend servers would be responsible for digesting this out of the request, finding the associated user and enforcing authorization rules for the request. It should probably update the expiration for the session as well.

If all this is happening over SSL, am I leaving the door open to any kind of attacks that I should be protecting against? You could try to guess session keys and place them in the header, so I suppose I could additionally append a user GUID to the session key to further prevent brute force attacks.

It's been a few years since I've actively programmed and I'm just getting back into the swing here. Apologies if I'm being obtuse or unnecessarily reinventing the wheel, just hoping to run my ideas by the community here based on my reading thus far and see if they pass the litmus test.

like image 684
austrum Avatar asked Mar 18 '14 18:03

austrum


People also ask

What is correct for authentication and authorization in Angular?

Angular Interview Q & A series Authentication is very important process in the system with respect to security. Authorization is the process of giving permission to the user to access certain resource in the system. Only the authenticated user can be authorised to access a resource.

What is difference between authentication and authorization in REST API?

So, what is the difference between authentication and authorization? Simply put, authentication is the process of verifying who someone is, whereas authorization is the process of verifying what specific applications, files, and data a user has access to.

How does authorization work in Angular?

When your users need to log in, your Angular application triggers an authentication event, which it handles by redirecting them to a customizable Auth0 login page. Once your users log in successfully, Auth0 redirects them back to your Angular application, returning tokens with their authentication and user information.


2 Answers

When someone asks about REST authentication, I defer to the Amazon Web Services and basically suggest "do that". Why? Because, from a "wisdom of the crowds" point of view, AWS solves the problem, is heavily used, heavily analyzed, and vetted by people that know and care far more than most about what makes a secure request than most. And security is a good place to "not reinvent the wheel". In terms of "shoulders to stand on", you can do worse than AWS.

Now, AWS does not use a token technique, rather it uses a secure hash based on shared secrets and the payload. It is arguably a more complicated implementation (with all of its normalization processes, etc.).

But it works.

The downside is that it requires your application to retain the persons shared secret (i.e. the password), and it also requires the server to have access to that a plain text version of the password. That typically means that the password is stored encrypted, and it then decrypted as appropriate. And that invite yet more complexity of key management and other things on the server side vs secure hashing technique.

The biggest issue, of course, with any token passing technique is Man in the Middle attacks, and replay attacks. SSL mitigates these mostly, naturally.

Of course, you should also consider the OAuth family, which have their own issues, notably with interoperability, but if that's not a primary goal, then the techniques are certainly valid.

For you application, the token lease is not a big deal. Your application will still need to operate within the time frame of the lease, or be able to renew it. In order to do that it will need to either retain the user credential or re-prompt them for it. Just treat the token as a first class resource, like anything else. If practical, try and associate some other information with the request and bundle it in to the token (browser signature, IP address), just to enforce some locality.

You are still open to (potential) replay problems, where the same request can be sent twice. With a typical hash implementation, a timestamp is part of the signature which can bracket the life span of the request. That's solved differently in this case. For example, each request can be sent with a serial ID or a GUID and you can record that the request has already been played to prevent it from happening again. Different techniques for that.

like image 175
Will Hartung Avatar answered Sep 22 '22 06:09

Will Hartung


Here is an incredible article about authentication and login services built with angular.

https://medium.com/opinionated-angularjs/7bbf0346acec

like image 33
Sten Muchow Avatar answered Sep 22 '22 06:09

Sten Muchow