In a Web application we define roles, forms authentication etc. for security, but what should be the best way to secure a Winform ?
Actually I am making desktop application in which I hide login page after successful login and show DisplayForm
like this ;
//On successful login
this.Hide()
Form newForm = new DisplayForm();
newForm.Show();
But I don't know if it's the right way or not? I want the user to be able to see this DisplayForm
only after successful login.
Any guidance please ?
To follow on from Mike's answer this is the implementation I used (as requested by the OP):
Add the following to the function definition:
[PrincipalPermissionAttribute(SecurityAction.Demand, Role = "<Your role>")]
public void YourFunction()
{
.. do something
}
Where <Your Role>
is the AD role you want to restrict access to.
Then wrap your function call like this:
try
{
YourFunction();
}
catch (System.Security.SecurityException)
{
MessageBox.Show("You do not have permission to perform this action.", "Access Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
...
Let me preface my answer with the following general remark: There is no absolute security in WinForms applications. Nothing stops the user from decompiling your application, removing any login requirements you might have added and recompiling it.
That said, I think your approach is correct. DisplayForm
won't show until you, the programmer, explicitly tell it to do so. Thus, if you only call someInstanceOfDisplayForm.Show()
after authentication has happened, that is fine.
As an additional security measure (to safeguard against some programming mistakes), a common practice is to
- set some global variable¹
UserLoggedIn
, after the user has successfully logged in and
- check this value in
Form_Open
of DisplayForm
(or any other form you want to protect).
¹ ... or Singleton property or some other kind of global storage. Yes, global variables are evil, but I think it is justified in this case, since a user logged into an application is a prime example of a legitimate "global state". If required, I'll gladly discuss this further in the comments.
The best way in my opinion is to use Windows Authentication (as suggested in the comment from Hans Passant) and do not implement your own login dialog and user store.
In this way, you can always make authorisation decisions by examining the current user principal (e.g. Thread.CurrentPrinciple
). The granting or denying of application permissions can then be done on the basis of their Active Direcory memberships, which are all accessible by looking at the user principle.
The advantages of this are:
- It prevents people bypassing your security by going directly to your assemblies
- It allows your admins to control application permissions using familiar Active Directory group membership - no need for you to write code for this and reduced chance of people forgetting to remove application permissions when users change role