public void CanExtractClaimsFromICaeAuthenticationProviderOption() { // Arrange var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://example.com/bar"); var authenticationHandlerOption = new AuthenticationHandlerOption(); var authenticationProviderOption = new CaeAuthProviderOptionTest() { Scopes = new [] { "User.Read" }, Claims = "claim" }; authenticationHandlerOption.AuthenticationProviderOption = authenticationProviderOption; // set the original AuthenticationProviderOptionTest as the auth provider var originalRequestContext = httpRequestMessage.GetRequestContext(); originalRequestContext.MiddlewareOptions[typeof(AuthenticationHandlerOption).ToString()] = authenticationHandlerOption; httpRequestMessage.Properties[typeof(GraphRequestContext).ToString()] = originalRequestContext; // Act by trying to extract info from ICaeAuthenticationProviderOption type AuthenticationProviderOption authProviderOption = httpRequestMessage.GetMsalAuthProviderOption(); // Assert that we can still find the information Assert.Single(authProviderOption.Scopes); Assert.Equal("User.Read", authProviderOption.Scopes[0]); Assert.Equal("claim", authProviderOption.Claims); }
// Test with a request that already has an auth provider option present public async Task AuthHandler_ShouldRetryUnauthorizedGetRequestAndExtractWWWAuthenticateHeadersShouldNotLoseScopesInformation() { // Arrange var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://example.com/bar"); var authenticationHandlerOption = new AuthenticationHandlerOption(); var authenticationProviderOption = new AuthenticationProviderOptionTest { Scopes = new string[] { "User.Read" } }; authenticationHandlerOption.AuthenticationProviderOption = authenticationProviderOption; // set the original AuthenticationProviderOptionTest as the auth provider var originalRequestContext = httpRequestMessage.GetRequestContext(); originalRequestContext.MiddlewareOptions[typeof(AuthenticationHandlerOption).ToString()] = authenticationHandlerOption; httpRequestMessage.Properties[typeof(GraphRequestContext).ToString()] = originalRequestContext; var unauthorizedResponse = new HttpResponseMessage(HttpStatusCode.Unauthorized); unauthorizedResponse.Headers.WwwAuthenticate.Add( new AuthenticationHeaderValue("authorization_url", "authorization_url=\"https://login.microsoftonline.com/common/oauth2/authorize\"," + "error=\"insufficient_claims\"," + "claims=\"eyJhY2Nlc3NfdG9rZW4iOnsibmJmIjp7ImVzc2VudGlhbCI6ZmFsc2UsInZhbHVlIjoxNTM5Mjg0Mzc2fX19\"")); var expectedResponse = new HttpResponseMessage(HttpStatusCode.OK); // Act testHttpMessageHandler.SetHttpResponse(unauthorizedResponse, expectedResponse); var response = await invoker.SendAsync(httpRequestMessage, new CancellationToken()); var requestContext = response.RequestMessage.GetRequestContext(); // Assert var middleWareOption = requestContext.MiddlewareOptions[typeof(AuthenticationHandlerOption).ToString()] as AuthenticationHandlerOption; Assert.NotNull(middleWareOption); var authProviderOption = middleWareOption.AuthenticationProviderOption as ICaeAuthenticationProviderOption; Assert.NotNull(authProviderOption); // Assert the decoded claims string is as expected Assert.Equal("{\"access_token\":{\"nbf\":{\"essential\":false,\"value\":1539284376}}}", authProviderOption.Claims); Assert.Same(response, expectedResponse); Assert.NotSame(response.RequestMessage, httpRequestMessage); // Assert that we still have the original scopes information Assert.Single(authProviderOption.Scopes); Assert.Equal("User.Read", authProviderOption.Scopes[0]); }
/// <summary> /// Sets <see cref="UserAssertion"/> for this request. /// This should only be used with <see cref="OnBehalfOfProvider"/>. /// </summary> /// <param name="baseRequest">The <see cref="IBaseRequest"/>.</param> /// <param name="userAssertion">A <see cref="UserAssertion"/> for the user.</param> public static T WithUserAssertion <T>(this T baseRequest, UserAssertion userAssertion) where T : IBaseRequest { string authHandlerOptionKey = typeof(AuthenticationHandlerOption).ToString(); AuthenticationHandlerOption authHandlerOptions = baseRequest.MiddlewareOptions[authHandlerOptionKey] as AuthenticationHandlerOption; MsalAuthenticationProviderOption msalAuthProviderOption = authHandlerOptions.AuthenticationProviderOption as MsalAuthenticationProviderOption ?? new MsalAuthenticationProviderOption(); msalAuthProviderOption.UserAssertion = userAssertion; authHandlerOptions.AuthenticationProviderOption = msalAuthProviderOption; baseRequest.MiddlewareOptions[authHandlerOptionKey] = authHandlerOptions; return(baseRequest); }
/// <summary> /// Sets MSAL's force refresh flag to <see cref="IAuthenticationProvider"/> for this request. If set to true, <see cref="IAuthenticationProvider"/> will refresh existing access token in cahce. /// This defaults to false if not set. /// </summary> /// <param name="baseRequest">The <see cref="IBaseRequest"/>.</param> /// <param name="forceRefresh">A <see cref="bool"/> flag to determine whether refresh access token or not.</param> public static T WithForceRefresh <T>(this T baseRequest, bool forceRefresh) where T : IBaseRequest { string authHandlerOptionKey = typeof(AuthenticationHandlerOption).ToString(); AuthenticationHandlerOption authHandlerOptions = baseRequest.MiddlewareOptions[authHandlerOptionKey] as AuthenticationHandlerOption; MsalAuthenticationProviderOption msalAuthProviderOption = authHandlerOptions.AuthenticationProviderOption as MsalAuthenticationProviderOption ?? new MsalAuthenticationProviderOption(); msalAuthProviderOption.ForceRefresh = forceRefresh; authHandlerOptions.AuthenticationProviderOption = msalAuthProviderOption; baseRequest.MiddlewareOptions[authHandlerOptionKey] = authHandlerOptions; return(baseRequest); }
/// <summary> /// Sets Microsoft Graph's scopes that will be used by <see cref="IAuthenticationProvider"/> to authenticate this request /// and can be used to perform incremental scope consent. /// This only works with the default authentication handler and default set of Microsoft graph authentication providers. /// If you use a custom authentication handler or authentication provider, you have to handle it's retrieval in your implementation. /// </summary> /// <param name="baseRequest">The <see cref="IBaseRequest"/>.</param> /// <param name="scopes">Microsoft graph scopes used to authenticate this request.</param> public static T WithScopes <T>(this T baseRequest, string[] scopes) where T : IBaseRequest { string authHandlerOptionKey = typeof(AuthenticationHandlerOption).ToString(); AuthenticationHandlerOption authHandlerOptions = baseRequest.MiddlewareOptions[authHandlerOptionKey] as AuthenticationHandlerOption; AuthenticationProviderOption msalAuthProviderOption = authHandlerOptions.AuthenticationProviderOption as AuthenticationProviderOption ?? new AuthenticationProviderOption(); msalAuthProviderOption.Scopes = scopes; authHandlerOptions.AuthenticationProviderOption = msalAuthProviderOption; baseRequest.MiddlewareOptions[authHandlerOptionKey] = authHandlerOptions; return(baseRequest); }
internal static AuthenticationProviderOption GetMsalAuthProviderOption(this HttpRequestMessage httpRequestMessage) { AuthenticationHandlerOption authHandlerOption = httpRequestMessage.GetMiddlewareOption <AuthenticationHandlerOption>(); AuthenticationProviderOption authenticationProviderOption = authHandlerOption?.AuthenticationProviderOption as AuthenticationProviderOption ?? new AuthenticationProviderOption(); // copy the claims and scopes information if (authHandlerOption?.AuthenticationProviderOption is ICaeAuthenticationProviderOption caeAuthenticationProviderOption) { authenticationProviderOption.Claims = caeAuthenticationProviderOption.Claims; authenticationProviderOption.Scopes = caeAuthenticationProviderOption.Scopes; } return(authenticationProviderOption); }
private static T SetParameter <T>(T baseRequest, Action <TokenAcquisitionAuthenticationProviderOption> action) where T : IBaseRequest { string authHandlerOptionKey = typeof(AuthenticationHandlerOption).ToString(); AuthenticationHandlerOption authHandlerOptions = baseRequest.MiddlewareOptions[authHandlerOptionKey] as AuthenticationHandlerOption ?? new AuthenticationHandlerOption(); TokenAcquisitionAuthenticationProviderOption msalAuthProviderOption = authHandlerOptions?.AuthenticationProviderOption as TokenAcquisitionAuthenticationProviderOption ?? new TokenAcquisitionAuthenticationProviderOption(); action(msalAuthProviderOption); #pragma warning disable CS8602 // Dereference of a possibly null reference. The Graph SDK ensures it exists authHandlerOptions.AuthenticationProviderOption = msalAuthProviderOption; #pragma warning restore CS8602 // Dereference of a possibly null reference. baseRequest.MiddlewareOptions[authHandlerOptionKey] = authHandlerOptions; return(baseRequest); }
/// <summary> /// Sets a username (email) and password of an Azure AD account to authenticate. /// This should only be used with <see cref="UsernamePasswordProvider"/>. /// This provider is NOT RECOMMENDED because it exposes the users password. /// We recommend you use <see cref="IntegratedWindowsAuthenticationProvider"/> instead. /// </summary> /// <param name="baseRequest">The <see cref="IBaseRequest"/>.</param> /// <param name="email">Email address of the user to authenticate.</param> /// <param name="password">Password of the user to authenticate.</param> public static T WithUsernamePassword <T>(this T baseRequest, string email, string password) where T : IBaseRequest { string authHandlerOptionKey = typeof(AuthenticationHandlerOption).ToString(); AuthenticationHandlerOption authHandlerOptions = baseRequest.MiddlewareOptions[authHandlerOptionKey] as AuthenticationHandlerOption; MsalAuthenticationProviderOption msalAuthProviderOption = authHandlerOptions.AuthenticationProviderOption as MsalAuthenticationProviderOption ?? new MsalAuthenticationProviderOption(); msalAuthProviderOption.Password = password; msalAuthProviderOption.UserAccount = new GraphUserAccount { Email = email }; authHandlerOptions.AuthenticationProviderOption = msalAuthProviderOption; baseRequest.MiddlewareOptions[authHandlerOptionKey] = authHandlerOptions; return(baseRequest); }
/// <summary> /// Extract TokenAcquisitionAuthenticationProviderOption from request.Properties if it is present /// </summary> /// <param name="httpRequestMessage">Current request message</param> /// <returns>Options set for just this request.</returns> private TokenAcquisitionAuthenticationProviderOption?GetMsalAuthProviderOption(HttpRequestMessage httpRequestMessage) { AuthenticationHandlerOption authHandlerOption = httpRequestMessage.GetMiddlewareOption <AuthenticationHandlerOption>(); return(authHandlerOption?.AuthenticationProviderOption as TokenAcquisitionAuthenticationProviderOption); }
internal static MsalAuthenticationProviderOption GetMsalAuthProviderOption(this HttpRequestMessage httpRequestMessage) { AuthenticationHandlerOption authHandlerOption = httpRequestMessage.GetMiddlewareOption <AuthenticationHandlerOption>(); return(authHandlerOption?.AuthenticationProviderOption as MsalAuthenticationProviderOption ?? new MsalAuthenticationProviderOption()); }