Authorization in ASP.NET MVC 4 - c#

I have a menu in web site. I want to access this for every role .
For example : i have 3 role that Role1 have access to personnel, referred, visit menu, and role2 have access to personnel, diet menu , and role3 have full access.
I created a static class that set value when user login in site. and use this class property for show/hide menu. but change this value when a nother user is login in site.
public static class GlobalVariables
{
public static string UserName { get; set; }
public static string Image { get; set; }
public static bool IsAuthorizePersonnel { get; set; }
public static bool IsAuthorizeReferred { get; set; }
public static bool IsAuthorizeDiet { get; set; }
public static bool IsAuthorizeVisit { get; set; }
}
How do i set access for menu ?

The static class is changing when new users login because ASP.NET handles multiple requests/clients in the same App domain, which means they share static classes/properties.
In order to make something like this work you would need to cache the information either via session state or a user keyed memory cache (such as Redis).
Alternatively, Asp.Net simple membership does have role support, so you could also consider creating the IsX properties as wrappers around role checks.
See the following articles for some examples:
http://www.asp.net/web-pages/overview/security/16-adding-security-and-membership
http://msdn.microsoft.com/en-us/library/5k850zwb%28v=vs.140%29.aspx
Hide link based on Role

Basically you have a single instance of the class which is used for all users in the site. Due to it being a static class.
You should create an instance-per-user class. Which you could place inside the cache under fi username.

Related

How to save username in global variable asp

I have online exam system I want to save username in global variable or any other thing that just can save it.
I want this username for get and set data on SQL database.
I'm using a global variable in class but it replace in every login.
any way to save username foreach user?
public class GVar
{
public static string user
{
get; set;
}
public static string mail
{
get;
set;
}
public static string melli
{
get;
set;
}
public static bool go
{
get;
set;
}
public static System.Threading.Thread thread { get; set; }
}
Use Application or Session as the case may be.
Session variables are global but limited to current session (call it user for understanding).
Application variables are globally shared across all sessions.
So, following statements may be used to get/set variables at application level
Application["user"] = "abc"; //sets the value at application level
var user = Application["user"]; //gets the value stored at application level
Similarly, to make it global, but isolate at session level,
Session["user"] = "abc"; //sets the value at session level
var user = Session["user"]; //gets the value stored at session level
EDIT
For ease of use, I prefer implementing them as properties, somewhat like this:
Define the class with custom getter/setter properties, and add it to App_Code folder
public static class GVar
{
public static string user
{
get { return Session["GVar_User"]; }
set { Session["GVar_User"] = value; }
}
//...
}
Use it in your application, as you would normally do with any other property.
GVar.user = "abc"; //set value
var usr = GVar.user; //get value
You can save it on login like this:
Session["user"] = "gamesdl";
And then you can get the value during executing like this:
String username = (string)(Session["user"]);
You can use claims.
The claims are in identity. And you can config then in login action.

Best way to do property level authorization in ServiceStack?

I'm currently developing a SPA in Angular, and so I've created a REST service using ServiceStack. I am also using ServiceStack's default authentication and authorization solution, which allows me to decorate services with the Authenticate attribute, and also allows me to authorize roles.
However, since my application has users, and users own resources, I need a way to restrict non-authorized users from performing certain actions. Furthermore, I would like to be able to create a single service for each discrete entity which can properly figure out what is safe to write to the database and what is safe to return to the user depending on their level of authorization.
So as an example, let's say I've created a service to handle operations on a Group entity. One of the actions I allow on a Group is to get the details for it:
Route: api/groups/{Id}
Response: Name, Description, CoverImageUrl, Members
However, depending on who the user is, I wish to restrict what data is returned:
Not authenticated: Name, CoverImageUrl
Authenticated: Name, CoverImageUrl, Decription
Member of requested group: Full access
Admin of website: Full access
So one simple approach to doing this is to create 3 different response DTOs, one for each type of response. Then in the service itself I can check who the user is, check on their relation to the resource, and return the appropriate response. The problem with this approach is that I would be repeating myself a lot, and would be creating DTOs that are simply subsets of the "master" DTO.
For me, the ideal solution would be some way to decorate each property on the DTO with attributes like:
[CanRead("Admin", "Owner", "Member")]
[CanWrite("Admin", "Owner")]
Then somewhere during the request, it would limit what is written to the database based on who the user is and would only serialize the subset of the "master" DTO that the user is permitted to read.
Does anyone know how I can attain my ideal solution within ServiceStack, or perhaps something even better?
The direct approach is the easiest, but you could also take advantage of custom filters attributes.
[Route("/groups/{Id}"]
public class UpdateGroup
{
public int Id { get; set; }
public string Name { get; set; }
public string CoverImageUrl { get; set; }
public string Description { get; set; }
}
[RequiresAnyRole("Admin", "FullAccess")]
[Route("/admin/groups/{Id}"]
public class AdminUpdateGroup
{
public int Id { get; set; }
public string Name { get; set; }
public string CoverImageUrl { get; set; }
public string Description { get; set; }
//... other admin properties
}
Service implementation:
public object Any(UpdateGroup request)
{
var session = base.SessionAs<AuthUserSession>();
if (session.IsAuthenticated) {
//.. update Name, CoverImageUrl, Description
}
else {
//.. only update Name, CoverImageUrl
}
}
public object Any(AdminUpdateGroup request)
{
//... Full Access
}
What ended up being the most pragmatic solution for me was actually pretty simple. The basic idea is that whichever service requires row-level authorization should implement a GetUserRole method, which in my case returns the user's most permissive role.
protected string GetUserRole(Domain.Group entity)
{
var session = SessionAs<AuthUserSession>();
var username = session.UserName;
if (session.Roles.Contains("Admin"))
{
return "Admin";
}
if (entity.Id == default(int) || entity.Leader.Username.Equals(username))
{
return "Leader";
}
// More logic here...
return session.IsAuthenticated ? "User" : "Anonymous";
}
Then I can use the user's role to figure out what to let them write:
var entityToWriteTo = ... // code that gets your entity
var userRole = GetUserRole(entityToWriteTo);
if (new[] {"Admin"}.Contains(userRole))
{
// write to admin-only entity properties
}
if (new[] {"Admin", "Leader"}.Contains(userRole))
{
// write to admin or leader entity properties
}
// Etc.
And the same logic applies for reads: You populate a DTO with properties set conditionally based on their role. Later on when you return the DTO back to the client, any properties that you haven't set either won't be serialized or will be serialized with a null value.
Ultimately, this solution allows you to use a single service for a resource instead of creating multiple services each with their own request DTO. There are, of course, refactorings you can do that makes this solution more streamlined. For example, you can isolate all of your reads and writes to one part of your code which will keep the services themselves free of role checks and things like that.

Granting an uber flexible user acess/modify rights system

I am developing an application where the client needs and extremely flexible user rights system. For example, a user should be able to have update rights in Form A but not in Form B (which prevents me from defining broad update rights). Admin should also be able to transfer specific rights to a user.
I was thinking of using the Command Pattern with CanExecute method but not really sure how I can use it in such a dynamic/specific way. Any suggestions ?
I have a similar situation in my application, which can be extended via plugins and the plugins can bring in their own permission. I solved that the following way:
static/common PermissionManager
very module/form/plugin can register its available permissions in the manager
the "permission manager UI" lists all available permissions and lets the admin assign them to users
on access every module/form/plugin asks the manager if the current user has the permission
Simplified class structure:
public class PermissionManager
{
public static Dictionary<string, IEnumerable<string>> AvailablePermissions { get; set; }
public static bool? Can(User user, string permission)
{
// check DB
return DENIED ? false : (ALLOWED ? true : null);
}
}
public class MyPlugin : IPlugin
{
public void Init()
{
PermissionManager.AvailablePermissions["MyPlugin"] =
new List<string>() { "Permission1", "Permission2" };
}
public void DoWork()
{
if (PermissionManager.Can(user, "Permission1") != true)
throw new NotAllowedException();
// do work
}
}
This is the basic patter I use. Of course you should use constants or similar for the permission names/keys. The admin UI can then iterate AvailablePermissions in the configuration UI.
In the DB I have something like the following (EF Code-First):
public class UserProfilePermissions
{
public UserProfile User { get; set; }
public Permission Permission { get; set; }
public bool IsAllowed { get; set; }
}
public class Permission
{
public int Id { get; set; }
public string Key { get; set; }
public string Group { get; set; }
}
So for every permission there is one Permission entry created (on the first assignment) in the DB and mapped via the mapping table using the IsAllowed to define "ALLOWED" or "DENIED".
The null value defines a not set permission so default values can be used (=> not set permission does not always say "DENIED").
The mapping table can also be used in the same style for e.g. roles.

Authentication by user

have scoured by couldn't find anything relevant.
I have to this point built a cool web app in MVC using C#. I created a User model as
public class User
{
// Must be named EntityNameId, must have primary key!
public int UserId { get; set; }
[DisplayName("First Name")]
public string firstName { get; set; }
[DisplayName("Last Name")]
public string lastName { get; set; }
[DisplayName("Cell Number")]
public string cellNumber { get; set; }
}
And as such have designed a profile/dashboard for each user
/User/Profile/1
Accessed by their id. Ive also got other sections such as a menu to edit items /Item/Index/1 which shows all items for that user etc. My code works etc to filter and populate those pages just for the user. To this point however I have not implemented any authentication. I would like to use the built in authentication tools through ApplicationServices and have done before with roles:
<Authorize(Roles:="Manager,Administrator")>
However I would like to limit pages to specific users who are logged in? I.e. /User/Profile/1 should only be accessible by that user etc. Rather than the roles they serve.
Does any one know how this could be done? I know this would likely mean tying the account controllers and user controllers together, not quite sure how to do this so that everything works the same? As app is basically finished, quite simple tho, but just requires authentication.
Just do a simple check at the top of the action method, if it's not the current user, perform the redirect.
public ActionResult Profile(int id)
{
if (CurrentUser.Id != id)
{
return RedirectToAction("Index");
}
return View();
}
If you use it a lot, you could refactor it out into a method.
A secondary option would be to not even pass the user Id into the controller/action method, just grab the logged in user's Id and get the information from there.
[Authorize]
public ActionResult Profile()
{
return View(profileService.GetUserProfile(CurrentUser.Id));
}

C# some sort of plugin system

I am a mobile web developer and trying to monetize my traffic with mobile ad services and i have a problem.
First of all to get most of out of your ads you usually need to do server side request to advert company's servers and there are quite few ad services. Problem starts when you want to use them in one site.
All have different approaches to server side calls and trying to maintain and implement those ad codes becomes pain after a while.
So I decided to write a class system where i can simply create methods for every company and upload it to my site.
So far i have
public Advert class
public AdPublisher class with GetAd method that returns an Advert
public Adservice class that has Service names as enum
I also have converted server request codes of all ad services i use to classes.
It works ok but I want to be able to create an ad service class upload it so that asp.net app can import/recognize it automatically like a plugin system.
As I am new to .net I have no idea where to start or how to do it.
To make thing clear here are my classes
namespace Mobile.Publisher
{
public class AdPublisher
{
public AdPublisher()
{
IsTest = false;
}
public bool IsTest { get; set; }
public HttpRequest CurrentVisitorRequestInfo { get; set; }
public Advert GetAd(AdService service)
{
Advert returnAd = new Advert();
returnAd.Success = true;
if (this.CurrentVisitorRequestInfo == null)
{
throw new Exception("CurrentVisitorRequestInfo for AdPublisher not set!");
}
if (service == null)
{
throw new Exception("AdService not set!");
}
if (service.ServiceName == AdServices.Admob)
{
returnAd.ReturnedAd = AdmobAds("000000");
}
return returnAd;
}
}
public enum AdServices
{
Admob,
ServiceB,
ServiceC
}
public class Advert
{
public bool Success { get; set; }
public string ReturnedAd { get; set; }
}
public partial class AdService
{
public AdServices ServiceName { get; set; }
public string PublisherOrSiteId { get; set; }
public string ZoneOrChannelId { get; set; }
}
private string AdmobAds(string publisherid)
{
//snip
return "test"
}
}
Basically i want to be able to add another ad service and code like
private string AdmobAds(string publisherid){
}
So that it can be imported and recognised as ad service.
I hope i was clear enough
Ths seems like a pretty vague/general question, and considering you mentioned you're no too familiar with .NET, I thought I'd point you in the direction of the Managed Extensibility Framework. This is an official Micrsoft library designed for creating plugin/add-in systems (it's like a specialised Inversion of Control framework). Note that in .NET 4.0, it's actually part of the framework base class library. There's also a great MSDN page on Add-ins and Extensibility - relating to the System.AddIn namespace - which you may find pretty helpful too.
You can load assemblies dynamically, then query the list of classes and check whether the class is derived from your interface. Check the "Assembly" class.

Categories