Instantly share code, notes, and snippets.
Forked from foyzulkarim/AuthorizationController.cs
Created
December 14, 2018 12:45
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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