SQL role security + custom ASP.Net base page - c#

I'm workng on a new, green-field ASP.Net application. We're implementing a base page which all pages will be, er, based on. The application will be running under Integrate Windows Auth, so I'll have the user's account details. With these, I'll be going to several databases (in which the user will exist) to find out what roles they are assigned to in each db. I'll be holding the role yay/nay in a bool array, and key into it via an enum.
There will be a session object that will hold a few things, and the roles assigned for that user. I'm thinking of making the session object available as a property of the base page, as the code would be something like this:
public SessionObject MasterSessionObject
{
get
{
if (Session["SessionObject"] == null)
{
// Create session object, assign user name, etc.
// Do something with roles...
Session["SessionObject"] = sessionObject;
}
return (SessionObject)Session["SessionObject"]
}
}
In order to control what happens on the (sub-classed) page, I want to provide a CheckSecurity method - e.g. if the user is not authorised to a certain part of a page, it can be hidden / disabled, or they could be booted back to a "not yours" page. The logical place for it is the base page, but seeing as the base page is already exposing the SessionObject that holds the roles permissions, would it not make more sense to Create a DatabaseSecurity type object and have the check on that?
Dealing with the latter approach, I've used abstract base classes to get me so far: I have a DatabaseRoles abstract class which contains the bool array, and a method to retrieve the roles for the user. The concrete implementation holds an Enum (as previously mentioned) to key into the array (in the base class). The abstract class also has the CheckRole method which takes in an int, to which I'm intending use a cast of the enum...
The SessionObject contains several of these DatabaseRoles implementations, and essentially does away with the need for a CheckSecurity in the base page class, leading to code like this in the actual page:
if (MasterSessionObject.SampleDatabaseRoles.Check((int)SampleDatabaseRolesEnum.RoleView))
{
// Do something
}
But, I'm sure you'll agree, it looks sucky...
If there was a CheckSecurity method on the base page, it would have to take a concrete DatabaseRoles object, but also an enum of which role to check, which would also look sucky. And finally, there would be a requirement at a later date to add more databases and their security settings...
I'll add code tomorrow if required... :-s
I dunno, I'm not that thick, but I do have a hard time sometimes binding all this together...
Thank you,
Mike K.

IF you happen to use ASP.Net / ASP.Net MVC, I would say the best place to do this would be via a custom HTTP Module by handling the AuthenticateRequest method & continuing with the request only if the request has been authenticated. There are tons of excellent articles online for this code.
Also - have a look at the Roles & Memberships of ASP.Net - it is pretty good & generally satisfies most requirements or you are always free to extend it. Again - tons of articles on custom membership providers...
unless I am missing something - HTH.

Related

ASP.NET WebAPI - how to create an abstract layer for multiple services

Alright, so assuming I am making a fancy web store.
I have a payment provider (say, paypal) which requires the user to sign into paypal website, confirm the credentials and then to redirect him into my website.
So basically the code behind that would look like this:
class PaymentManager
{
public string AcceptPayment(Payment payment)
{
//return redirect url
}
public bool ConfirmPayment(string paymentToken)
{
//if token is valid the payment succeded
}
}
So basically the usage of this manager from my controller maps into 2 controller methods (each requiring an individual request).
Now, assuming I have a different payment manager, which requires 3 methods being sequentially executed instead of 2. Something like:
class AnotherPaymentManager
{
public string AcceptPayment(Payment payment)
{
//return validation redirect url
}
public string ValidatePayment(string validationCode)
{
//return redirect url
}
public bool ConfirmPayment(string paymentToken)
{
//if token is valid, confirm payment
}
}
Now this class' usage maps into 3 controller methods (we need the client to execute the Accept method to declare payment, then to execute the Validate method to validate it and after all to execute the Confirm method to make sure the server has accepted it).
The question is: provided these managers have different API usage scenarios to do the same thing (as shown above), is there a way to make an abstract layer between them and the controller? I mean something like:
interface IPaymentManager
{
void MakePayment(); //this controls the payment methods flow
//Something like (Accept -> Confirm) in the former case
//and (Accept -> Validate -> Confirm) in the latter
}
I am doing this in ASP.NET WebAPI 2, but I think it may apply to MVC as well.
If I understand correctly, when a user creates a transaction they are redirected to the payment provider (with a redirect url in the response). Once there they confirm their credentials which returns them to your fancy web store (with a confirmation token provided by the payment provider). If that token is valid then the transaction was successful. Also each of those actions require a separate endpoint in your controller.
If those assumptions are correct, I would say it is not necessary, or even recommended, to create an abstraction here. Also there is response data (validationCode, paymentToken, etc.) from the payment provider which your PaymentManger functions and controller endpoints are dependent on in order to proceed in the process.
In my experience, trying to abstract too early can make more work for you down the road. Without more information (more implementations of payment provider clients) you might make abstractions that are too specific - which can not be used for different PaymentManager types you add later.
However, if you already posses this data (validationCode, etc.), then you could abstract here, but I would still say it is unnecessary, and potentially a waste of time.
If you are determined to abstract here, then you can implement your interface in each of your PaymentManager classes. Having each PaymentManger implement the MakePayment function which would call the respective PaymentManager functions.
Again, I would not recommend abstracting here. It doesn't make sense, and really won't be that helpful in my opinion. Wait until you implement a few more PaymentManager classes. Then you will be able to more accurately see the patterns between the different types of PaymentMangers and abstract those patterns out.
If my understanding of the problem was not correct, let me know where I misunderstood the problem, and I will try to answer it again.
On a side note, I would recommend looking into asynchronous functions and the await operator, if you haven't already and are making calls to an external API.
Hope this helps.

Custom Roles/Permissions in ASP.NET

I currently have a Web Application which is using it's own "Permissions" table which contains the following columns:
UserName - Windows UserName (Context.User.Identity.Name)
DivisionID - Links to a Division Table
RoleID - Comes from a custom Roles Table
RegionID - Recently added field to divide my Application into Countries (Canada, USA, International)
When the User logs into the site, they choose which Region they want to enter and I need to give them access to those Regions based on if they have any permissions set for that specific RegionID. Upon selecting a Region, the RegionID is stored in Session and will be used for this permission check and defining how data is populated on the pages (I haven't implemented the Session variable into all of the pages just yet so that can be changed if need be)
My initial thought would be to run my Permission Check on each page sending them to one of three destinations:
Invalid Permission Page (false)
Region Select Page - No Region selected in Session (RegionID = 0)
The page they requested - If has a permission set for that Region
I've also looked into using the Application_AuthenticateRequest method within the Global.asax but I cannot use Session within this area and it seems to be hitting the Application_AuthenticateRequest much more than it should be.
With my current App, what would be the best way to authenticate each user with their corresponding Regions, based on their Permissions?
I've really only worked with forms authentication-- but I'm assuming you'll be using windows authentication for membership and some form of custom roles authentication. I've never done it, but one would think it should work.
http://msdn.microsoft.com/en-us/library/system.web.security.roleprovider.getrolesforuser
You could create a custom provider that would take into account the Session value for Region in order to return the correct roles. I know for a web application, the default provider stores the roles as an encrypted cookie on the client. I'm thinking you can do something similar.
Normally I wouldn't recommend this method, but as it seems that you have already developed your application, you could relatively easily implement the following without too much upheaval:
Create a base class for your pages, and then inherit all the pages in your application from the base class. You would of course implement the "authorization" within the base class.
The one rather nasty problem with this is that if you forget to derive your page from the base class, then your page has no security on it.....but you could just as easily forget to implement your "Permission check"....
Something like
public class AuthorizedPage: System.Web.UI.Page
{
protected override void OnLoad(EventArgs e)
{
// ... authorization logic here...
// Be sure to call the base class's OnLoad method!
base.OnLoad(e);
}
}
You could check this out ASP.net "BasePage" class ideas and this https://web.archive.org/web/20211020133935/https://www.4guysfromrolla.com/articles/041305-1.aspx
Or, another idea, if you have used Master Pages you could also just do this stuff in the master page....

Ways to share common functions betweed few pages in ASP.NET

This is possibly very lame question and I lack knowledge about ASP.Net. In this case a link to an article explaining would be very welcome.
I'm working on web-site on ASP.NET with C# as codebehind. My current project involves developing few pages with very similar functionality and a many functions are the same. For example
private void PermissionCheck()
{
if (null == Session["UserID"] ||
null == Session["ProjectID"] ||
null == Session["AssetID"] ||
null == Session["ProjectName"])
{
Response.Redirect("~/Login.aspx");
}
}
Would be the same on 2 pages. Some other things are the same as well. I would like to put this into common base class. But there are other functions that don't really belong to pages at all:
private string GetAttachmentTempPath()
{
return Request.PhysicalApplicationPath + WebConfigurationManager.AppSettings.Get("AttachmentsTempFolder");
}
I would like to move this into Attachment class, but to get the physical path of the application, I need to pass in Request object into that method, which is not really nice, as it couples Attachment class with Page.Request object.
Is there any way to move these functions somewhere else without needing to pass Page.Request objects around??
p.s. The appliction is huge, and there is no scope to change the entire architecture.
For your permission thing you could make a base page class:
class BasePage : Page
{
...
protected override OnInit() {
// do check here
}
}
Now you can implement your page like this class MyOtherPage : BasePage { ... }
The OnInit gets executed everytime your MyOtherPage gets loaded.
You can see a complete page lifecycle here: Link
For your other problem: Consider to implement a global available static tool class
Update
A good approach for making things like web.config easier to access is a Singleton. In asp.net a singleton is only created once and lives until the asp worker process gets stopped . So this values are shared across the whole asp.net application. This is also good for storing data in a global context that you dont want to get out of your database or file anytime a user makes a page request (for example a version number or things like that)
Update 2
To access the request without passing it to every function, use this:
HttpContext.Current.Request
Base page is a good option for reusable code in Page level. Other than that for things like configuration values it's good to come up with utility classes specifically for those methods base don there type of operations.
If you need to avoid passing in Page object into these types of utility methods,
HttpContext
class would be handy because you can access many of the ASP.Net object through static members through this class. HttpConext # MSDN
If you have similar functions behind the page, you can use ASP.NET WEb User Control.
You can create the functions in the usercontrol and use the control in the pages where necessary.
Have look at this article about Web User Control in Asp.Net

What would be the best way to handle a system with multiple user types?

I've been given the task of updating an asp system to MVC3. My main issue is that the current system has 2 different kinds of user, each user has their own user table, and in the current asp site, each user is defined by a number of different session held variables.
Because other systems use the two different user tables, I can't merge them. So what would be the best way forward?
I initally thought about keeping them seperate in the system; having a class type for each user which holds the seperate variables mirrored from their asp counterpart. On login, I could push user type to userdata in the auth cookie, then create an extension method on the IPrincipal to return the user type when required.
This feels a bit of a hack, and as the users will be viewing the same pages, there would be a lot of duplication of code.
Would it be better to create some form of facade before the user repository which would attach a role to a common user object which would identify the user type in the system? I could then check this role and pull out the data, that used to be stored in session variables, when needed.
If I would given a chance to do this I would do it in following way:
Implement asp.net membership provider and import all users into it.
Create two different roles for user types
Use profile provider to store additional properties from user type tables.
This way, you can use combination of role and profile to handle any situation related to authorization and restriction.
I would define an interface with methods common to both users, and have both user types implement the interface. So, if you have something like:
interface IUser { bool CanViewPage1(); }
class UserType1 : IUser { }
class UserType2 : IUser { }
Session["user"] = new UserType1();
Then you can do:
var user = (IUser)Session["user"];
For common operations:
if (user.CanViewPage1())
{
...
}
and for operations where you need the user object:
bool CanViewPage2(IUser user)
{
if(user is UserType1)
{
var ut1 = (UserType1)user;
...
} else if (user is UserType2)
{
var ut2 = (UserType2)user;
...
}
}
The last part can be done via extension methods as well, as you said.
Id suggest to use WIF with custom simple STS server and use claims for user types.
http://msdn.microsoft.com/en-us/library/ee748475.aspx
And for checking this stuff - use custom attribute, or simple - Identity.HasClaim("someclaim name or type").
Also this will standartize your approach for authentication/authorization, which can save some time later=)
If I was building this application from the ground up, i'd differentiate user type by role. With this in mind, I've created an anticorruption class between the User builder and reps. This injects/removes a role (id of 0) to distinguish user type. In future, the client hopes to merge tables, so this seemed the most sensible way forward for now.

Requires a generic approach to validate control of ASP.Net form

I have a B2B we app having lots of forms taking input from registered users. So validation is mandatory there. I am using 3 tier architecture for my app. I am just ignoring server validation controls and client side validations. Instead i am thinking of Code Behind based validation, which i know will increase hit to my server, but too is most secure, if I am not wrong.
So what i am thinking is,
to enumerate all the controls of the page and check their validity. But this wayI can check only whether it is empty or not. Also I have to write it on each and every page.
Another approach, if i can set the maxlength , mandatory etc somewhere in my Model Layer where I have skeleton classes,and compare it while save button hit and tell what is missing and where.
Some common method that will take entire page controls as array of controls and check for validity...
Please guide me which one is possible or any other good solution.So that i can avoid code repetitions.
Model Layer means
public class Employee
{
public string Name {get;set;}
}
You can add a set of controls that inherit from ASP.NET controls, only with (a)additional type classification. For example: TextBox that accepts an attribute of DataType (enum) and values like: int, double, email etc. Another idea is for int type add a min/max values (i.e 15-32). And (b) a Validate function that returns true/false if the value matches the datatype.
Then, create a page base that inherits from Page and exposes a function called ValidateAllMyControls that iterates through all those special controls that are in use in the current form and calls the Validate function for each one. If one of them returns false - the form is not valid. :)

Categories