Security operations
Check out this article and learn more details about the WEBfactory 2010 Client SDK security operations and the involved paramters.
The following article documents the Security methods from the WEBfactory 2010 Silverlight SDK. To view an example on how to use the Security methods, click on the link below:
LoginUser
Method Definition
void LoginUser(string user, string password); void LoginUser(string user, string password, bool isDomainUser); void LoginUser(string user, string password, OnResultDelegate resultDelegate); void LoginUser(string user, string password, bool isDomainUser, OnResultDelegate resultDelegate);
Calling Parameters
user User name
password User password
isDomainUser User is in domain
resultDelegate Delegate to function handling the result
Description
This method logs in a specific user.
There are two methods available. The difference is that one method is able to register a callback which indicates the result of the operation.
The delegate OnResultDelegate is defined as:
void OnResultDelegate(Exception error, int[] results);
The error (type Exception) is a Silverlight error indicator for asynchronous operations. WEBfactory 2010 bypasses this exception to SDK users to make it easier to find communication errors.
Each value of the integer array results may have one of the following values:
0: Success
-4095: User login failed (Login)
-4094: No user logged in (Write)
-4093: Insufficient user authorizations (Write)
-4092: User already logged on (Login)
-4091: Invalid user password (Login)
-4090: Max user count reached (Login)
-4089: Unspecified server error (Login, Write)
-4088: Signal is write protected (Write)
LoginCurrentWindowsUser
Method Definition
void LoginCurrentWindowsUser(OnResultDelegate resultDelegate);
Calling Parameters
resultDelegate Delegate to function handling the result
Description
This method logs in the current windows user and calls the callback when the process is completed successfully or not.
The delegate OnResultDelegate is defined as:
void OnResultDelegate(Exception error, int[] results);
The error (type Exception) is a Silverlight error indicator for asynchronous operations. WEBfactory 2010 bypasses this exception to SDK users to make it easier to find communication errors.
Each value of the integer array results may have one of the following values:
0: Success
-4095: User login failed (Login)
-4094: No user logged in (Write)
-4093: Insufficient user authorizations (Write)
-4092: User already logged on (Login)
-4091: Invalid user password (Login)
-4090: Max user count reached (Login)
-4089: Unspecified server error (Login, Write)
-4088: Signal is write protected (Write)
-404: Cannot obtain current logged in user name
LogoutUser
Method Definition
void LogoutUser();
Calling Parameters
None
Description
This method logs out any currently logged in user.
SetSecurityServer
Method Definition
void SetSecurityServer(string serverName);
Calling Parameters
serverName Host name of WEBfactory 2010 server
Description
This method sets the WEBfactory 2010 2006 security server in a multi server environment.
For a single WEBfactory 2010 server project it is not necessary to invoke this method.
CheckProjectAuthorization
Method Definition
bool CheckProjectAuthorization(string AuthorizationName);
Calling Parameters
AuthorizationName Name of project authorization
Description
This method returns whether a logged in user has a specific project authorization or not.
GetProjectAuthorizations
Method Definition
List<string> GetProjectAuthorizations();
Description
This method returns the project authorizations of the logged in user. If no user is logged in, or the logged in user has no project authorizations the method returns an empty list.
CheckAuthorizationGroup
Method Definition
bool CheckAuthorizationGroup(string AuthorizationGroupName);
Calling Parameters
AuthorizationGroupName Name of authorization group
Description
This method returns whether a logged in user is member of a specific authorization group or not.
GetAuthorizationGroups
Method Definition
List<string> GetAuthorizationGroups();
Description
This method returns the authorization groups the logged in user is a member of. If no user is logged in, or the logged in user is not a member of any authorization group the method returns an empty list.
CheckSystemAuthorization
Method Definition
bool CheckSystemAuthorization (string AuthorizationName);
Calling Parameters
AuthorizationName Name of system authorization
Description
This methods returns whether a logged in user has a specific system authorization or not.
GetSystemAuthorizations
Method Definition
List<string> GetSystemAuthorizations();
Description
This method returns the system authorizations of the logged in user. If no user is logged in, or the logged in user has no system authorizations the method returns an empty list.
GetSecurtityStatus
Method Definition
SecurityStatus GetSecurtityStatus();
Calling Parameters
None
Description
This method returns the security status of the security server.
This setting can be done inside WEBfactory 2010Studio:
Security Settings for WEBfactory 2010 Server
The return value is an enumeration:
public enum WFSecurityStatus { SecurityUnknown, //Status was not received so far SecurityOn, //Security on the server is on SecurityOff //Security on the server is off }
GetUserName
Method Definition
string GetUserName();
Calling Parameters
None
Description
This method returns user name of currently logged in user. Returned string is empty if no user is logged in.
GetUserLevel
Method Definition
int GetUserLevel();
Calling Parameters
None
Description
This method returns user level of currently logged in user. Returned integer is -1 if no user is logged in.
ChangePasswordAsAdmin
Method Definition
void ChangePasswordAsAdmin(string user, string newPassword); void ChangePasswordAsAdmin(string user, string newPassword, bool isDomainUser); void ChangePasswordAsAdmin(string user, string newPassword, OnResultDelegate resultDelegate); void ChangePasswordAsAdmin(string user, string newPassword, bool isDomainUser, OnResultDelegate resultDelegate);
Calling Parameters
user User name
newPassword New user password
isDomainUser User is in domain
resultDelegate Delegate to function handling the result
Description
This method changes the password of a specific user as administrator. The current logged in user needs the system authorization to change passwords (User Manager User).
There are two methods available. The difference is that one method is able to register a callback which indicates the result of the operation.
The delegate OnResultDelegate is defined as:
void OnResultDelegate(Exception error, int[] results);
The error (type Exception) is a Silverlight error indicator for asynchronous operations. WEBfactory 2010 bypasses this exception to SDK users to make it easier to find communication errors.
Each value of the integer array results may have one of the following values:
0: Success
-4095: User login failed (Login)
-4094: No user logged in (Write)
-4093: Insufficient user authorizations (Write)
-4092: User already logged on (Login)
-4091: Invalid user password (Login)
-4090: Max user count reached (Login)
-4089: Unspecified server error (Login, Write)
-4088: Signal is write protected (Write)
The delegate OnResultDelegate is defined as:
void OnResultDelegate(Exception error, int[] results);
The error (type Exception) is a Silverlight error indicator for asynchronous operations. WEBfactory 2010 bypasses this exception to SDK users to make it easier to find communication errors.
Each value of the integer array results may have one of the following values:
0: Success
-4095: User login failed (Login)
-4094: No user logged in (Write)
-4093: Insufficient user authorizations (Write)
-4092: User already logged on (Login)
-4091: Invalid user password (Login)
-4090: Max user count reached (Login)
-4089: Unspecified server error (Login, Write)
-4088: Signal is write protected (Write)
ChangePasswordAsUser
Method Definition
void ChangePasswordAsUser(string oldPassword, string newPassword); void ChangePasswordAsUser(string oldPassword, string newPassword, bool isDomainUser); void ChangePasswordAsUser(string oldPassword, string newPassword, OnResultDelegate resultDelegate); void ChangePasswordAsUser(string oldPassword, string newPassword, bool isDomainUser, OnResultDelegate resultDelegate);
Calling Parameters
oldPassword Current user password
newPassword New user password
isDomainUser User is in domain
resultDelegate Delegate to function handling the result
Description
This method changes the password of the current logged in user. The user must confirm the password change by providing current password.
There are two methods available. The difference is that one method is able to register a callback which indicates the result of the operation.
The delegate OnResultDelegate is defined as:
void OnResultDelegate(Exception error, int[] results);
The error (type Exception) is a Silverlight error indicator for asynchronous operations. WEBfactory 2010 bypasses this exception to SDK users to make it easier to find communication errors.
Each value of the integer array results may have one of the following values:
0: Success
-4095: User login failed (Login)
-4094: No user logged in (Write)
-4093: Insufficient user authorizations (Write)
-4092: User already logged on (Login)
-4091: Invalid user password (Login)
-4090: Max user count reached (Login)
-4089: Unspecified server error (Login, Write)
-4088: Signal is write protected (Write)
The delegate OnResultDelegate is defined as:
void OnResultDelegate(Exception error, int[] results);
The error (type Exception) is a Silverlight error indicator for asynchronous operations. WEBfactory 2010 bypasses this exception to SDK users to make it easier to find communication errors.
Each value of the integer array results may have one of the following values:
0: Success
-4095: User login failed (Login)
-4094: No user logged in (Write)
-4093: Insufficient user authorizations (Write)
-4092: User already logged on (Login)
-4091: Invalid user password (Login)
-4090: Max user count reached (Login)
-4089: Unspecified server error (Login, Write)
-4088: Signal is write protected (Write)
UserContextChanged
Event Definition
event OnUserContextChangedEventHandler UserContextChanged; delegate void OnUserContextChangedEventHandler(string userName);
Calling Parameters
userName Name of current user
Description
The event UserContextChanged is fired after a user logs in or logs out. The event handler has one calling parameter which indicates the current logged in user. If userName is null, no user is logged in.
GetIsDomainUser
Method Definition
bool GetIsDomainUser();
Calling Parameters
None
Description
This method returns if the user is domain user or not.
Security operations example
Check out these easy step based guides in order to learn how te WEBfactory 2010 Client SDK security operations work.
In the following tutorial, you will learn to extend the ClientSDKExample with a simple login system and a section that will display the logged user's project and system authorizations. For this, we will add several new controls to the project: a TextBox, a PasswordBox, two buttons and six text blocks.
The following tutorial is based on he solution build in the Internationalization Operations tutorial.
In order to complete the steps described below, WEBfactory 2010 Server must be running and the Demo database must be loaded in WEBfactory 2010Studio.
The User and Authorization used in the following tutorial must be defined in WEBfactory 2010 User Manager.
All versions of Microsoft Visual Studio and Microsoft Expression Blend can be used to create this example. For extended compatibility, we will use Microsoft Visual Studio 2010.
The guide is split in three sections:
The final solution is available for download here:
Make sure to unblock any downloaded file before using it. Windows automatically blocks the files coming from the internet for security reasons.
If downloading a Visual Studio solution, make sure to update all the references marked with the warning symbol before building it.
Editing the XAML
To demonstrate the Security operations available in the Client SDK, we need to add a new StackPanel section to our application, and inside it, several new controls: a TextBox, a PasswordBox, two buttons and six text blocks.
Using Microsoft Visual Studio
In the ClientSDKExample solution, go to the Solution Explorer and open the MainPage.xaml.
In the horizontal StackPanel container, add a new vertical StackPanel to hold our new controls. Set the Margin attribute to 2.
<StackPanel Orientation="Vertical" Margin="2"> </StackPanel>
Inside the new StackPanel, add a TextBlock control to act as a label for our new section. Set its Textproperty to Security and its FontWeight attribute to Bold.
<StackPanel Orientation="Vertical" Margin="2"> <TextBlock Text="Security" FontWeight="Bold"></TextBlock> </StackPanel>
Add a TextBox named UserNameBox and a PasswordBox named PasswordBox at the bottom of the vertical StackPanel container:
<StackPanel Orientation="Vertical" Margin="2"> <TextBlock Text="Security" FontWeight="Bold"></TextBlock> <TextBox Name="UserNameBox" /> <PasswordBox Name="PasswordBox" /> </StackPanel>
Add two Button controls below the previously added controls and name them LoginButton and LogoutButton. Add the Content property for both buttons and fill it with the appropriate text (Login and Logout):
<StackPanel Orientation="Vertical" Margin="2"> <TextBlock Text="Security" FontWeight="Bold"></TextBlock> <TextBox Name="UserNameBox" /> <PasswordBox Name="PasswordBox" /> <Button Name="LoginButton" Content="Log in"></Button> <Button Name="LogoutButton" Content="Log out"></Button> </StackPanel>
For the LoginButton and LogoutButton, define the Click events:
<Button Name="LoginButton" Content="Log in" Click="LoginButton_Click"></Button> <Button Name="LogoutButton" Content="Log out" Click="LogoutButton_Click"></Button>
Add the six text blocks to display the logged in user and the corresponding project and system authorizations. While only three TextBlock elements will be used to display the logged user and its authorizations, the other TextBlock elements will act as labels, indicating the displayed information.
<StackPanel Orientation="Vertical" Margin="2"> <TextBlock Text="Security" FontWeight="Bold"></TextBlock> <TextBox Name="UserNameBox" /> <PasswordBox Name="PasswordBox" /> <Button Name="LoginButton" Content="Log in" Click="LoginButton_Click"></Button> <Button Name="LogoutButton" Content="Log out" Click="LogoutButton_Click"></Button> <TextBlock Text="Logged user:" FontWeight="Bold"></TextBlock> <TextBlock Name="UserLabel"></TextBlock> <TextBlock Text="Project Authorizations:" FontWeight="Bold"></TextBlock> <TextBlock Name="ProjectAuthorizationsLabel"></TextBlock> <TextBlock Text="System Authorizations:" FontWeight="Bold"></TextBlock> <TextBlock Name="SystemAuthorizationsLabel"></TextBlock> </StackPanel>
Using Microsoft Expression Blend
Using the Assets panel, add the following controls on the MainPage:
A TextBlock displaying the Security text, with Bold fonts.
A TextBox named UserNameBox.
A PasswordBox named PasswordBox.
A Button, named LoginButton and with the contents set to Log in.
A Button, named LogoutButton and with the contents set to Log out.
A TextBlock displaying the Logged user text, with Bold fonts, to act as a label.
A TextBlock named UserLabel.
A TextBlock displaying the Project Authorizations text, with Bold fonts, to act as a label.
A TextBlock named ProjectAuthorizationsLabel.
A TextBlock displaying the System Authorizations text, with Bold fonts, to act as a label.
A TextBlock named SystemAuthorizationsLabel.
Programming the application
The programming part of the ClientSDKExample goes the same for both Microsoft Visual Studio and Expression Blend, though it is highly recommended to use Microsoft Visual Studio for programming.
Use the Solution Explorer to open the MainPage.xaml.cs.
On the UserControl_Loaded event, register to the UserContextChanged event when at run time:
wfConnector.UserContextChanged += UserContextChanged;
Next, we will handle the UserContextChanged event. On the UserContextChanged event, we will check to see if any user name has been submitted and display the user name in the UserLabel TextBlock if so, or if no user name is submitted, show that no user is logged in using the UserLabel TextBlock:
private void UserContextChanged(string userName) { if (string.IsNullOrEmpty(userName)) { UserLabel.Text = "No logged user"; } else { UserLabel.Text = userName; } }
As usual, we will need to unregister from the UserContextChanged when the application is closed. We need to add the following line in the
DisposeConnector()
method:wfConnector.UserContextChanged -= UserContextChanged;
Login functionality
Now it's time to handle the login. Define the Click event for the LoginButton. We will call the
Login()
method on this event, with the content of the UserNameBox and PasswordBox as parameters:private void LoginButton_Click(object sender, RoutedEventArgs e) { Login(UserNameBox.Text, PasswordBox.Password); }
Create the
Login()
method. TheLogin()
method will initialize the login attempt and catch any exceptions:private void Login(string userName, string password) { try { TryLogin( userName, password); } catch (Exception ex) { MessageBox.Show(string.Format("{0} {1}", GetType().Name, ex.Message)); } }
Create the
TryLogin()
method. It will check the user name not to be null and proceed with calling theLoginUser()
method from the connector. TheLoginUser()
method will return the OnLoginResultHandler event.private void TryLogin(string userName, string password) { if (string.IsNullOrEmpty(userName)) return; wfConnector.LoginUser( userName, password, OnLoginResultHandler); }
On the OnLoginResultHandler event, we will call a new
HandleLoginAttemptResult()
method to handle the login attempt.private void OnLoginResultHandler(Exception error, int[] results) { HandleLoginAttemptResult(error, results); }
The HandleLoginAttemptResult will check if the login attempt was successful or not. If successful, the
IsSuccessful()
method will return true and the connector will proceed with the login internally. If not successful, it calls theHandleLoginAttemptFailure()
method:private void HandleLoginAttemptResult(Exception error, int[] results) { var errorCode = results == null ? 0 : results.FirstOrDefault(); if (!IsSuccessful(error, results)) { HandleLoginAttemptFailure(error, errorCode); } }
The
IsSuccessful()
method returns true when theOnLoginResultHandler()
returns a null error and the errorCode is 0. If the method returns true, the login will be done by the connector.private bool IsSuccessful(Exception error, IEnumerable<int> results) { var errorCode = results == null ? 0 : results.FirstOrDefault(); return error == null && errorCode == 0; }
Next, we need to handle the login attempt failure. The
HandleLoginAttemptFailure()
method will display an error message with the information obtained using the error code from theGetTextFromErrorCode()
method:private void HandleLoginAttemptFailure(Exception error, int errorCode) { string errorMessage = error != null ? error.Message //If there is an error in communicating with the server, the error message will be displayed : GetTextFromErrorCode(errorCode); //If there was no error in communicating with the server, it will display the text for an error code MessageBox.Show(errorMessage); }
The GetTextFromErrorCode method will return the translations of the error codes:
private string GetTextFromErrorCode(int errorCode) { if (errorCode == 0) return "Login attempt failed"; string translation = null; switch (errorCode) { case -404: translation = "Login failed - cannot obtain current logged in user name"; break; case -4082: translation = "Login failed - the number of failed logins exceeded. Username blocked."; break; case -4086: translation = "Login failed - invalid command syntax"; break; case -4087: translation = "Login failed - expired password"; break; case -4089: translation = "Login failed - internal server error"; break; case -4090: translation = "Login failed - max count reached"; break; case -4091: translation = "Login failed - invalid username or password"; break; case -4092: translation = "Login failed - already logged on"; break; case -4094: translation = "Login failed - invalid username or password"; break; default: translation = "Login attempt failed"; break; } return translation; }
Logout functionality
We will start by handling the LogoutButton Click event. On this Click event ,we will call a new Logout()
method.
private void LogoutButton_Click(object sender, RoutedEventArgs e) { Logout(); }
The Logout method called by the Click event handler will try to initialize the LogoutUser()
method of the connector and catch any exceptions if the LogoutUser()
fails:
private void Logout() { try { wfConnector.LogoutUser(); } catch (Exception ex) { MessageBox.Show(string.Format("{0} {1}", GetType().Name, ex.Message)); } }
Enforcing authorizations
Our controls are now programmed to initialize the login and logout procedures from the connector. But to test the real functionality, we will check for Project Authorizations and condition the visibility of one control based on the existence of a specific Project Authorization:
We will create a simple method that will condense all the needed functionality inside a single line of code. The
EnforceAuthorization()
method will enable the SignalInput TextBox control only if the connector finds the Administration Project Authorization for the logged in user.private void EnforceAuthorization() { SignalInput.IsEnabled = wfConnector.CheckProjectAuthorization("Administration"); }
Now this method must be called whenever the UserContextChanged event is triggered, so the SignalInput control is enabled or disabled whenever a user logs in and out. For this, we need to call the
EnforceAuthorization()
method in the UserContextChanged event handler. Place the method call before the existing if statement:private void UserContextChanged(string userName) { EnforceAuthorization(); if (string.IsNullOrEmpty(userName)) { UserLabel.Text = "No logged user"; } else { UserLabel.Text = userName; } }
Displaying authorizations
To display the available authorizations for the logged in user, we need to check for them each time the user context changes and display them in the Text attributes of the corresponding TextBlock controls.
On the UserContextChanged()
method, call two new methods: ObtainProjectAuthorizations()
and ObtainSystemAuthorizations()
.
private void UserContextChanged(string userName) { EnforceAuthorization(); ObtainProjectAuthorizations(); ObtainSystemAuthorizations(); if (string.IsNullOrEmpty(userName)) { UserLabel.Text = "No logged user"; } else { UserLabel.Text = userName; } }
Now let's define the first method, the ObtainProjectAuthorizations()
. This method will get the project authorization list for the logged in user and place the results as a list of strings in the ProjectAuthorizationLabel TextBlock. Each authorization will be listed on a new line because of the \r\n separator.
private void ObtainProjectAuthorizations() { List<string> UserProjectAuthorizationsList = wfConnector.GetProjectAuthorizations(); string UserProjectAuthorizations = string.Join("\r\n", UserProjectAuthorizationsList.ToArray()); ProjectAuthorizationsLabel.Text = UserProjectAuthorizations; }
In a similar way, we will define the ObtainSystemAuthorizations()
method.
private void ObtainSystemAuthorizations() { List<string> UserSystemAuthorizationsList = wfConnector.GetSystemAuthorizations(); string UserSystemAuthorizations = string.Join("\r\n", UserSystemAuthorizationsList.ToArray()); SystemAuthorizationsLabel.Text = UserSystemAuthorizations; }
Building and testing the application
Press F5 to build and run the solution. Make sure that the correct database (containing the used signals, users and authorizations) is loaded and the WEBfactory 2010 Server is started.
The final solution is available for download here
Make sure to unblock any downloaded file before using it. Windows automatically blocks the files coming from the internet for security reasons.
If downloading a Visual Studio solution, make sure to update all the references marked with the warning symbol before building it.