Browse DevX
Sign up for e-mail newsletters from DevX


Manage Custom Security Credentials the Smart (Client) Way : Page 2

By default, you can only manage the security credentials of the SQL Server database that ships with ASP.NET 2.0 using a local instance of Visual Studio 2005. This article shows how to extend the management capabilities by wrapping the ASP.NET 2.0 providers with a Web service and using a Windows Forms application to manage the credentials store.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Solution Architecture
The solution architecture is simple—wrap the ASP.NET 2.0 providers with a Web service and expose the credentials management operations for remote clients. You can even add the missing functionality. Then, use a Windows Forms application to consume that Web service while providing a rich user interface and a comprehensive credentials management experience. The Web service configuration file will contain the directives pertaining to the credentials store. This does mean, however, that all applications managed by the Web service will share those directives.

Wrap the ASP.NET 2.0 providers with a Web service and expose the credentials management operations for remote clients.
While you can build the Web service bottom-up, that is, start with the static methods of Roles and Membership, wrap them and define the Web service that way, I prefer a contract-driven approach: start by designing what would be the best interfaces to perform the various operation, and only then worry about how to implement them. Doing it this way will ensure that the interfaces exposed by the Web service support all the required administration functionality, and will also decouple the client application from any implementation details (such as wrapping the providers).

Editor's Note: For information about contract-first, see the July/Aug 2005 issue of CoDe Magazine.)

One of the nicer features of ASP.NET 2.0 is its support for Web service interfaces: you can define and have the Web service expose logical interfaces, just like classes do. To do so, you need to decorate your interfaces with the WebServiceBinding attribute and expose the individual interface methods via the WebMethod attribute. Then, you would have a class derive from the interface and implement it, and the compiler will insist you support all methods of the interface.

To manage and interact with the credentials store and the Web service configuration file I defined five interfaces. These are: IApplicationManager, IMembershipManager, IPasswordManager, IRoleManager, and IUserManager.

The IApplicationManager interface, shown in Listing 2, allows the administrator to delete a specified application, that is, remove all references to it from the database and delete all its users and its roles. IApplicationManager allows deleting all applications from the store, and it can return a list of all the applications in the store. Note that the interface is defined as an internal interface—public or internal visibility modifiers have no meaning for Web service interfaces. Each method on the interface is decorated with the WebMethod attribute with a short description of the method. In addition, all methods (in all interfaces in this architecture) that access the credentials store are configured to use transactions. This is so that two operations such as deleting an application and creating a user will execute in complete isolation from each other, and to ensure the atomicity of complex operations such as deleting all users. Web services in .NET 2.0 can only start a new transaction, and that is controlled via the TransactionOption property of the WebMethod attribute. In all subsequent code listings, both the description and the transaction support are omitted to save space, but they are in the accompanying source code. Last but not least is the use of the WebServiceBinding attribute on the interface. This designates the interface as a Web service interface that clients and services can bind against, that is, implement or consume it. In order to expose the interface to the outside world as a WSDL contract, you need to use a shim class. The shim class is required because you cannot expose an interface as a Web service, nor can you apply the WebService attribute on it. The shim class will also provide the namespace definition for the interface via the WebService attribute. The code below shows the IApplicationManagerShim abstract class definition.

[WebService(Name="IApplicationManager", Namespace="http://CredentialsServices", Description="IApplicationManager is used to manage applications. This web service is only the definition of the interface. You cannot invoke method calls on it.")] abstract class IApplicationManagerShim : IApplicationManager { public abstract void DeleteApplication( string application); public abstract string[] GetApplications(); public abstract void DeleteAllApplications(); }

Because IApplicationManagerShim is a class, you can expose it as a Web service. Because it is an abstract class and all the methods are defined as abstract methods, there is no need to implement any of the methods (nor can you). To make it look just like the interface, IApplicationManagerShim sets the Name property of the WebService attribute to IApplicationManager (instead of the default class name). You can now expose the interface using the IApplicationManager.asmx file.

<%@ WebService Language="C#" CodeBehind="~/App_Code/IApplicationManagerShim.cs" Class="IApplicationManagerShim"%>

Now, if you browse to the IApplicationManager.asmx page you will see the interface definition. You can use the /serverInterface option of WSDL.exe to import the interface definition to the client or to any other service that wants to bind to the interface definition.

The IMembershipManager interface (see Listing 3) allows you to manage all aspects of user accounts: creating and deleting user accounts, updating user accounts, retrieving user account details, and retrieving all the users in an application.

The IRoleManager interface shown below allows you to manage all aspects of logical roles: creating and deleting roles, adding and removing users to and from roles, and retrieving all the roles in an application.

[WebServiceBinding("IRoleManager")] interface IRoleManager { [WebMethod(...)] void CreateRole(string application,string role); [WebMethod(...)] bool DeleteRole(string application,string role, bool throwOnPopulatedRole); [WebMethod(...)] void AddUserToRole(string application, string userName, string role); [WebMethod(...)] void DeleteAllRoles(string application, bool throwOnPopulatedRole); [WebMethod(...)] string[] GetAllRoles(string application); [WebMethod(...)] string[] GetRolesForUser(string application, string userName); [WebMethod(...)] string[] GetUsersInRole(string application, string role); [WebMethod(...)] void RemoveUserFromRole(string application, string userName, string roleName); //More members }

This IPasswordManager interface provides mostly read-only information pertaining to the application password policy.

[WebServiceBinding("IPasswordManager")] interface IPasswordManager { [WebMethod(...)] bool EnablePasswordReset(string application); [WebMethod(...)] bool EnablePasswordRetrieval(string application); [WebMethod(...)] string GeneratePassword(string application, int length int numberOfNonAlphanumericCharacters); [WebMethod(...)] bool RequiresQuestionAndAnswer(string application); [WebMethod(...)] string ResetPassword(string application, string userName); [WebMethod(...)] string GetPassword(string application, string userName, string passwordAnswer); [WebMethod(...)] void ChangePassword(string application, string userName, string newPassword); //More members }

That policy is stored typically in the application's configuration file. The policy includes whether password reset and retrieval is enabled, password strength, and password answer policy. You can also use IPasswordManager to generate a new password that complies with the password strength policy. In addition, IPasswordManager is used to reset, change or retrieve a specified user's password.

The IUserManager interface allows validating user credentials, retrieving role membership, and getting all the roles a user is a member of. It is available for test and analysis purposes.

[WebServiceBinding("IUserManager")] public interface IUserManager { [WebMethod(...)] bool Authenticate(string applicationName, string userName, string password); [WebMethod(...)] bool IsInRole(string applicationName, string userName, string role); [WebMethod(...)] string[] GetRoles(string applicationName, string userName); }

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date