Files
ShrlAlgoToolkit/WPFUI.Test/Web/AuthenticationService.cs
2026-01-01 10:02:59 +08:00

115 lines
4.0 KiB
C#

using System;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Flurl.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
namespace WPFUI.Test.Web
{
public class AuthenticationService
{
private readonly DispatcherTimer _sessionTimer;
private readonly TimeSpan _sessionTimeout = TimeSpan.FromMinutes(30); // 单次 Session 时长
public bool IsAuthenticated { get; private set; }
public event Action SessionExpired;
public event Action LoggedOut;
public AuthenticationService()
{
_sessionTimer = new DispatcherTimer { Interval = _sessionTimeout };
_sessionTimer.Tick += (s, e) =>
{
Logout();
SessionExpired?.Invoke();
};
}
public async Task<ResponseVO> LoginAsync(string username, string password)
{
try
{
// 1. 取公钥
var keyJson = await Settings.Default.PublicKeyUrl.GetStringAsync();
var pubKeyVO = JsonConvert.DeserializeObject<PublicKeyVO>(keyJson);
if (pubKeyVO.Successful)
{
// 2. 用 BouncyCastle 加密
var encrypted = RSAHelper.EncryptByJavaKey(pubKeyVO.Data.PublicKey, $"{password}");
var jsonData = $"{{\"accountName\":\"{username}\",\"password\":\"{encrypted}\",\"uuid\":\"{pubKeyVO.Data.UUID}\",\"appVersion\":\"newversion\"}}";
// 3. 发送登录请求
var respones = GetStreamReader(Settings.Default.LoginUrl, jsonData);
var settings = new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Ignore
};
return JsonConvert.DeserializeObject<ResponseVO>(respones, settings);
}
else
{
MessageBox.Show("获取不到用户公钥信息,请联系管理员");
return null;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return null;
}
}
private string GetStreamReader(string url, string postData, string auth = "", int timeout = 60000, string encode = "utf-8", string contentType = "application/json", string method = "POST")
{
var data = Encoding.GetEncoding(encode).GetBytes(postData);
var webRequest = (HttpWebRequest)WebRequest.Create(url);
if (!string.IsNullOrWhiteSpace(auth))
{
var athu = "Authorization:" + auth;
var whc = new WebHeaderCollection();
whc.Add(athu);
webRequest.Headers.Add(whc);
}
webRequest.Method = method;
webRequest.ContentType = contentType + ";" + encode;
webRequest.ContentLength = data.Length;
webRequest.Timeout = timeout;
var requestStream = webRequest.GetRequestStream();
requestStream.Write(data, 0, data.Length);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
var responseStream = webResponse.GetResponseStream();
if (responseStream == null) { return ""; }
var streamReader = new StreamReader(responseStream, Encoding.GetEncoding(encode));
return streamReader.ReadToEnd();
}
public void Logout()
{
if (IsAuthenticated)
{
IsAuthenticated = false;
_sessionTimer.Stop();
LoggedOut?.Invoke();
}
}
}
}