Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save scorpio-angel/2dbdc56370f62233f2b290a08fb7e319 to your computer and use it in GitHub Desktop.
Save scorpio-angel/2dbdc56370f62233f2b290a08fb7e319 to your computer and use it in GitHub Desktop.
Role-Based-Access-Control Authorization Logic based on ASP.NET Identity and System.Runtime.Caching.MemoryCache
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net.Http;
using System.Runtime.Caching;
using System.Web.Http;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Server.Identity.Models;
[Authorize]
[RoutePrefix("api/Authorization")]
public class AuthorizationController : ApiController
{
[HttpPost]
[Route("Authorize")]
[ActionName("Authorize")]
public IHttpActionResult Authorize(PermissionRequest permissionRequest)
{
var policy = new CacheItemPolicy
{
SlidingExpiration = new TimeSpan(1, 0, 0)
};
var db = this.Request.GetOwinContext().Get<SecurityDbContext>();
var cache = MemoryCache.Default;
bool containsRoles = cache.Contains("Roles");
List<ApplicationRole> roles;
if (containsRoles)
{
roles = cache.GetCacheItem("Roles")?.Value as List<ApplicationRole>;
}
else
{
roles = db.Roles.ToList().Select(x => new ApplicationRole(x.Name) { Id = x.Id }).ToList();
bool addedRoles = cache.Add("Roles", roles, policy);
}
List<ApplicationUser> users;
bool containsUsers = cache.Contains("Users");
if (containsUsers)
{
users = cache.Get("Users") as List<ApplicationUser>;
}
else
{
users = db.Users.ToList().Select(
x => new ApplicationUser()
{
UserName = x.UserName,
RoleName = x.RoleName,
Id = x.Id,
ShopId = x.ShopId,
IsActive = x.IsActive,
}).ToList();
bool addedUsers = cache.Add("Users", users, policy);
}
List<ApplicationPermission> permissions;
bool containsPermissions = cache.Contains("Permissions");
if (containsPermissions)
{
permissions = cache.Get("Permissions") as List<ApplicationPermission>;
}
else
{
permissions = db.Permissions.Include(x => x.Role).Include(x => x.Resource).ToList().Select(
x => new ApplicationPermission()
{
Id = x.Id,
Resource = x.Resource,
IsAllowed = x.IsAllowed,
RoleId = x.RoleId,
ResourceId = x.ResourceId,
Role = x.Role,
IsDisabled = x.IsDisabled
}).ToList();
bool addedPermissions = cache.Add("Permissions", permissions, policy);
}
string userId = this.User.Identity.GetUserId();
ApplicationUser user = users.First(x => x.Id == userId);
var any = permissions.Any(
x => x.Role.Name == user.RoleName && x.Resource.Name == permissionRequest.Name && x.IsAllowed);
return any ? (IHttpActionResult)this.Ok() : this.Unauthorized();
}
}
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
[TestClass]
public class AuthorizationServerTest
{
string bizbookserveridentity = "http://localhost:61923/";
string adminDemo1Username = "[email protected]";
string adminDemo1Pass = "";
HttpClient client;
[TestInitialize]
public void Setup()
{
this.client = new HttpClient();
}
[TestMethod]
public void GetIdentityValueTestMethod()
{
string url = this.bizbookserveridentity + "api/values/getvalue";
var result = this.client.GetAsync(url).Result;
Assert.IsTrue(result.StatusCode == HttpStatusCode.OK);
}
[TestMethod]
public void GetIdentityTokenReturnsAppropriateData()
{
HttpResponseMessage message = this.RequestToken(this.adminDemo1Username, this.adminDemo1Pass);
bool b = message.StatusCode == HttpStatusCode.OK;
Assert.IsTrue(b);
string content = message.Content.ReadAsStringAsync().Result;
dynamic responseObject = JsonConvert.DeserializeObject<dynamic>(content);
Assert.IsNotNull(responseObject.role);
Assert.AreEqual("ShopAdmin", responseObject.role.ToString());
}
[TestMethod]
public void GetIdentityAuthorizationFailWithoutBearerToken()
{
string url = this.bizbookserveridentity + "api/Authorization/Authorize";
var unAuthorizedResult = this.client.GetAsync(url).Result;
Assert.AreEqual(HttpStatusCode.Unauthorized, unAuthorizedResult.StatusCode);
}
[TestMethod]
public void GetIdentityAuthorizationSuccessWithBearerToken()
{
string url = this.bizbookserveridentity + "api/Authorization/Authorize";
this.SetTokenToHttpHeader(this.adminDemo1Username, this.adminDemo1Pass);
var request = new PermissionRequest() { Name = "side-menu-employee" };
var authorizedResult = this.client.PostAsJsonAsync(url, request).Result;
Assert.AreEqual(HttpStatusCode.OK, authorizedResult.StatusCode);
}
private void SetTokenToHttpHeader(string username, string password)
{
string result = this.RequestToken(username, password).Content.ReadAsStringAsync().Result;
dynamic tokenObject = JsonConvert.DeserializeObject<dynamic>(result);
this.client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", tokenObject.access_token.ToString());
}
private HttpResponseMessage RequestToken(string adminDemo1Com, string adminDemo1Pass)
{
var url = this.bizbookserveridentity + "token";
var nameValueCollection = GetNameValueCollection(adminDemo1Com, adminDemo1Pass);
var formUrlEncodedContent = new FormUrlEncodedContent(nameValueCollection);
var message = this.client.PostAsync(url, formUrlEncodedContent).Result;
return message;
}
private static List<KeyValuePair<string, string>> GetNameValueCollection(string adminDemo1Com, string adminDemo1Pass)
{
var nameValueCollection = new List<KeyValuePair<string, string>>();
var username = new KeyValuePair<string, string>("username", adminDemo1Com);
var password = new KeyValuePair<string, string>("password", adminDemo1Pass);
var grant_type = new KeyValuePair<string, string>("grant_type", "password");
nameValueCollection.Add(username);
nameValueCollection.Add(password);
nameValueCollection.Add(grant_type);
return nameValueCollection;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment