4.2 Adding password authentication
In this section we are going to add a common Login View for our application and a service that performs user authentication by email and password. The final implementation of the authentication will depend on the specific technology we use, and we’ll describe it for each technology in the subsequent sections.
As usual, we will begin with defining the relevant things in our Xomega model. Let's open up the person.xom file, and declare a new data object called AuthenticationObject, which will serve as a data model for our login view. Since it doesn’t represent any persisted object, we will want to turn off modification tracking for it in a custom subclass, so we’ll add a customize attribute, as follows.

Next we will define a new structure "credentials" with two parameters for the email and password, which will be added to our AuthenticationObject as properties.

Notice how we use the “email” type that we defined earlier, and a "plain password" type for the password parameter, which was pre-configured in the Xomega model. Next let's add an operation "authenticate" to the person object, which will use this structure as an input argument. We also don’t want to expose it via REST or WCF APIs, since they’ll use their own standard authentication mechanism, so we’ll configure our operation to not support them, as shown below.

Even though the operation is not going to update anything in the database, we marked it with type "update", so that the Login View would be generated with a Save button and the logic to call this operation with the supplied credentials, which is pretty much what we want for the Login button. So let's go ahead, and add the actual Login View definition in the model as follows.

Let's have a look at some things that we have configured on our Login View. We will need to customize the logic for the generated view to implement the actual authentication for each specific technology in our application, so we marked it with the customize attribute. We set the child attribute to true, so that this view would not be added to the main menu by the generator. We set our AuthenticationObject as the view model for the view. We used the standard layout for the view, but we overrode it to make the fields stack up as one column instead of two, and also to set some size.
These are all the changes that we need in the model, so we can go ahead and build the model project now. Once the model build finishes, let's open the PersonServiceCustomized.cs under the generated PersonService.cs, and provide a custom implementation for the Authenticate method as shown below.

This is where we would need to hash the user supplied password using the salt that is stored in the database along with the hashed password, and compare the result with the latter. For ease of testing though, we will instead just compare it with a hardcoded word "password" for now. If the email address is not found or the password is not valid, we’ll report a critical error using the generated constant InvalidCredentials for the message that we’ve added to the Resources.resx in the .Services.Entities project.
Next, let’s open the generated AuthenticationObjectCustomized.cs in the .Client.Common project, and set it up to not track modifications, as shown below. We also set the IsNew flag to false, so that the view title would say just “Login” and not “New Login”.

With this common code we’ll have an internal operation that can authenticate a person by email and password, and a generated Login View that can collect this information and call that operation when the user clicks the Save button. Presenting the Login view and the actual authentication of the user will need to be implemented for each specific technology, as we’ll see in subsequent sections. Before that though, let’s see how you can write common platform-independent security logic in the business services and the presentation layer.
Next: 4.3 Securing business services >