63 lines
2.0 KiB
C#
63 lines
2.0 KiB
C#
using System;
|
|
using System.Net;
|
|
|
|
namespace Laservall.Solidworks.Server
|
|
{
|
|
/// <summary>
|
|
/// Per-session auth token. Passed to browser via URL fragment (#token=xxx),
|
|
/// returned via Authorization: Bearer header or ?token= query param.
|
|
/// </summary>
|
|
internal sealed class AuthTokenMiddleware
|
|
{
|
|
private readonly string _token;
|
|
|
|
public AuthTokenMiddleware()
|
|
{
|
|
_token = Guid.NewGuid().ToString("N");
|
|
}
|
|
|
|
public string Token => _token;
|
|
|
|
public bool IsAuthorized(HttpListenerRequest request)
|
|
{
|
|
if (request.Url.AbsolutePath == "/")
|
|
{
|
|
return true;
|
|
}
|
|
|
|
string authHeader = request.Headers["Authorization"];
|
|
if (!string.IsNullOrEmpty(authHeader))
|
|
{
|
|
const string bearerPrefix = "Bearer ";
|
|
if (authHeader.StartsWith(bearerPrefix, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
string headerToken = authHeader.Substring(bearerPrefix.Length).Trim();
|
|
if (string.Equals(headerToken, _token, StringComparison.Ordinal))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ?token= fallback for SSE/download (can't set custom headers)
|
|
string queryToken = request.QueryString["token"];
|
|
if (!string.IsNullOrEmpty(queryToken))
|
|
{
|
|
return string.Equals(queryToken, _token, StringComparison.Ordinal);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static void RejectUnauthorized(HttpListenerResponse response)
|
|
{
|
|
response.StatusCode = 401;
|
|
response.ContentType = "application/json; charset=utf-8";
|
|
byte[] body = System.Text.Encoding.UTF8.GetBytes("{\"error\":\"Unauthorized\"}");
|
|
response.ContentLength64 = body.Length;
|
|
response.OutputStream.Write(body, 0, body.Length);
|
|
response.Close();
|
|
}
|
|
}
|
|
}
|