When building a backend for the TX Text Control Document Editor and Document Viewer, the TX Text Control NuGet packages implement the necessary endpoints and handlers for the communication between the client-side libraries and the backend.

It is recommended that these endpoints be secured using a middleware that checks for an access token. This demo implementation does not create and store access tokens, but illustrates how incoming requests can be checked for an access token. Typically, your actual authorization layer, such as OAuth, creates the access tokens.

The following diagram illustrates the request flow with an integrated custom security middleware.

Security Middleware in ASP.NET Core

The client-side part of the Document Editor or Viewer requests a resource from the backend by sending an access token with the request. The custom security middleware captures this request as part of the request pipeline.

The access token is validated, and if valid, the request is forwarded to the appropriate TX Text Control middleware, and if not, an UnauthorizedAccessException is thrown.

Custom Security Middleware

The middleware implementation is shown in the following code.

namespace TXTextControl
{
public class TXSecurityMiddleware
{
private RequestDelegate m_next;
// stored access token usually retrieved from any storage
// implemented thought OAuth or any other identity protocol
private const string access_token = "821e2f35-86e3-4917-a963-b0c4228d1315";
public TXSecurityMiddleware(RequestDelegate next)
{
m_next = next;
}
public async Task Invoke(HttpContext context)
{
// Check if the request is a TX Text Control request
if (context.WebSockets.IsWebSocketRequest &&
context.WebSockets.WebSocketRequestedProtocols.Contains("TXTextControl.Web") ||
(context.Request.Query.ContainsKey("access_token") &&
context.GetEndpoint()?.DisplayName?.Contains("TXTextControl.Web.MVC.DocumentViewer") == true))
{
// Retrieve access token from the query string
var accessToken = context.Request.Query["access_token"];
// Showcase only: Easy comparison of tokens
if (accessToken != access_token)
{
throw new UnauthorizedAccessException();
}
else
{
await m_next.Invoke(context);
}
}
else if (m_next != null)
{
await m_next.Invoke(context);
}
}
}
}
view raw test.cs hosted with ❤ by GitHub

Access Token

The access token in this example is hard-coded and would normally be generated and validated by the authorization strategy you have in place.

Registering the Middleware

The middleware is registered in the Program.cs request pipeline. The following entries must be added after the app.UseRouting() entry, assuming you have created a backend based on this tutorial.

app.UseWebSockets();
// Add the TX Security Middleware to the request pipeline
app.UseMiddleware<TXTextControl.TXSecurityMiddleware>();
// TX Text Control specific middleware
app.UseTXWebSocketMiddleware();
app.UseTXDocumentViewer();
view raw test.cs hosted with ❤ by GitHub

The order in which requests get processed is very important. You need to add the custom security middleware first, followed by the TX Text Control middleware entries.

Passing the Access Tokens

When the client-side part of the Document Editor or Viewer sends a request to the backend, the access token must be passed with the request. The following code shows how to pass the access token within either the WebSocketURL or BasePath properties.

Document Editor

@using TXTextControl.Web.MVC
@{
// use an access token (for example returned by OAuth)
var sAccessToken = "821e2f35-86e3-4917-a963-b0c4228d1315";
// build WebSocketURL including access token in query string
var sProtocol = (Context.Request.IsHttps) ? "wss://" : "ws://";
var sWebSocketURL = sProtocol + Context.Request.Host
+ "/TXWebSocket?access_token=" + sAccessToken;
}
@Html.TXTextControl().TextControl(settings =>
{
settings.WebSocketURL = sWebSocketURL; // pass built WebSocketURL
}).Render()
view raw test.cshtml hosted with ❤ by GitHub

Document Viewer

@using TXTextControl.Web.MVC.DocumentViewer
@{
// use an access token (for example returned by OAuth)
var sAccessToken = "821e2f35-86e3-4917-a963-b0c4228d1315";
// build BasePath including access token in query string
var sProtocol = (Context.Request.IsHttps) ? "https://" : "http://";
var sBasePathURL = sProtocol + Context.Request.Host
+ "?access_token=" + sAccessToken;
}
<div style="width: 800px; height: 600px;">
@Html.TXTextControl().DocumentViewer(settings =>
{
settings.BasePath = sBasePathURL; // pass the base path
settings.Dock = DocumentViewerSettings.DockStyle.Fill;
}).Render()
</div>
view raw test.cshtml hosted with ❤ by GitHub

Conclusion

Securing document editing and viewing endpoints within web applications is critical to preventing unauthorized access. This article provides a comprehensive guide on integrating security middleware into ASP.NET Core to fortify these endpoints effectively.