Skip to content

Commit

Permalink
Merge pull request #105 from davidjrh/fix/stackoverflowex
Browse files Browse the repository at this point in the history
Fix stack overflow issue when validating tokens
  • Loading branch information
davidjrh authored Nov 7, 2023
2 parents 05a0d98 + 028bd7f commit 75d4ad1
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 31 deletions.
2 changes: 1 addition & 1 deletion DotNetNuke.Authentication.Azure/AzureADProvider.dnn
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<dotnetnuke type="Package" version="5.0">
<packages>
<package name="AzureADProvider" type="Auth_System" version="04.04.04">
<package name="AzureADProvider" type="Auth_System" version="04.04.05">
<friendlyName>DNN Azure Active Directory Provider</friendlyName>
<description>
The DNN Azure Active Directory Provider is an Authentication provider for DNN Platform that uses Azure Active Directory OAuth2 authentication to authenticate users.
Expand Down
4 changes: 3 additions & 1 deletion DotNetNuke.Authentication.Azure/AzureADReleaseNotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
<p style="margin: 0"><a href="http://davidjrh.intelequia.com" target="_new">David Rodriguez</a><br /><a href="mailto:davidj@intelequia.com">davidj@intelequia.com</a></p>
<p style="margin: 0"><strong>About the DNN Azure Active Directory Authorization Provider</strong></p>

<p style="margin: 0"><b>Version 04.04.04</b></p>
<p style="margin: 0"><b>Version 04.04.05</b></p>
<p style="margin: 0">
# Maintenance
* Updated project to exclude content from NuGet package by using a .nuspec file
* Properly exclude packages and node_modules
# Bug Fixes
* Fix stack overflow exception
</p>

<p style="margin: 0"><b>Version 04.04.01</b></p>
Expand Down
5 changes: 1 addition & 4 deletions DotNetNuke.Authentication.Azure/Components/AadController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,7 @@ private static UserInfo GetOrCreateCachedUserInfo(JwtSecurityToken jwt, PortalSe
var cache = DotNetNuke.Services.Cache.CachingProvider.Instance();
if (string.IsNullOrEmpty((string)cache.GetItem($"SyncAADToken|{tokenKey}")))
{
var azureClient = new AzureClient(portalSettings.PortalId, AuthMode.Login)
{
JwtIdToken = jwt
};
var azureClient = new AzureClient(portalSettings.PortalId, AuthMode.Login, jwt);
azureClient.SetAuthTokenInternal(jwt.RawData);
azureClient.SetAutoMatchExistingUsers(true);
var userData = azureClient.GetCurrentUserInternal(jwt);
Expand Down
77 changes: 57 additions & 20 deletions DotNetNuke.Authentication.Azure/Components/AzureClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ private GraphClient GraphClient
return _graphClient;
}
}
private readonly AzureConfig Settings;
private AzureConfig Settings;

private List<ProfileMapping> _customClaimsMappings;
public List<ProfileMapping> CustomClaimsMappings
Expand Down Expand Up @@ -250,7 +250,7 @@ public bool PrefixServiceToGroupName
#region Constructors

internal JwtSecurityToken JwtIdToken { get; set; }
public Uri LogoutEndpoint { get; }
public Uri LogoutEndpoint { get; set; }

private bool _autoMatchExistingUsers = false;
public override bool AutoMatchExistingUsers
Expand All @@ -277,18 +277,28 @@ private int GetCalculatedPortalId()

public string RedirectUrl { get; set; }


public AzureClient(int portalId, AuthMode mode)
: base(portalId, mode, AzureConfig.ServiceName)
{
Initialize(portalId, mode, null);
}

public AzureClient(int portalId, AuthMode mode, JwtSecurityToken jwt)
: base(portalId, mode, AzureConfig.ServiceName)
{
Initialize(portalId, mode, jwt);
}

private void Initialize(int portalId, AuthMode mode, JwtSecurityToken jwt)
{
Settings = new AzureConfig(AzureConfig.ServiceName, portalId);

TokenMethod = HttpMethod.POST;


if (!string.IsNullOrEmpty(Settings.TenantId))
{
TokenEndpoint = new Uri(string.Format(Utils.GetAppSetting("AzureAD.TokenEndpointPattern", TokenEndpointPattern), Settings.TenantId));
TokenEndpoint = new Uri(string.Format(Utils.GetAppSetting("AzureAD.TokenEndpointPattern", TokenEndpointPattern), Settings.TenantId));
LogoutEndpoint = new Uri(string.Format(Utils.GetAppSetting("AzureAD.LogoutEndpointPattern", LogoutEndpointPattern), Settings.TenantId, UrlEncode(HttpContext.Current.Request.Url.ToString())));
AuthorizationEndpoint = new Uri(string.Format(Utils.GetAppSetting("AzureAD.AuthorizationEndpointPattern", AuthorizationEndpointPattern), Settings.TenantId));
MeGraphEndpoint = new Uri(string.Format(Utils.GetAppSetting("AzureAD.GraphEndpointPattern", GraphEndpointPattern), Settings.TenantId));
Expand Down Expand Up @@ -317,8 +327,8 @@ public AzureClient(int portalId, AuthMode mode)
AuthTokenName = "AzureUserToken";
OAuthVersion = "2.0";
OAuthHeaderCode = "Basic";
LoadTokenCookie(string.Empty);
JwtIdToken = null;
LoadTokenCookieInternal(string.Empty, jwt == null);
JwtIdToken = jwt;

_prefixServiceToUserName = Settings.UsernamePrefixEnabled;
_prefixServiceToGroupName = Settings.GroupNamePrefixEnabled;
Expand All @@ -333,27 +343,43 @@ public AzureClient(int portalId, AuthMode mode)
return oState.Service == Service;
}

public bool LoadToken(string token)
internal bool LoadTokenInternal(string token, bool verifyToken = true)
{
// Clean token
if (token.Contains("oauth_token="))
{
token = token.Split('&').FirstOrDefault(x => x.Contains("oauth_token=")).Substring("oauth_token=".Length);
}

// Verify token
var aadController = new AadController();
string authorization = string.Empty;
try
if (!verifyToken)
{
authorization = aadController.ValidateAuthHeader(token);
AuthToken = token;
return true;
}
catch (Exception ex)

// Verify token
var cache = DotNetNuke.Services.Cache.CachingProvider.Instance();
// Calculate a hash of a string
var hash = token.GetHashCode().ToString();
var cacheKey = "TokenValidation" + hash;
string username = (string) cache.GetItem(cacheKey);
if (string.IsNullOrEmpty(username))
{
Logger.Error("Error validating token", ex);
var aadController = new AadController();
string authorization = string.Empty;
try
{
authorization = aadController.ValidateAuthHeader(token);
username = string.IsNullOrEmpty(authorization)
? string.Empty
: aadController.ValidateAuthorizationValue(authorization);
}
catch (Exception ex)
{
Logger.Error("Error validating token", ex);
}
}
string username = string.IsNullOrEmpty(authorization) ? null : aadController.ValidateAuthorizationValue(authorization);


if (string.IsNullOrEmpty(username))
{
// If the token is not valid, remove it and redirect to logoff
Expand All @@ -375,20 +401,31 @@ public bool LoadToken(string token)
AuthToken = token;
return true;
}

}

protected new void LoadTokenCookie(string suffix)
public bool LoadToken(string token)
{
return LoadTokenInternal(token);
}

internal void LoadTokenCookieInternal(string suffix, bool verifyToken = true)
{
HttpCookie authTokenCookie = HttpContext.Current.Request.Cookies[this.AuthTokenName + suffix];
if (authTokenCookie != null)
{
if (authTokenCookie.HasKeys)
{
LoadToken(authTokenCookie.Values[OAuthTokenKey]);
LoadTokenInternal(authTokenCookie.Values[OAuthTokenKey], verifyToken);
}
}
}

protected new void LoadTokenCookie(string suffix)
{
LoadTokenCookieInternal(suffix);
}

protected override TimeSpan GetExpiry(string responseText)
{
var jsonSerializer = new JavaScriptSerializer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package >
<metadata>
<id>DotNetNuke.Authentication.Azure</id>
<version>4.4.4</version>
<version>4.4.5</version>
<title>DotNetNuke.Authentication.Azure</title>
<authors>Intelequia Technologies</authors>
<owners>Intelequia Technologies</owners>
Expand Down
4 changes: 2 additions & 2 deletions DotNetNuke.Authentication.Azure/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.4.4.0")]
[assembly: AssemblyFileVersion("4.4.4.0")]
[assembly: AssemblyVersion("4.4.5.0")]
[assembly: AssemblyFileVersion("4.4.5.0")]

4 changes: 2 additions & 2 deletions docs/images/DNNAzureAD_LatestRelease.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 75d4ad1

Please sign in to comment.