Authorization in ASP.Net MVC using XML Configuration.

 

Authorization in ASP.Net MVC using XML Configuration.

Download Source Code

Doing authorization in a clean way is always tricky, You want a delicate balance between an extreme abstraction and something like embedding roles in-side your compiled code, I have always preferred simple abstraction either using roles and their corresponding mappings in the database or using simple xml file to store action to role mappings.

Asp.net MVC comes with built in Authorization filter attribute that you can use on your Controller and Action to define the role that can access corresponding Controller or Action. This approach will work fine for small application where you have predefined action to role mappings, but when you have bigger application where developers are not going to define role mappings and mappings might change frequently then maintenance of hard quoted roles might become nightmare.

I have created simple application to demonstrate how you can xml based configuration to apply authorization in MVC application. Following are four major pieces of the application.

  • ConfigurationSectionHandler for defining XML Configuration for Controller and Action to role mapping.
  • IMVCAuthorizer Interface and implementation MCVXMLAuthorizer.
  • HttpModule which plugs into AuthorizeRequest event to validate if user are authorized to access Controller and Action.
  • Sample MVC application to test XMLAuthorizer.

Defining XML and Configuration Section.

Following is the XML structure that defines Controller and Action to role mappings, As you can see Controller and Actions can have their own set of roles. Empty Home Controller section means everybody has access to Controller and all Actions.

As you can also see in first controller node Admin, Edit and View roles have access to Admin Controller but access to Edit and Admin action if limited to specific roles only.

< controllers >
  
< controller  name ="Admin">
    
< roles >
      
< role > Admin </ role >
      
< role > Edit </ role >
      
< role > View </ role >
    
</ roles >
    
< actions >
      
< action  name ="Index">
        
< roles >
          
< role > Admin </ role >
          
< role > Edit </ role >
          
< role > View </ role >
        
</ roles >
      
</ action >
      
< action  name ="Edit">
        
< roles >
          
< role > Edit </ role >
          
< role > Admin </ role >
        
</ roles >
      
</ action >
      
< action  name ="Admin">
        
< roles >
          
< role > Admin </ role >
        
</ roles >
      
</ action >
    
</ actions >
  
</ controller >
  
< controller  name ="Home"> </ controller >
</ controllers >  


Configuration Section handler has two important properties 1) Type which defines fully qualified type name of class implements IXMLAuthorizer interface and 2) ConnectionString which in our case is the path of XMLConfiguration file, additionally It also has static GetSettingsMethod which returns current settings from Web.Config file.

public class  AuthorizationMappingSection : IConfigurationSectionHandler {

        
public object  Create( object  parent,  object  configContext, System.Xml.XmlNode section) {
            
// Create an instance of XmlSerializer based on the RewriterConfiguration type...
            
XmlSerializer ser  = new  XmlSerializer( typeof (AuthorizationMappingSection)) ;

            
// Return the Deserialized object from the Web.config XML
            
return  ser.Deserialize( new  XmlNodeReader(section)) ;
        
}

        
public static  AuthorizationMappingSection GetSettings() {
            
if  (HttpContext.Current.Cache[ "AuthorizationMappingSection" == null ) {
                AuthorizationMappingSection settings
                    
(AuthorizationMappingSection)ConfigurationManager.GetSection( "AuthorizationMappingSection" ) ;

                
HttpContext.Current.Cache[ "AuthorizationMappingSection" settings ;
            
}

            
return  ((AuthorizationMappingSection)HttpContext.Current.Cache[ "AuthorizationMappingSection" ]) ;
        
}

       [XmlAttribute(
"type" )]
        
public string  Type {  get; set;  }

        [XmlAttribute(
"connectionString" )]
        
public string  ConnectionString {  get; set;  }
}


IMVCAuthorizer and MCVXMLAuthorizer Implementation.

IMVCAuthorizer interface has two methods, 1) IsAuthorized which takes controllerName and actionName and Principle object. And 2) Initialize methods which takes connection string.


public interface  IMVCAuthorizer {
     
       
bool  IsAuthorized( string  controllerName,  string  actionName, System.Security.Principal.IPrincipal user) ;
 
       void 
Initilize( string  connectionString) ;
}


MCVXMLAuthorizer implements IMVCAuthorizer, In Initialize method it reads XML file and de-serialize it into ControllerAuthorizationInfoCollection class, as you can see it puts de-serialize object into cache and puts dependency on physical file so any time some body changes the file cache will be invalidated.

IsAuthorized is the method that contains logic to check authorization against XML configuration you can download the source code if you want to go deeper into logic inside  ControllerAuthorizationInfoCollection class.


public class  MCVXMLAuthorizer:IMVCAuthorizer {

       ControllerAuthorizationInfoCollection controllers 
= null;

       public bool 
IsAuthorized( string  controllerName , string  actionName, System.Security.Principal.IPrincipal user) {
            
return  controllers.CanAccessAction(controllerName,actionName, user) ;
        
}

        
public void  Initilize( string  connectionString) {
            
string  key  "MCVXMLAuthorizerCacheKey" ;

            if 
(HttpContext.Current.Cache[key] ! = null ) {
                controllers 
(ControllerAuthorizationInfoCollection)HttpContext.Current.Cache[key] ;
           
else  {
                
string  path  HttpContext.Current.Server.MapPath(connectionString) ;
                
controllers  getControllerAuthorizationInfoCollection(path) ;
                
HttpContext.Current.Cache.Insert(key, controllers,  new  System.Web.Caching.CacheDependency(path)) ;
            
}
        }

        
private  ControllerAuthorizationInfoCollection getControllerAuthorizationInfoCollection( string  path) {
            ControllerAuthorizationInfoCollection rVal 
= null;           
            
XmlSerializer ser  = new  XmlSerializer( typeof (ControllerAuthorizationInfoCollection)) ;

            using 
(FileStream fs  File.OpenRead(path)) {
                rVal 
(ControllerAuthorizationInfoCollection)ser.Deserialize(fs) ;
            
}
            
return  rVal ;
        
}
    }

HttpModule

AuthorizationMappingModule is an HttpModule which hooks into AuthorizedRequest event of page life cycle and check is user has access to particular controller and action, if user does not have privilege to access then it will throw Security Exception.

void  OnAuthorizeRequest( object  sender, EventArgs e) {
            HttpContext context 
((HttpApplication)sender).Context ;
            
RouteData routeData  RouteTable.Routes.GetRouteData( new  HttpContextWrapper(context)) ;

            if 
(routeData ! = null ) {
                
string  controller  routeData.GetRequiredString( "controller" ) ;
                string 
action  routeData.GetRequiredString( "action" ) ;
                
IMVCAuthorizer authorizer  GetMVCAuthorizer() ;

                if 
(!authorizer.IsAuthorized(controller, action, context.User)) {
                    
string  message  = string .Format( "User {0} does not have permission to access {1} on {2}"
                        
, context.User.Identity.Name, action, controller) ;

                    
System.Diagnostics.Trace.TraceInformation(message) ;
                    throw new 
SecurityException(message) ;
                
}
            }
   }

Sample MVC Application to test Authorization.

I have created a simple MVC application with two Controllers, Controller that we are going to test is Admin Controller, I have also simple UI in Home Controller which allows you to login as an different user and try to access different links. As an-authenticated user you should not have access to any actions on Admin Controller and as you switch your role by clicking different login links your permission will change. following is the screen shot of application.



You will need to add reference to MVCAuthorization.dll and following configuration section handler and http module settings in your web.config file.
 


Next Steps,

If you are planning to store mappings in database you can easily create your own implementation of MVCSQLAuthorizer and plug into Web.config file.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值