I need to organize some simple security in a class depends on value of the enum.
All that I can figure out is using attribute on a method and then run check then if it fails throw an exception.
Sample:
[ModulePermission(PermissonFlags.Create)]
public void CreateNew()
{
CheckPermission();
System.Windows.Forms.MessageBox.Show("Created!");
}
protected void CheckPermission()
{
var method = new System.Diagnostics.StackTrace().GetFrame(1).GetMethod();
if (!flags.HasFlag(method.GetCustomAttributes(true).Cast<ModulePermissionAttribute>().First().Flags))
{
throw new ApplicationException("Access denied");
}
}
is there more elegant or simple way to do this, like just to trigger an event when method run?
Why not just use standard Code Access Security instead of reimplementing the attribute handling and stack walking?
I think that if you read through the linked documentation, you'll see that what you have is nowhere close to what is needed to achieve actual security. Thankfully, this hard problem has already been solved...
Not with an enum, but with strings - voila (enforced by the runtime, even in full-trust):
public static class PermissionFlags {
public const string Create = "Create";
}
[PrincipalPermission(SecurityAction.Demand, Role = PermissionFlags.Create)]
public void CreateNew() {
System.Windows.Forms.MessageBox.Show("Created!");
}
All you need to do now is to represent the user as a principal. This is done for you in ASP.NET, and there is a winform plugin (in VS2008 etc) to use ASP.NET for membership. It can be configured for vanilla winforms and WCF, too; at the most basic level, GenericPrincipal / GenericIdentity:
// during login...
string[] roles = { PermissionFlags.Create /* etc */ };
Thread.CurrentPrincipal = new GenericPrincipal(
new GenericIdentity("Fred"), // user
roles);
But you can write your own principal / identity models easily enough (deferred / cached access checks, for example).
You might want to look at doing this with something like PostSharp, which will give you a framework for applying the attributes so that you don't have to run the check in your method. This may, however, increase the complexity depending on how the currently active flags are accessed. You'd probably need some class to cache the current permissions for the current user.
You could take a look at Aspect Oriented Programming.
Check out Postsharp for instance, which will enable you to 'weave' some additional logic at compile time in the methods that you've decorated with your ModulePermission attribute.
By doing so, you will not have to call the 'CheckPermission' method anymore inside that 'secured' method, since that logic can be weaved by Postsharp.
(A while ago, I've been playing around with Postsharp: http://fgheysels.blogspot.com/2008/08/locking-system-with-aspect-oriented.html )
Related
I'm trying to implement a security mechanism to automatically test a particular plugins permissions and method security privileges and I've gotten a bit stuck on how to get this working.
I've writing a custom MEF Metadata attribute that takes a constructor property like:
params PluginPermission[] permission
This contains an array of all the permissions that the plugin is granted.
The PluginPermission class looks like:
PluginPermission.cs
public enum PluginPermission
{
CreateUsers,
DeleteUsers,
ReadPassword,
WritePassword,
AddUsersToGroups,
AddGroups,
DeleteGroups
}
I've also written a RequiredPermissionAttribute that targets individual methods and takes one or more PluginPermission objects to tell the system what permissions are required for an individual method to be execute. These are applied to the interface for the plugins like:
ILicensingManagement.cs
[RequiredPermission(PluginPermission.CreateUsers)]
bool AddUser(string userName);
Obviously if the plugin doesn't have the required permissions for a particular method the method is not executed.
What I'm stuck on is how to actually get the test method in the RequiredPermissionAttribute class to run before the method is executed and how to gracefully exit the execution if the permissions requirements for the method are not met by the plugin.
I looked at the xUnit BeforeAfterTestAttribute but the implementation seemed so specific I stuggled to pull the source code apart to arrive at the solution.
I can't comment on MEF specific things but one thing to keep in mind that custom attributes are nothing more than "tags", they do not do anything unless your code specifically checks for them, for example using reflection.
The BeforeAfterTestAttribute of xUnit probably works, because xUnit uses reflection to execute the methods. When it encounters this attribute it changes its behavious accordingly.
Attributes in the .NET framework namespace work because either the CLR checks for them or the compiler does.
I know this doesn't really answer your question completely but it was a bit too long to put into a comment.
Update: you can access the attributes using the Type if it's a class or the MethodInfo if it's a method, e.g.
MethodInfo mi = /* method info */;
Attribute[] attrs = mi.GetCustomAttributes(typeof(RequiredPermissionAttribute), false);
RequiredPermissionAttribute req = attrs.Cast<RequiredPermissionAttribute>().FirstOrDefault();
if ((req != null) && (/* current user does not have the required permission */)) throw new Exception();
But this is not a real security solution, a developer can easily avoid these checks. I've only briefly glanced at it but PostSharp could maybe help you.
I have a private static readonly field in my class:
public class MyClass
{
// ISSUE #1 -- requires unproven: path != null
private static readonly DirectoryInfo MyDirectory =
new DirectoryInfo(Settings.Default.MyDirectoryPath);
protected virtual void SomeMethod()
{
if (MyDirectory.Exists)
{
// ISSUE #2 -- requires unproven: !string.IsNullOrEmpty(path)
var catalog = new DirectoryCatalog(MyDirectory.FullName);
}
}
}
For issue #1 I used a null coalescing operator to default to some magic string and that fixed it, but I don't really like that solution. I was hoping there was a better solution.
For issue #2 the only thing I can think of is using a Contract.Assumes because if I attempt to use Contract.Requires(MyDirectory.Exists || !String.IsNullOrEmpty(MyDirectory.FullName)); it complains about visibility (private field used in a requires on a protected method).
Issue #1 is a result of Settings.Default.MyDirectoryPath being code generated by Visual Studio without any contracts on the property. This issue is not limited to null strings. Many API's now have contracts that require say a TimeSpan to be non-negative but using a setting directly in the API will generate a Code Contracts warning.
A way to solve this issue is to wrap the setting in a method that has a contract. E.g.:
String GetMyDirectoryPath() {
Contract.Ensures(Contract.Result<String>() != null);
var myDirectoryPath = Settings.Default.MyDirectoryPath;
Contract.Assume(myDirectoryPath != null);
return myDirectoryPath;
}
Notice how the Contract.Assume really performs validation of your setting (which can't be verified by Code Contracts because it is controlled by an external configuration file). Had it been a TimeSpan that is expected to be non-negative you can either use Contract.Assume to do the validation resulting in a ContractException or some other method using your own exception instead.
Adding this extra layer is somewhat tedious but because the setting is defined outside the application it needs to be run-time validated at some point just as you have to validate interactive user input.
Issue #2 is probably because DirectoryInfo doesn't have any contracts defined. The easist way is to use Contract.Assume. This will make a statement about what you believe is the expected behavior of DirectoryInfo but a run-time check will still be in place to ensure that your belief is correct (provided that you keep the checks in your code).
var path = MyDirectory.FullName;
Contract.Assume(!string.IsNullOrEmpty(path));
var catalog = new DirectoryCatalog(path);
After having used Code Contracts in a current project for a while now I have found that it does force you to rewrite your code at times to correct for issues. You really have two options here.
You can add the setting to your project settings to output what the correct attributes to apply are to ignore certain warnings. This is done by adding the "-outputwarnmasks" flag to the "Extra Static Checker Options" under the Advanced section in the Code Contracts tab of the Project file settings. This will add information to the Build Output window giving you the correct attributes to add to ignore the individual cases. (very useful when dealing with Entity Framework).
You can rewrite your code to add the proper Requires and Ensures to your code so that the warnings don't appear.
If you want to rewrite the code:
To solve Issue #1 you would have to wrap the Settings class and expose a new MyDirectoryPath as a property that isn't code generated so that you can add a check in it and return an empty string and add the Contract.Ensures(Contract.Result<string>() != null) at the top of the Getter for the property.
To solve Issue #2 you would have to wrap you access to the class field inside a private static property that adds the proper Ensures and Requires.
I have usually gone with rewriting the code wherever possible except with Entity Framework/LINQ where you need to add the attributes, especially with complex queries.
** Disclaimer ** These are just the ways I have found to solve the issues as there isn't a great deal of information on other ways of working around these types of items.
Well, for Issue#2, I think you might want to use && not ||. But beyond that, perhaps for Issue#1 you can put those checks in the static constructor? Another option for Issue#2 is to have the method to take the directory as a parameter:
private static readonly DirectoryInfo MyDirectory;
static MyClass()
{
Contract.Requires(Settings.Default.MyDirectoryPath != null);
MyDirectory = new DirectoryInfo(Settings.Default.MyDirectoryPath);
}
protected void SomeMethod()
{
SomeOtherMethod(MyDirectory);
}
protected virtual void SomeOtherMethod(DirectoryInfo directory)
{
Contract.Requires(directory.Exists && !String.IsNullOrEmpty(directory.FullName));
var catalog = new DirectoryCatalog(directory.FullName);
}
I don't have much experience working with the Contract API, so I might be off my rocker with all this. :)
Contract.Requires(MyDirectory.Exists || !String.IsNullOrEmpty(MyDirectory.FullName));
Don't do this! MyDirectory.Exists can change at any time and the caller cannot guarantee it. Just throw an exception if the directory doesn't exist - this is what exceptions are for.
To add an audit trail to our application we decided to use NHibernate.Envers. To allow app specific tracking of revisions, the DefaultRevisionEntity was extended with user specific data.
public virtual void NewRevision( object revisionEntity )
{
var revisionData = revisionEntity as Revision;
if( revisionData != null )
{
// Set additional audit data.
var identity = UserAccessor.CurrentIdentity;
revisionData.UserId = identity.UserId;
revisionData.EmployeeId = identity.EmployeeId;
revisionData.UserName = identity.Name;
}
}
Envers decides wich RevisionListener to use depending on the RevisionEntity attribute your class is decorated with:
[RevisionEntity( typeof( RevisionListener ) )]
I am using the ServiceLocator pattern to inject my accessor into the RevisionListener. Currently this is the only place where I have to use a ServiceLocator and really want to get rid of it.
Is there another, flexible way to inject my UserAccessor into the RevisionEntity?
No, you can't today.
However - it sounds like a nice feature. Please add a JIRA ticket about it here
http://nhibernate.jira.com/browse/NHE
Without giving it too much thoughts, I think it'll be pretty hard to enable users to do this with only attribute configuration though (if so, sort of an IoC needs to be built internally). Probably it can be accomplished by allowing to inject a revision listener singleton "somewhere close to IntegrateWithEnvers method".
Regards
Roger
I have a dialog, Authentication dialog, that is going to be required in different parts of my application. What would be the best design practice to be able to effeciently call the dialog and the logic behind it (seperate classes) in different points of the program?
EG:
User starts program - login required
User wants to view encrypted data - confirmation of password required
User wants to change password - confirmation of current password required.
So what would be a good way to implement this?
Any suggestions are welcome?
Perhaps not the simplest solution to implement, but you could look into using Aspect Oriented Programming. You could then annotate each method which requires user login. This makes the code clean and readable.
[ConfirmUser(ErrorMethod=... RequireUsername=false, RequirePassword=true )]
public void ViewData()
{
// your code
}
The AOP framework would weave in the required code to handle the user confirmation in your method.
Or do the same thing inside the methods manually:
public void ViewData()
{
ConfirmUser();
// your code
}
public void ConfirmUser()
{
if( !DoLoginPage() ) throw new SecurityException("Incorrect credentials");
}
You could have ConfirmUser return a bool instead of an exception. That's another discussion, and depends on your application. If you deny operations in lower code layers, an exception is the way to go. A try/catch makes you put the error handling at the bottom of the function, while a returning bool requires and if statement at the top.
public void ViewData()
{
try
{
ConfirmUser();
// your code
}
catch( SecurityException )
{
//handle error
}
}
vs
public void ViewData()
{
if( !ConfirmUser() )
{
//handle error
return;
}
// your code
}
You could implement both ConfirmUser and ConfirmPassword, or have both in the same method with a parameter, perhaps an enum to say what you need to verify.
[Flags]
public enum Requires
{
Username,
Password
}
public bool ConfirmUser( Requires requiresField )
{
}
One approach could be to create a "user authenticated" method.
So when ever you need to check that the user is allowed to perform the requested action you make the call:
if (UserAuthenticated())
{
// Perform action
}
This method would hold details of the user and prompt for the password and check them against the database. If the details match, return true and carry on.
On start up the user name wouldn't be set so the dialog could prompt for that as well.
This is an example of aspect orientated programming or cross-cutting concerns.
Generally speaking, there is no real difference in designing reusable Forms compared to designing any other reusable class - put the classes you want to re-use into one or more assemblies and reference them from the point where you want to reuse them. That works for Forms as well as for any other reusable class.
If you need slightly different functionality of your Form depending on the context you are calling it, you can, for example, write appropriate constructors, or initialize the dialog by appropriate methods before showing it.
Basically I'm trying to implement some sort of poor man's Aspect Oriented Programming in C#. I had thought about using a ContextAttribute but they seem only be be bound at the class level. Is there any way that I can put an attribute in such that it will receive the same parameters as the method which it annotates or some way to access the context in which it fired?
I have this code
public void AddUser(User user)
{
var errors = DataAnnotationsValidationRunner.GetErrors(user);
if (errors.Any())
throw new RulesException(errors);
users.Add(user);
}
from which I would like to extract the first 3 lines so I had something like
[Validated]
public void AddUser(User user)
{
users.Add(user);
}
I think you are missing a third component. Most AOP implementations (e.g. Aspect#) rely on a proxy or interceptor to actually execute the code. In your scenario, you lack whichever component needed to 1) know the attribute exists on the method, and 2) trigger the mechanism (or become it) needed to execute the code within the attribute.
Fortunately, there are already many (fairly) simple solutions available in open source. The simplest option I can think of would be to use a compile-time weaver like PostSharp. Grab a copy of that, and in the samples you'll find several examples of exactly what you are trying to do (you'd be interested in the OnMethodInvocationAspect).
The end result is that your code looks exactly like it does in the sample you provided, yet it's also running the code you wish.
Don't know exactly how your solution should look like, but in C# attributes do not execute code as long as you don't request them (as far as I know). And if you query for the attribute, you also have the context. So there is something wrong with your strategy in my opinion.