Server security
This article covers the basics of securing a server resource. What security is needed as well as how to secure your server depends on two general factors; where it's deployed and how secret it is.
There are a number of different approaches for securing a resource. These are in no way mutually exclusive, so you might use none, one or any number of them:
-
Use a firewall for shielding a resource. You may protect the resource so that calls may only come from within a given network zone or only from a set authorized callers (ip-addresses).
-
Require user authentication to grant resource access. You may protect access to, or use of, a resource by requiring users to authenticate themselves. Your authentication solution may either rely on - trust - relying on our network directory or using its own user directory for authentication.
-
Filter information access, and function availability, based on user credentials. This too requires authentication and means limiting what the user can see and do based who he/she is. This protection is, by necessity, something your solution implements itself.
-
Encryption of resource calls. You may, at least for sensitive information running across the Internet, consider to use SSL (https) when accessing server resources. This prevents third parties from extracting information such as user id's and password.
The first approach does not affect your implementation, it's a consequence of where the solution is deployed. However, it is not to be considered sufficient outside of a highly controlled environment. Most often your solution will require protection of the second kind as well. The easiest way is to rely on your network directory. This avoids having to introduce and manage your own, often less safe, directory solution. Furthermore, it allows safe single-sign-on and provides the best and safest end-user experience. The third protection has the largest solution impact. Coming up with, and implementing, a good way of handling user credentials in your solution might very well be just as difficult as building the solution itself. In fact, the credentials system is most likely an integral part of your solution.
On the Internet
Deploying a system on the Internet introduces a number of "no-can-dos" and special concerns. For one thing, you can't rely on your local network directory for authentication. A more vital issue is that of security: many web applications rely on the false assumption that the server resources can only be called from the intended front-ends. The truth is that other code, including hostile code, can call these resources to cause damage or circumvent inadequate security. The most obvious security measure, in this case, is to layer your system. This way you can leave on the Internet only the parts that need to be there, while the other resources remain shielded by a firewall. The shielded resources are now only available through the public ones, via your server on the Internet, but are not available for direct access.
RISE web services
RISE is, of course, subject to all of the above concerns and you may apply all of the above security measures in a RISE solution. When in a LAN environment our suggestion - for the "normal" application - is that you rely on the network directory and apply an eventual credentials mechanism in your front-end. Simply, beacuse this is the easiest way and hostile code isn't a realistic treat (if you've got hostile co-workers you've got a bigger problem than IT).
For Internet domain RISE solutions, or for solutions requiring extensive security, RISE provides some means to assist you in building your security solution. The most important of these is to use RISE composed, or aggregted, methods in combination with custom authentication code to implement a security solution that is fully contained in your RISE project and entirely under your control. This allows you to implement any authentication and/or authorization process.
Read more about how to accomplish permission control in our section on composed methods.
There are also some utilities at a technical level that you may use. You trigger these when generating your server code by turning on any of the options supportTicket or userLogin.
Support for custom User Login
This approach could be used when you implement, or already have, your own custom user directory. RISE provides a hook for you where you can place your own authentication logics.
If the server code is generated with the flag userLogin set to true, all generated methods will require two extra arguments; userid and password. Behind the scenes this causes the generated method to call a separate Verify-method. You need to implement this method yourself and make it a part of your solution.
The signature for the custom user authentication method:
// Whatever references you need plus ..
using System.Data.Odbc;
namespace YourModelPrefix
{
public class Login
{
public static bool Verify(OdbcConnection dbConn, string userid, string password)
{
// Your code to verify the userid and password goes here!
// return true to allow execution to continue
return false;
}
}
} |
The ODBC connection is passed to the Verify method. The reason is to allow you to pass the userid and password to the connection used by RISE, i.e. to use the supplied userid and password, or some other user information, to log in to the database. To insert a userid and password into an ODBC connection string you could use the following code:
OdbcConnectionStringBuilder csb = new OdbcConnectionStringBuilder(dbConn.ConnectionString);
if (csb.ContainsKey("uid")) csb["uid"]=userid; else csb.Add("uid",userid);
if (csb.ContainsKey("pwd")) csb["pwd"]=password; else csb.Add("pwd",password);
dbConn.ConnectionString = csb.ConnectionString; |
Support for Tickets
A "Ticket" concept could be used when you run in a trust relationship with another directory but are prevented from explicitly authenticating against that directory. For instance, because you don't have access or the user password. Normally, a ticket is a code snippet (perhaps a GUID) created when the user is authenticated against the trusted directory. The ticket is then passed, instead of userid and password, to solutions and sub-systems that trust the directory that generated the ticket. Note, a ticket solution requires a way to store and verify tickets. To avoid that tickets are hi-jacked, a ticket should - in most solutions - either be time-limited or only valid for a limited number of authentications or both.
If the server code is generated with the flag supportTicket set to true, all generated methods will require an extra argument; ticket. Behind the scenes this causes the generated method to call a separate Verify-method. You need to implement this method yourself and make it a part of your solution.
Sample code for the custom ticket method:
namespace YourModelPrefix
{
public class Ticket
{
public static bool Verify(string ticket)
{
// Your code to verify the ticket goes here!!
// return true to allow execution to continue
return false;
}
}
} |