Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
AngularJS Windows Authentication Service using .NET Web API and Hot Towel template
angular.module('app')
.factory("authentication", ["$http", "$q", "$window", authentication]);
function authentication($http, $q, $window) {
var user;
function login() {
// check if the user already exists for this session
if (user) {
return $q.when(user); // resolve with given value, necessary because calling function expects a promise.
}
var url = 'api/users/current/';
return $http.get(url).then(function (result) {
var result = result.data;
user = {
id: result.UserId,
displayName: result.DisplayName,
guid: result.ADGuid,
isAdmin: result.IsAdmin
};
addUserToStorage();
console.log("user created.");
return $q.when(user);
});
}
function addUserToStorage() {
$window.sessionStorage["user"] = JSON.stringify(user);
}
function getUser() {
return user;
}
function init() {
if ($window.sessionStorage["user"]) {
user = JSON.parse($window.sessionStorage["user"]);
}
}
init();
return {
user: user,
init: init,
addUserToStorage: addUserToStorage,
login: login,
getUser: getUser
};
};
(function () {
'use strict';
var controllerId = 'base';
angular.module('app')
.controller(controllerId, ['common', 'authentication', base]);
function base(common, authentication) {
var vm = this;
// local vm.user object for use with topnav.html to display logged in user name
vm.user = { displayName: "..." };
activate();
function activate() {
common.activateController([login()], controllerId);
}
function login() {
return authentication.login().then(function (data) {
vm.user = data;
});
}
}
})();
// in the controllers, we can get the current user by deferring to authentication service
(function () {
'use strict';
var controllerId = 'sales';
angular.module('app')
.controller(controllerId, ['$q', 'common', 'authentication', sales]);
function sales($q, common, authentication)
{
// ...
// each controller has a call to getUser(), which defers to the authentication service for auth status
var vm = this;
vm.user = {};
activate();
function activate() {
// call the getUser promise
common.activateController([getUser()], controllerId)
.then(function () { });
}
function getUser() {
return authentication.login().then(function(data) {
vm.user = data;
return $q.when(data);
});
}
// ...
}
})();
<nav class="navbar navbar-fixed-top navbar-inverse">
<div class="navbar-header">
<a href="/" class="navbar-brand">
<span class="brand-title">
...
</span>
</a>
<a class="btn navbar-btn navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
</div>
<div class="navbar-collapse collapse" >
<div class="pull-right navbar-logo" data-ng-controller="base as vm">
<ul class="nav navbar-nav pull-right">
<li>
<a href="\">
Welcome, {{ vm.user.displayName }}
</a>
</li>
<li>
<a href="\">
</a>
</li>
<li class="dropdown dropdown-big">
<a href="http://localhost:20293/Help" target="_blank">Help</a>
</li>
</ul>
</div>
</div>
</nav>
public class User
{
public int UserId { get; set; }
public string DisplayName { get; set; }
public string ADGuid { get; set; }
public bool IsAdmin { get; set; }
}
public class UserFactory
{
private readonly IQwDbContext db = new QwDbContext();
public User Create(WindowsIdentity currentWindowsUser)
{
var user = new User();
string name = currentWindowsUser.Name.Replace("DOMAIN\\", "");
// a much simplified case for example (better to retrieve by GUID)
User userInDatabase = (from u in db.Users
where u.FirstName.ToLower() + u.LastName.ToLower() == name.ToLower()
select u).FirstOrDefault();
if (userInDatabase != null)
{
user.UserId = userInDatabase.UserId;
user.DisplayName = userInDatabase.DisplayName;
user.IsAdmin = userInDatabase.IsAdmin;
user.ADGuid = userInDatabase.ADGuid;
}
return user;
}
}
[RoutePrefix("api/users")]
public class UsersController : ApiController
{
/// <summary>
/// Gets the currently logged in user account in AD as a User object
/// </summary>
/// <returns></returns>
[Route("current/")]
public User GetCurrentUser()
{
User user = new UserFactory().Create(WindowsIdentity.GetCurrent());
return user;
}
}

mlauser commented Nov 13, 2014

I'm new to angular, so I'm having some troubles implementing this. I have the code in place in my Hot Towel project, and there are no errors, but the UserController is not invoked when I run it, and no user name is displayed. The UserController works when called directly using the URL, so it seems that the angular code is not trying to access it. I am loading all of the .js references in index.html, and verified that they are loaded successfully using Fiddler. Do I need to add a call somewhere in the angular code to invoke GetUser?

Owner

danbergman commented Feb 23, 2015

Hi mlauser, sorry for the long delay...you most likely found a solution already, nevertheless I simplified the gist to be more clear and to include an example of a call to getUser() in the controllers activation method.

Krudo commented Jul 16, 2015

Hi danbergman,
Great job, very clear and easy to understand!!
10X

I have been searching for this concise and simple solution for a long time. Well done!

MashB commented Nov 9, 2015

Nice and clear explanation. I implemented and ran locally it works as expected. But when I deploy to IIS as two separate website ( WebAPI and AngularJS ) , now I get identity as IIS hosted account and not the User account.
Can you give me hint how can I achieve the same on deployment.

shkup commented Dec 7, 2015

Shouldn't you use interceptor service for authentication?

Nice and clear explanation. I implemented and ran locally it works as expected. But when I deploy to IIS as two separate website ( WebAPI and AngularJS ) , now I get identity as IIS hosted account and not the User account.
Can you give me hint how can I achieve the same on deployment.

The same here , how can i use that for Production

after looking at node-activedirectory and ldapjs this is probably the best solution. otherwise go back to asp.net mvc stack.

type or namespace name DbContext could not be found

davidjefferson commented May 16, 2017 edited

What is this common? My angular always returns Unknown provider: commonProvider <- common.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment