fix token auth issue
This commit is contained in:
parent
73c8d0da33
commit
4534d24fe6
@ -9,25 +9,25 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
{
|
{
|
||||||
internal class TokenAuthentication : ITokenAuthentication
|
internal class TokenAuthentication : ITokenAuthentication
|
||||||
{
|
{
|
||||||
private readonly ConcurrentDictionary<string, TokenState> _tokens;
|
private readonly ConcurrentDictionary<int, TokenState> _tokens;
|
||||||
private readonly RandomNumberGenerator _random;
|
private readonly RandomNumberGenerator _random;
|
||||||
private static readonly TimeSpan TimeoutPeriod = new(0, 0, 120);
|
private static readonly TimeSpan TimeoutPeriod = new(0, 0, 120);
|
||||||
private const short TokenLength = 4;
|
private const short TokenLength = 4;
|
||||||
|
|
||||||
public TokenAuthentication()
|
public TokenAuthentication()
|
||||||
{
|
{
|
||||||
_tokens = new ConcurrentDictionary<string, TokenState>();
|
_tokens = new ConcurrentDictionary<int, TokenState>();
|
||||||
_random = RandomNumberGenerator.Create();
|
_random = RandomNumberGenerator.Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AuthorizeToken(ITokenIdentifier authInfo)
|
public bool AuthorizeToken(ITokenIdentifier authInfo)
|
||||||
{
|
{
|
||||||
var key = BuildKey(authInfo);
|
var authorizeSuccessful = _tokens.ContainsKey(authInfo.ClientId) &&
|
||||||
var authorizeSuccessful = _tokens.ContainsKey(key) && _tokens[key].Token == key;
|
_tokens[authInfo.ClientId].Token == authInfo.Token;
|
||||||
|
|
||||||
if (authorizeSuccessful)
|
if (authorizeSuccessful)
|
||||||
{
|
{
|
||||||
_tokens.TryRemove(key, out _);
|
_tokens.TryRemove(authInfo.ClientId, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
return authorizeSuccessful;
|
return authorizeSuccessful;
|
||||||
@ -36,15 +36,14 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
public TokenState GenerateNextToken(ITokenIdentifier authInfo)
|
public TokenState GenerateNextToken(ITokenIdentifier authInfo)
|
||||||
{
|
{
|
||||||
TokenState state;
|
TokenState state;
|
||||||
var genKey = BuildKey(authInfo);
|
|
||||||
|
|
||||||
if (_tokens.ContainsKey(genKey))
|
if (_tokens.ContainsKey(authInfo.ClientId))
|
||||||
{
|
{
|
||||||
state = _tokens[genKey];
|
state = _tokens[authInfo.ClientId];
|
||||||
|
|
||||||
if (DateTime.Now - state.RequestTime > TimeoutPeriod)
|
if (DateTime.Now - state.RequestTime > TimeoutPeriod)
|
||||||
{
|
{
|
||||||
_tokens.TryRemove(genKey, out _);
|
_tokens.TryRemove(authInfo.ClientId, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -59,12 +58,12 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
TokenDuration = TimeoutPeriod
|
TokenDuration = TimeoutPeriod
|
||||||
};
|
};
|
||||||
|
|
||||||
_tokens.TryAdd(genKey, state);
|
_tokens.TryAdd(authInfo.ClientId, state);
|
||||||
|
|
||||||
// perform some housekeeping so we don't have built up tokens if they're not ever used
|
// perform some housekeeping so we don't have built up tokens if they're not ever used
|
||||||
foreach (var (key, value) in _tokens)
|
foreach (var (key, value) in _tokens)
|
||||||
{
|
{
|
||||||
if ((DateTime.Now - value.RequestTime) > TimeoutPeriod)
|
if (DateTime.Now - value.RequestTime > TimeoutPeriod)
|
||||||
{
|
{
|
||||||
_tokens.TryRemove(key, out _);
|
_tokens.TryRemove(key, out _);
|
||||||
}
|
}
|
||||||
@ -97,7 +96,5 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
_random.Dispose();
|
_random.Dispose();
|
||||||
return token.ToString();
|
return token.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private string BuildKey(ITokenIdentifier authInfo) => $"{authInfo.NetworkId}_${authInfo.Game}";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.SyndicationFeed.ReaderWriter" Version="1.0.2" />
|
<PackageReference Include="Microsoft.SyndicationFeed.ReaderWriter" Version="1.0.2" />
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.15.1" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.16.1" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.15.1" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.16.1" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -31,8 +31,7 @@ namespace IW4MAdmin.Plugins.Login.Commands
|
|||||||
{
|
{
|
||||||
var success = gameEvent.Owner.Manager.TokenAuthenticator.AuthorizeToken(new TokenIdentifier
|
var success = gameEvent.Owner.Manager.TokenAuthenticator.AuthorizeToken(new TokenIdentifier
|
||||||
{
|
{
|
||||||
NetworkId = gameEvent.Origin.NetworkId,
|
ClientId = gameEvent.Origin.ClientId,
|
||||||
Game = gameEvent.Origin.GameName,
|
|
||||||
Token = gameEvent.Data
|
Token = gameEvent.Data
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.15.1" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.16.1" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.15.1" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.16.1" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.15.1" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.16.1" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.15.1" PrivateAssets="All" />
|
<PackageReference Include="RaidMax.IW4MAdmin.SharedLibraryCore" Version="2022.6.16.1" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -24,8 +24,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
{
|
{
|
||||||
var state = gameEvent.Owner.Manager.TokenAuthenticator.GenerateNextToken(new TokenIdentifier
|
var state = gameEvent.Owner.Manager.TokenAuthenticator.GenerateNextToken(new TokenIdentifier
|
||||||
{
|
{
|
||||||
Game = gameEvent.Origin.GameName,
|
ClientId = gameEvent.Origin.ClientId
|
||||||
NetworkId = gameEvent.Origin.NetworkId
|
|
||||||
});
|
});
|
||||||
gameEvent.Origin.Tell(string.Format(_translationLookup["COMMANDS_GENERATETOKEN_SUCCESS"], state.Token,
|
gameEvent.Origin.Tell(string.Format(_translationLookup["COMMANDS_GENERATETOKEN_SUCCESS"], state.Token,
|
||||||
$"{state.RemainingTime} {_translationLookup["GLOBAL_MINUTES"]}", gameEvent.Origin.ClientId));
|
$"{state.RemainingTime} {_translationLookup["GLOBAL_MINUTES"]}", gameEvent.Origin.ClientId));
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
using Data.Models;
|
using SharedLibraryCore.Interfaces;
|
||||||
using SharedLibraryCore.Interfaces;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.Helpers;
|
namespace SharedLibraryCore.Helpers;
|
||||||
|
|
||||||
public class TokenIdentifier : ITokenIdentifier
|
public class TokenIdentifier : ITokenIdentifier
|
||||||
{
|
{
|
||||||
public long NetworkId { get; set; }
|
public int ClientId { get; set; }
|
||||||
public Reference.Game Game { get; set; }
|
|
||||||
public string Token { get; set; }
|
public string Token { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
|
namespace SharedLibraryCore.Interfaces;
|
||||||
using Data.Models;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.Interfaces;
|
|
||||||
|
|
||||||
public interface ITokenIdentifier
|
public interface ITokenIdentifier
|
||||||
{
|
{
|
||||||
long NetworkId { get; }
|
int ClientId { get; }
|
||||||
Reference.Game Game { get; set; }
|
string Token { get; }
|
||||||
string Token { get; set; }
|
|
||||||
}
|
}
|
||||||
|
@ -103,9 +103,8 @@ namespace WebfrontCore.Controllers.API
|
|||||||
{
|
{
|
||||||
var tokenData = new TokenIdentifier
|
var tokenData = new TokenIdentifier
|
||||||
{
|
{
|
||||||
Game = privilegedClient.GameName,
|
ClientId = clientId,
|
||||||
Token = request.Password,
|
Token = request.Password
|
||||||
NetworkId = privilegedClient.NetworkId
|
|
||||||
};
|
};
|
||||||
|
|
||||||
loginSuccess =
|
loginSuccess =
|
||||||
|
@ -41,8 +41,7 @@ namespace WebfrontCore.Controllers
|
|||||||
{
|
{
|
||||||
loginSuccess = Manager.TokenAuthenticator.AuthorizeToken(new TokenIdentifier
|
loginSuccess = Manager.TokenAuthenticator.AuthorizeToken(new TokenIdentifier
|
||||||
{
|
{
|
||||||
NetworkId = privilegedClient.NetworkId,
|
ClientId = clientId,
|
||||||
Game = privilegedClient.GameName,
|
|
||||||
Token = password
|
Token = password
|
||||||
}) ||
|
}) ||
|
||||||
(await Task.FromResult(Hashing.Hash(password, privilegedClient.PasswordSalt)))[0] ==
|
(await Task.FromResult(Hashing.Hash(password, privilegedClient.PasswordSalt)))[0] ==
|
||||||
|
@ -277,8 +277,7 @@ namespace WebfrontCore.Controllers
|
|||||||
{
|
{
|
||||||
var state = Manager.TokenAuthenticator.GenerateNextToken(new TokenIdentifier
|
var state = Manager.TokenAuthenticator.GenerateNextToken(new TokenIdentifier
|
||||||
{
|
{
|
||||||
NetworkId = Client.NetworkId,
|
ClientId = Client.ClientId
|
||||||
Game = Client.GameName
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return string.Format(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_GENERATETOKEN_SUCCESS"],
|
return string.Format(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_GENERATETOKEN_SUCCESS"],
|
||||||
|
@ -454,6 +454,6 @@ img.social-icon {
|
|||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-link .oi {
|
.sidebar-link .oi, .sidebar-link img {
|
||||||
min-width: 16px;
|
min-width: 1.2rem;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user