I\'m developing an Asp.net MVC + Web API + AngularJS SPA. I would like to have several types of registration/authentication:
By no means am I familiar with Microsoft backends, but still I'll give it a try ;-) :
Good resources on how the authentication/authorisation should be done in Angular-based SPA:
https://github.com/fnakstad/angular-client-side-auth
live demo: http://angular-client-side-auth.herokuapp.com/login
Good ng-conf talk on how authorisation is done in Google Doubleclick Manager application: http://www.youtube.com/watch?v=62RvRQuMVyg&t=2m29s
It's not quite what you want (authentication), but the solution begins to kick in on the authentication phase. Furthermore it may be useful later and the approach Ido is presenting seems really sound.
Slides: https://docs.google.com/file/d/0B4F6Csor-S1cNThqekp4NUZCSmc/edit
Last but not least: Mastering Web Application Development with AngularJS.
A brilliant Angular book by Paweł Kozłowski and Pete Bacon Darwin.
It has a whole chapter or two dedicated to auth- stuff. It shows some complex solutions, such as retrial and session-expired interceptors. But even if you will not use approaches from the book directly, those chapters are still a must-reads since they may give you an inspiration for devising your own auth- solutions.
Remark - http-auth-interceptor
: As it is mentioned in the book, the securityInterceptor
solution was originally invented by Witold Szczerba. See the blog post.
http-auth-interceptor
code, mentioned by @CorySilva, is actually sample code to concepts explained in the post.
btw: Those 2 chapters are great, but I hope that the Community comes up with some easier solutions in the future. Every time I read this interceptor promise api
-based code I get a severe headache :)
btw2: If somebody doesn't consider oneself an Angular expert, the entire book is definetly a must-read and great complement after reading the Guide
As for building the login page with ASP - I suggest using ASP only as a backend and middleware and drawing whole the app with Angular.
You can start with your approach and switch to the pure-Angular SPA if it will begin to require more and more crazy hacks to make technologies play together nicely.
But I might be wrong and this particular case won't require applying any hacks.
I can only comment on my own experience, maybe it is helpful. We use the same stack as you, Asp.net MVC + Web API + AngularJS. We use server-side MVC for authentication (Microsoft.AspNet.Identity), since we are not exposing a public API at this stage and the only consumer of the API will be our SPA this works perfectly with the least amount of effort.
This also enables us to set a UserContext Angular service on the server once logged in that can be shared through your entire Angular app, the Google Doubleclick Manager guys goes into some of the benefits of this approach during there ng-conf presentation. Since Web Api supports Asp.Net Identity, authentication and authorization works seamlessly between MVC and Web Api.
To sum up the major pros and cons:
Pros:
Cons:
So in short, the MVC view that we use to bootstrap our SPA is protected with [Authorize] as well as our Web Api methods. Inside the MVC view we also initialize our UserContext Angular service using Razor to inject whatever user properties we want to expose. Once the SPA is loaded via the single Razor view, everything else is handled via Angular.
We have used what Beyers described before and it works well for most apps, and I use it frequently.
In our current application we are working on the premise that separation of concern should apply to route management.
Normal lifecycle:
Angular Ctrl structure:
index.html
<body>
<!-- I am a fullscreen login element, z-index=2000-->
<div data-ng-controller="LoginCtrl" data-ng-hide="isAuthenticated()"</div>
<div data-ng-controller="ContentCtrl">
<!-- fullscreen class has a z-index=2001 -->
<section data-ng-view data-ng-class="{fullscreen: isViewPublic()}"></section>
<!-- header and nav go here -->
</div>
</body>
We could get a little more creative on how display the public views/routes but you get the idea. We only have a few public routes and they are mainly for registration, password resets, etc.
Disclaimer: I have yet to integrate with and oauth/external authentication services. Hopefully this setup will still hold water.
Any critique of this process is welcome.