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.
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); | |
} | |
} | |
} | |
} |
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(); |
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() |
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> |
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.