Thursday, November 30, 2017

Adding user authentication to a .Net Core Angular project - Part 1

Create a new Angular project
Visual Studio includes a great starter template for using Angular 4 with an ASP.NET Core 2.0 backend.  However, this template lacks some pretty important functionality - authentication and authorisation.  When you create a new project based on this template, the Change Authentication button is disabled and the authentication type is locked at No Authentication.

In this series of posts, I am going to extend this default template to include authentication and authorisation functionality using Microsoft Identity.  At the end of this series, we will have a project that supports the following functionality:
  1. Users will be able to register for the site using their email address.  Registration will require email verification.
  2. Users will also be able to register for the site using a social media account.  I will only include support for Facebook and Google accounts.  This functionality can easily be extended to support plenty of other account providers.
  3. Users will be able to optionally sign in to the site.  We will use JWT tokens for authentication.  We will write Angular route guards to prevent unauthenticated users gaining access to authorised functionality.
  4. We will provide all of the standard account management functionality - change password, sign out, forgot password, etc.
  5. Where appropriate, our forms will be protected using reCaptcha to stop automated posting of sensitive information.
So, strap your self in.  Although this all seems pretty standard functionality, we have quite a lot of work to do before we reach our end goal.

First things first, let's create a project based on the default Angular template in Visual Studio.  I will be using Visual Studio 2017 Enterprise edition and C#.  Start by creating a new ASP.NET Core Web Application.  In honour of my blog host, I will be calling my new project Blogger.
New project dialog

After you choose ASP.NET Core Web Application, you will be presented with a number of project templates.  The Angular template is only available with ASP.NET Core 2.0, so make sure you have selected it in the drop down list at the top of the dialog.  To keep things simple, I am not including Docker support.
New ASP.NET Core 2.0 project types
Restore NPM packages

Select the Angular template and click OK.  Visual Studio does it's thing, and, before you know it, you have an Angular site created.  Now, an important thing to remember with this template is that it is not ready to run straight away.  The template has a lot of NPM dependencies, and these are not included with the project template.  So, to load these, right click the package.json file in the Solution Explorer window and select Restore Packages.  There's a lot to download, so it can take a while.  Use the Bower/npm Output window to track the progress.

As a slight aside, if you work in a company that uses an NTLM web proxy, NPM does not work with these types of proxies.  However, there is a simple fix.  If you don't already have it, install and run Fiddler whilst you are using Visual Studio.  Fiddler performs the necessary proxy authentication required for NPM to run.

Once the NPM packages have all been downloaded, you have a working website.  Run the project and you will see the default site in action.

Angular IE error
Or will you?!?  Well, if you are using any version of Internet Explorer prior to version 12, your website won't run and you will get the error shown on the left.  By default Angular targets "evergreen" browsers which means that some versions of IE are not immediately supported.  Fortunately, you can add support by importing polyfills.  To do this, edit your boot.browser.ts file.  This file is found in the ClientApp folder of your project.  Immediately after the first line, add the line import 'core-js/client/shim';.

Rerun the application, and you will see the default Hello, world! website.
Default ASP.NET Core 2.0 Angular website

Now that we have a working Angular site, in my next post I will modify this default site to add a bootstrap popup to allow the user to register for our site.

Source code (2214k)



Thursday, July 28, 2011

Adobe Media Encoder CS5 - No audio

I have had a unique problem recently where my Adobe Media Encoder (CS4 and CS5) would not encode the audio on a movie.  There were no error messages - there was just no sound.  Examining the resulting FLV file in Audacity showed that there was an audio track with a waveform, however Adobe Media Player and VLC Player would not play the audio.

After much trial and error, I was able to identify the following fix:

  1. Make sure that the video you want to render as an FLV is located on your hard drive.
  2. From the Start menu select Run.
  3. In the Open field, type "msconfig" then click OK.
  4. From the General tab, select "Diagnostic Startup" then click the "OK" button.
  5. At the prompt, select "Restart".
  6. Once your PC has restarted, run AME and encode the video you saved on your hard drive.
  7. Repeat steps 1-5, except select "Normal Startup" instead of "Diagnostic Startup".
Your Adobe Media Encoder should now work correctly.

As far as I can tell, this fix seems to work when using a PC where your Windows profile is stored on a network share.

Wednesday, July 20, 2011

Actionscript compile error - attempted access of inaccessible method through a reference with static type

If you are sure that the class and method that generated this error are all marked as public a simple publish settings change may help to fix the problem.  In the Publish Settings, select the Flash tab.  Then check the Export SWC option.  Then publish your SWF.  The error should be gone.

Tuesday, July 19, 2011

The dreaded "itunes was unable to load provider data from sync services" error

iTunes users (as at version 10.3.1.55) on a network behind an internet proxy requiring a username and password to connect to the internet might get this error when they attempt to synchronise in iTunes. 
The error occurs because iTunes tries to access the internet to load data - and it does not correctly pass your login details to the proxy.  The good news is that there is a very simple work-around.

In iTunes, select the "iTunes Store" option in the left panel.  You will be asked for your proxy username and password.  Enter your details, and select the "Remember password" box.  Click the OK button.  This saves your details in iTunes for the duration of your current iTunes session.

Re-run your sync, and all should work correctly.  The only problem is that you will need to do this each time you restart iTunes.

Monday, January 17, 2011

Getting database activity in a Java agent - Part 1

So you have a requirement to access the user activity log for a database through a Java agent?  The first thing you will discover is that there is no way to access this information through the standard Domino object model.  However, all is not lost - this information can be accessed using the Domino C API.  You just need to code a link between your Java agent and the C API.  This article is the first in a series describing the steps required to create this link.

The easiest way to call a native shared library in a Java agent is using JNA (https://jna.dev.java.net/).  JNA is a Java library that allows Java programs to easily access native shared libraries (DLLs on Windows machines).  The only drawback to its use is that JNA requires a JAR file to be present on the machine on which you wish to run the Java agent (ie. the client for a client side agent or the server for a server side agent).  For the purposes of this article, I will assume that you are creating a server-side Java agent.  In addition, I have assumed that you are running a Windows based server - those running other operating systems will need to translate folder structures/syntax as required.

To install JNA on the server, you will need to download the latest release JAR file from the JNA homepage.  You will need the jna.jar file.  Download this file.  It will need to be copied to the folder <Domino Path>/jvm/lib/ext on your server where <Domino Path> is the path to the Domino installation.  Domino automatically searches this folder for JAR files to include when running Java agents - you will need to restart the HTTP task on the server to load the new JAR file.

You will also need to copy a version of the file to your local machine. You will reference this version of the file when compiling your Java agents in the Domino designer - ensuring you do not get any nasty compile messages when you reference the JNA objects.  Place the JAR file in the <Domino Path>/jvm/lib/ext on your machine where <Domino Path> is the path to the Domino installation.

You are now ready to begin the development of your new agent.  In the Domino designer, create a new Java agent.  From the Project menu, select the Properties option.  In the properties window, click the Java Build Path option.  This opens the Java Build Path window shown in Figure 1 below.

Figure 1 - The Java Build Path window

Select the Libraries tab, then click the Add External JARS... button.  Browse to and select the jna.jar file you copied to your development machine.  Click the OK button to save your change to the build path.

The key to JNA is to define a Java interface that converts the native library call signatures to Java interface methods.  The JNA library provides some helpful classes for defining these interfaces.  If you are interested in the process of defining the interface, the JNA documentation has a good overview here.  The key to the interface definition is that it inherits from the JNA StdCallLibrary class - this will be vital for linking the interface to the Windows API. 

The interface that defines all of the C structures and methods you will require to retrieve a database's user activity log is this:
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.*;

public interface NNotes extends StdCallLibrary {
public class TimeDate extends Structure {
public int innards1;
public int innards2;
}

public class DBActivity extends Structure {
public static class ByReference extends DBActivity implements Structure.ByReference {}

public TimeDate First;
public TimeDate Last;
public int Uses;
public int Reads;
public int Writes;
public int PrevDayUses;
public int PrevDayReads;
public int PrevDayWrites;
public int PrevWeekUses;
public int PrevWeekReads;
public int PrevWeekWrites;
public int PrevMonthUses;
public int PrevMonthReads;
public int PrevMonthWrites;
}

public class DBActivity_Entry extends Structure {
public TimeDate Time;
public short Reads;
public short Writes;
public int UserNameOffset;

public DBActivity_Entry() {}

public DBActivity_Entry(Pointer pointer) {
super(pointer);

// Read the values
read();
}
}

short ConvertTIMEDATEToText(IntByReference IntlFormat, IntByReference TextFormat, Pointer InputTime, Pointer retTextBuffer, short TextBufferLength, ShortByReference retTextLength);
short NSFDbOpen(String dbName, IntByReference dbHhandle);
short NSFDbClose(IntByReference dbHandle);
short NSFDbGetUserActivity(int dbHandle, int Flags, DBActivity.ByReference retDbActivity, IntByReference rethUserInfo, ShortByReference retUserCount);
Pointer OSLockObject(int Handle);
short OSUnlockObject(int Handle);
}
Once you have defined the interface, you can begin writing the agent.  In part 2 of this article, I will describe the steps required to retrieve the database activity.

Wednesday, December 22, 2010

XPages and Server Side Javascript libraries

So, you have created an XPage and you have a Javascript function that you want to reuse in multiple places within the XPage (say, for example, to hide a number of different controls on the page using identical logic).  Where do you place the Javascript function so that you can access it from Server Javascript and not have to rewrite (and maintain) identical code multiple times?  The answer is a "Server Javascript" script library.

You create a "Server Javascript" script library in the same way you would any other script library.  The secret is to change the script library type to "Server Javascript".

Figure 1 - Creating a Server Javascript script library

Give the script library a name and click OK.  The "Server Javascript" editor panel opens.

Figure 2 - The Server Javascript editor panel
This is the editor panel that you should be familiar with from adding Server Javascript to XPages.  Add the Javascript function to your library in the same manner you would if you were adding it direct to your XPage.  When you are finished, save and close the editor.

So, how do you reference your script library from your XPage?  The key is the import keyword.  At the start of your Server Javascript routine, you need to enter the following statement:
import xpages;
where xpages is the name of your Server Javascript script library.  You will then be able to call all of the functions you placed in the script library in your routine.

Monday, June 28, 2010

Introduction to Domino servlets - Part 1

Domino servers support Java servlets.  According to wikipedia, servlets are "a Java class which conforms to the Java Servlet API, a protocol by which a Java class may respond to http requests".

For the Domino developer, it is easiest to think of servlets as Java web agents that sit outside a database.  There are two advantages of using servlets over standard Java web agents:
  1. They are not constrained by the limitations of agents inside a database.  So, for example, a servlet can access the raw HTTP data sent by the browser - whereas this information is already pre-processed in a standard agent and cannot be accessed.  In addition, a servlet can send binary data to a browser - an agent cannot.
  2. They are only loaded into memory the first time they are called.  This means they run more efficiently than standard web agents -  which are loaded into memory every time they run.

In order to use Java servlets, your Domino server needs to enable the Domino Servlet Manager. This is done in the Internet Protocols... section of the server configuration document:


There are a series of configuration options for Java servlets, however, the default options will generally suffice.  You will need to restart the server once the servlet manager has been enabled.

Part 2 of this post will examine how to write a servlet in Java.  The final part will examine how to implement and call them from your Domino server.

Wednesday, June 9, 2010

Domino 8.5 upgrade gotcha

There is a difference in the functionality of the Send method between Domino version 7.0.3 and Domino version 8.5.1.  In Domino 7.0.3, the following code:
Call document.Send(False, "First Person/OU=One/OU=2/O=3; Second Person/OU=Four/OU=Five/O=Six")
would send two e-mails - one to First Person  and another to Second Person.  Domino treated the ";" character as a name separator.

With Domino 8.5.1, this is no longer the case.  Domino no longer recognises the ";" as a name separator.  Instead, it will now attempt to send an e-mail to a person called "First Person/OU=One/OU=2/O=3; Second Person/OU=Four/OU=Five/O=Six" - and will obviously fail.

So, what is the correct code for Domino 8.5?  To achieve the same result as Domino 7.0, your code now needs to be written as follows:
Dim names(1) As String
names(0) = "First Person/OU=One/OU=2/O=3"
names(1) =  "Second Person/OU=Four/OU=Five/O=Six"
Call document.Send(False, names)
The Send method expects an array of strings as the second argument.  The problem is identical, regardless of whether you supply the recipient names as a parameter on the Send method or you add a SendTo field to the document.

Sunday, May 30, 2010

Lotusscript and Windows APIs

Did you know that Lotusscript supports Windows APIs?  Windows APIs are routines that provide access to commonly used lower-level Windows functionality.  There are literally thousands of APIs that provide almost all of the functionality available through Windows.  For example, you could change the caption of a window using an API, you could add a printer to the list of available printers or you could complete many other tasks that cannot be achieved through Lotusscript alone.  Windows APIs are contained in DLL files that are installed when Windows is installed - so they will work on all Windows machines without any additional file installation required.

So, how do you import API functionality into your Lotusscript agent?  You use the Lotusscript Declare keyword. The Declare keyword tells the Lotusscript compiler that a subroutine is not defined in Lotusscript but can instead be found in an external DLL file.

The best way to demonstrate the use of this keyword is by example.  We will create a Lotusscript agent that flashes the foreground window on your desktop - something that cannot be achieved through Lotusscript alone.

In the Declarations section of your agent, enter the following code:
Declare Private Function GetForegroundWindow Lib "user32.dll" () As Long
This declaration imports the GetForegroundWindow API.  This API retrieves the handle to the desk-top foreground window (usually the active window on the desk-top).  A window handle is a unique number identifying a specific window to the Windows operating system.  The declaration tells the compiler that this API can be found in the user32.dll file.  It also tells the compiler that the API returns a value of type Long.  It is important to note that API names are case-sensitive - so, getforegroundwindow is not the same as GetForegroundWindow.

On the next line of the Declarations section of your agent, enter the following code:

Declare Private Function FlashWindow Lib "user32.dll" (Byval hwnd As Long, Byval bInvert As Long) As Long
This declaration imports a second API - FlashWindow.  As with the GetForegroundWindow API, it is  found in the user32.dll file and returns a Long variable.  However, unlike GetForegroundWindow, the FlashWindow API expects two parameters - hwnd and bInvert.  The Declare statement tells Lotusscript what parameters an API expects and the variable type of the parameters.  The purpose of these parameters for this particular API is discussed below.

Now that we have successfully told the Lotusscript compiler about the APIs we will be using, we can write the Lotusscript to call them.  In the Initialize section of your agent, enter the following code:
Dim hWnd As Long

hWnd = GetForegroundWindow()

Call FlashWindow(hWnd, 1)
The first line of code,
hWnd = GetForegroundWindow()
retrieves the handle to the desk-top foreground Window.

The second line of code,
Call FlashWindow(hWnd, 1)
actually causes the window to flash. The first argument (hwnd) is the handle of the window we wish to flash. The second argument (bInvert) is 0 if we want a window to stop flashing, or non-zero if we want a window to start flashing.

Save the agent, then run it.  You will see in the taskbar of Windows the tab for the active window flash. 
This basic structure can be followed for all Windows APIs - and there are thousands of them. They can be used to cleverly extend Lotusscript agents to perform functionality well beyond its standard limitations.

Thursday, May 27, 2010

Domino 8.5

So, my work has just upgraded the first of our Domino servers to version 8.5 - which means I am finally showing interest in some of the new features in the latest release.

In particular, I am so excited that the JVM now runs version 1.6 of Java - giving us access to all of the cool new features in that release of Java. To my mind, this is a step towards providing Domino servers with some of the powerful features that ASP.NET developers have had for some time.