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

This comment has been minimized.

Show comment Hide comment
@mlauser

mlauser 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?

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?

@danbergman

This comment has been minimized.

Show comment Hide comment
@danbergman

danbergman 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.

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

This comment has been minimized.

Show comment Hide comment
@Krudo

Krudo Jul 16, 2015

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

Krudo commented Jul 16, 2015

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

@swizzmagik

This comment has been minimized.

Show comment Hide comment
@swizzmagik

swizzmagik Aug 1, 2015

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

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

@MashB

This comment has been minimized.

Show comment Hide comment
@MashB

MashB 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.

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

This comment has been minimized.

Show comment Hide comment
@shkup

shkup Dec 7, 2015

Shouldn't you use interceptor service for authentication?

shkup commented Dec 7, 2015

Shouldn't you use interceptor service for authentication?

@tobiashoeft

This comment has been minimized.

Show comment Hide comment
@tobiashoeft

tobiashoeft Mar 18, 2016

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

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

@mgonzales3

This comment has been minimized.

Show comment Hide comment
@mgonzales3

mgonzales3 Sep 5, 2016

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

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

@VCS-Deepak

This comment has been minimized.

Show comment Hide comment
@VCS-Deepak

VCS-Deepak Sep 14, 2016

type or namespace name DbContext could not be found

type or namespace name DbContext could not be found

@davidjefferson

This comment has been minimized.

Show comment Hide comment
@davidjefferson

davidjefferson May 16, 2017

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

davidjefferson commented May 16, 2017

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