Skip to content
This repository has been archived by the owner on Jun 30, 2023. It is now read-only.

Commit

Permalink
Merge pull request #99 from MSOpenTech/bugs
Browse files Browse the repository at this point in the history
SSO is broken on WinPhone #77
  • Loading branch information
brentschmaltz committed Aug 26, 2014
2 parents 926acb4 + 6df5d4f commit b66731a
Show file tree
Hide file tree
Showing 19 changed files with 128 additions and 74 deletions.
8 changes: 5 additions & 3 deletions src/ADAL.Common/AcquireTokenInteractiveHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ internal partial class AcquireTokenInteractiveHandler : AcquireTokenHandlerBase

private Uri redirectUri;

private string redirectUriRequestParameter;

private PromptBehavior promptBehavior;

private readonly string extraQueryParameters;
Expand All @@ -52,7 +54,7 @@ public AcquireTokenInteractiveHandler(Authenticator authenticator, TokenCache to

this.redirectUri = redirectUri;

this.VerifyRedirectUriForSsoMode();
this.SetRedirectUriRequestParameter();

if (userId == null)
{
Expand Down Expand Up @@ -85,7 +87,7 @@ protected override void AddAditionalRequestParameters(RequestParameters requestP
{
requestParameters[OAuthParameter.GrantType] = OAuthGrantType.AuthorizationCode;
requestParameters[OAuthParameter.Code] = this.authorizationResult.Code;
requestParameters[OAuthParameter.RedirectUri] = this.redirectUri.AbsoluteUri;
requestParameters[OAuthParameter.RedirectUri] = this.redirectUriRequestParameter;
}

protected override void PostTokenRequest(AuthenticationResult result)
Expand Down Expand Up @@ -134,7 +136,7 @@ private RequestParameters CreateAuthorizationRequest(string loginHint, bool incl
RequestParameters authorizationRequestParameters = new RequestParameters(this.Resource, this.ClientKey);
authorizationRequestParameters[OAuthParameter.ResponseType] = OAuthResponseType.Code;

authorizationRequestParameters[OAuthParameter.RedirectUri] = this.redirectUri.AbsoluteUri;
authorizationRequestParameters[OAuthParameter.RedirectUri] = this.redirectUriRequestParameter;

if (!string.IsNullOrWhiteSpace(loginHint))
{
Expand Down
15 changes: 10 additions & 5 deletions src/ADAL.Common/UserIdentifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,27 @@
namespace Microsoft.IdentityModel.Clients.ActiveDirectory
{
/// <summary>
/// Indicates the type of UserIdentifier
/// Indicates the type of <see cref=" UserIdentifier"/>
/// </summary>
public enum UserIdentifierType
{
/// <summary>
/// UniqueId
/// When a <see cref=" UserIdentifier"/> of this type is passed in a token acquisition operation,
/// the operation is guaranteed to return a token issued for the user with corresponding <see cref=" UserIdentifier.UniqueId"/> or fail.
/// </summary>
UniqueId,

/// <summary>
/// OptionalDisplayableId
/// When a <see cref=" UserIdentifier"/> of this type is passed in a token acquisition operation,
/// the operation restricts cache matches to the value provided and injects it as a hint in the authentication experience. However the end user could overwrite that value, resulting in a token issued to a different account than the one specified in the <see cref=" UserIdentifier"/> in input.
/// </summary>
OptionalDisplayableId,

/// <summary>
/// RequiredDisplayableId
/// When a <see cref=" UserIdentifier"/> of this type is passed in a token acquisition operation,
/// the operation is guaranteed to return a token issued for the user with corresponding <see cref=" UserIdentifier.DisplayableId"/> (UPN or email) or fail
/// </summary>
RequiredDisplayableId,
RequiredDisplayableId
}

/// <summary>
Expand Down
38 changes: 0 additions & 38 deletions src/ADAL.CommonWinRT/AcquireTokenInteractiveHandler.cs

This file was deleted.

2 changes: 2 additions & 0 deletions src/ADAL.CommonWinRT/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ internal static partial class AdalError
{
public const string UnauthorizedUserInformationAccess = "unauthorized_user_information_access";
public const string CannotAccessUserInformation = "user_information_access_failed";
public const string NeedToSetCallbackUriAsLocalSetting = "need_to_set_callback_uri_as_local_setting";
}

internal static partial class AdalErrorMessage
{
public const string CannotAccessUserInformation = "Cannot access user information. Check machine's Privacy settings or initialize UserCredential with userId";
public const string RedirectUriUnsupportedWithPromptBehaviorNever = "PromptBehavior.Never is supported in SSO mode only (i.e. no redirectUri)";
public const string UnauthorizedUserInformationAccess = "Unauthorized accessing user information. Check application's 'Enterprise Authentication' capability";
public const string NeedToSetCallbackUriAsLocalSetting = "You need to add the value of WebAuthenticationBroker.GetCurrentApplicationCallbackUri() to an application's local setting named CurrentApplicationCallbackUri.";
}

internal static class Constant
Expand Down
4 changes: 2 additions & 2 deletions src/ADAL.NET/AcquireTokenInteractiveHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ private static bool IsUserLocal()
return prefix.Equals(Environment.MachineName.ToUpperInvariant());
}

private void VerifyRedirectUriForSsoMode()
private void SetRedirectUriRequestParameter()
{
// There is no special redirectUri for SSO mode on this platform.
this.redirectUriRequestParameter = redirectUri.AbsoluteUri;
}

private static class NativeMethods
Expand Down
3 changes: 0 additions & 3 deletions src/ADAL.WinPhone/ADAL.WinPhone.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@
<DocumentationFile>Microsoft.IdentityModel.Clients.ActiveDirectory.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\ADAL.CommonWinRT\AcquireTokenInteractiveHandler.cs">
<Link>CommonWinRT\AcquireTokenInteractiveHandler.cs</Link>
</Compile>
<Compile Include="..\ADAL.CommonWinRT\AdalEventSource.cs">
<Link>CommonWinRT\AdalEventSource.cs</Link>
</Compile>
Expand Down
35 changes: 32 additions & 3 deletions src/ADAL.WinPhone/AcquireTokenInteractiveHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Core;
using Windows.Security.Authentication.Web;
using Windows.Storage;

namespace Microsoft.IdentityModel.Clients.ActiveDirectory
{
Expand Down Expand Up @@ -59,13 +60,41 @@ internal void AcquireAuthorization()

IDictionary<string, object> payload = new Dictionary<string, object>();
payload[WabArgName.CorrelationId] = this.CallState.CorrelationId.ToString();
payload[WabArgName.RedirectUri] = redirectUri.AbsoluteUri;
payload[WabArgName.RedirectUri] = this.redirectUriRequestParameter;
payload[WabArgName.UserId] = userId.Id;
payload[WabArgName.UserIdType] = (int)userId.Type;
payload[WabArgName.Resource] = this.Resource;
payload[WabArgName.ClientId] = this.ClientKey.ClientId;

webUi.Authenticate(authorizationUri, this.redirectUri, this.ssoMode, payload, this.CallState);
webUi.Authenticate(authorizationUri, this.redirectUri, payload, this.CallState);
}

private void SetRedirectUriRequestParameter()
{
if (ReferenceEquals(this.redirectUri, Constant.SsoPlaceHolderUri))
{
try
{
this.redirectUriRequestParameter = WebAuthenticationBroker.GetCurrentApplicationCallbackUri().AbsoluteUri;
}
catch (FormatException ex)
{
// This is the workaround for a bug in managed Uri class of WinPhone SDK which makes it throw UriFormatException when it gets called from unmanaged code.
const string CurrentApplicationCallbackUriSetting = "CurrentApplicationCallbackUri";
if (ApplicationData.Current.LocalSettings.Values.ContainsKey(CurrentApplicationCallbackUriSetting))
{
this.redirectUriRequestParameter = (string)ApplicationData.Current.LocalSettings.Values[CurrentApplicationCallbackUriSetting];
}
else
{
throw new AdalException(AdalError.NeedToSetCallbackUriAsLocalSetting, AdalErrorMessage.NeedToSetCallbackUriAsLocalSetting, ex);
}
}
}
else
{
this.redirectUriRequestParameter = redirectUri.AbsoluteUri;
}
}

private static class WabArgName
Expand Down
2 changes: 1 addition & 1 deletion src/ADAL.WinPhone/IWebUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal interface IWebUI
{
PromptBehavior PromptBehavior { get; }

void Authenticate(Uri authorizationUri, Uri redirectUri, bool ssoMode, IDictionary<string, object> headersMap, CallState callState);
void Authenticate(Uri authorizationUri, Uri redirectUri, IDictionary<string, object> headersMap, CallState callState);

AuthorizationResult ProcessAuthorizationResult(IWebAuthenticationBrokerContinuationEventArgs args, CallState callState);
}
Expand Down
4 changes: 2 additions & 2 deletions src/ADAL.WinPhone/WebUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public PromptBehavior PromptBehavior
}
}

public void Authenticate(Uri authorizationUri, Uri redirectUri, bool ssoMode, IDictionary<string, object> headersMap, CallState callState)
public void Authenticate(Uri authorizationUri, Uri redirectUri, IDictionary<string, object> headersMap, CallState callState)
{
ValueSet set = new ValueSet();
foreach (string key in headersMap.Keys)
Expand All @@ -54,7 +54,7 @@ public void Authenticate(Uri authorizationUri, Uri redirectUri, bool ssoMode, ID

try
{
WebAuthenticationBroker.AuthenticateAndContinue(authorizationUri, ssoMode ? null : redirectUri, set, WebAuthenticationOptions.None);
WebAuthenticationBroker.AuthenticateAndContinue(authorizationUri, ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri) ? null : redirectUri, set, WebAuthenticationOptions.None);
}
catch (Exception ex)
{
Expand Down
3 changes: 0 additions & 3 deletions src/ADAL.WinRT/ADAL.WinRT.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
</ItemGroup>
<ItemGroup>
<Compile Include="..\ADAL.CommonWinRT\AcquireTokenInteractiveHandler.cs">
<Link>CommonWinRT\AcquireTokenInteractiveHandler.cs</Link>
</Compile>
<Compile Include="..\ADAL.CommonWinRT\AdalEventSource.cs">
<Link>CommonWinRT\AdalEventSource.cs</Link>
</Compile>
Expand Down
10 changes: 9 additions & 1 deletion src/ADAL.WinRT/AcquireTokenInteractiveHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

using Windows.Networking;
using Windows.Networking.Connectivity;
using Windows.Security.Authentication.Web;
using Windows.System.UserProfile;

namespace Microsoft.IdentityModel.Clients.ActiveDirectory
Expand All @@ -40,7 +41,7 @@ protected override async Task PreTokenRequest()
private async Task AcquireAuthorizationAsync()
{
Uri authorizationUri = this.CreateAuthorizationUri(await IncludeFormsAuthParamsAsync(this.CallState));
this.authorizationResult = await webUi.AuthenticateAsync(authorizationUri, this.redirectUri, this.ssoMode, this.CallState);
this.authorizationResult = await webUi.AuthenticateAsync(authorizationUri, this.redirectUri, this.CallState);
}

internal static async Task<bool> IncludeFormsAuthParamsAsync(CallState callState)
Expand Down Expand Up @@ -76,5 +77,12 @@ private async static Task<bool> IsUserLocalAsync(CallState callState)
return true;
}
}

private void SetRedirectUriRequestParameter()
{
this.redirectUriRequestParameter = ReferenceEquals(this.redirectUri, Constant.SsoPlaceHolderUri) ?
WebAuthenticationBroker.GetCurrentApplicationCallbackUri().AbsoluteUri :
this.redirectUri.AbsoluteUri;
}
}
}
2 changes: 1 addition & 1 deletion src/ADAL.WinRT/IWebUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ namespace Microsoft.IdentityModel.Clients.ActiveDirectory.Internal
{
internal interface IWebUI
{
Task<AuthorizationResult> AuthenticateAsync(Uri authorizationUri, Uri redirectUri, bool ssoMode, CallState callState);
Task<AuthorizationResult> AuthenticateAsync(Uri authorizationUri, Uri redirectUri, CallState callState);
}
}
3 changes: 2 additions & 1 deletion src/ADAL.WinRT/WebUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ public WebUI(PromptBehavior promptBehavior, bool useCorporateNetwork)
this.useCorporateNetwork = useCorporateNetwork;
}

public async Task<AuthorizationResult> AuthenticateAsync(Uri authorizationUri, Uri redirectUri, bool ssoMode, CallState callState)
public async Task<AuthorizationResult> AuthenticateAsync(Uri authorizationUri, Uri redirectUri, CallState callState)
{
bool ssoMode = ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri);
if (this.promptBehavior == PromptBehavior.Never && !ssoMode && redirectUri.Scheme != Constant.MsAppScheme)
{
throw new ArgumentException(AdalErrorMessage.RedirectUriUnsupportedWithPromptBehaviorNever, "redirectUri");
Expand Down
1 change: 1 addition & 0 deletions tests/Test.ADAL.WinPhone.Dashboard/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<Button Content="Smoke Test" HorizontalAlignment="Left" Margin="141,34,0,0" VerticalAlignment="Top" Click="Button_Click"/>
<TextBox HorizontalAlignment="Left" Height="386" Margin="21,231,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="345" Name="AccessToken"/>
<controls5:Button Content="Clear Cache" HorizontalAlignment="Left" Margin="139,92,0,0" VerticalAlignment="Top" Click="Button_Click_1"/>
<controls5:Button Content="SSO Test" HorizontalAlignment="Left" Margin="141,149,0,0" VerticalAlignment="Top" Click="SsoButton_Click"/>

</controls5:Grid>
</Page>
26 changes: 25 additions & 1 deletion tests/Test.ADAL.WinPhone.Dashboard/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,14 @@ private async void Button_Click(object sender, RoutedEventArgs e)

private void DisplayToken(AuthenticationResult result)
{
this.AccessToken.Text = result.AccessToken;
if (!string.IsNullOrEmpty(result.AccessToken))
{
this.AccessToken.Text = result.AccessToken;
}
else
{
this.AccessToken.Text = result.ErrorDescription;
}
}

private async void Button_Click_1(object sender, RoutedEventArgs e)
Expand All @@ -108,5 +115,22 @@ private async void Button_Click_1(object sender, RoutedEventArgs e)
this.context = await AuthenticationContext.CreateAsync(sts.Authority);
this.context.TokenCache.Clear();
}

private async void SsoButton_Click(object sender, RoutedEventArgs e)
{
this.AccessToken.Text = string.Empty;

this.context = await AuthenticationContext.CreateAsync(sts.Authority);

var result = await this.context.AcquireTokenSilentAsync(sts.ValidResource, sts.ValidClientId, sts.ValidUserId);
if (result.Status == AuthenticationStatus.Success)
{
this.DisplayToken(result);
}
else
{
this.context.AcquireTokenAndContinue(sts.ValidResource, sts.ValidClientId, null, sts.ValidUserId, this.DisplayToken);
}
}
}
}
2 changes: 1 addition & 1 deletion tests/Test.ADAL.WinPhone.Unit/ReplayerWebUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public PromptBehavior PromptBehavior

public static IDictionary<string, object> LastHeadersMap { get; private set; }

public void Authenticate(Uri authorizationUri, Uri redirectUri, bool ssoMode, IDictionary<string, object> headersMap, CallState callState)
public void Authenticate(Uri authorizationUri, Uri redirectUri, IDictionary<string, object> headersMap, CallState callState)
{
string key = authorizationUri.AbsoluteUri + redirectUri.AbsoluteUri;

Expand Down
Loading

0 comments on commit b66731a

Please sign in to comment.