private static ClientContext CreateContext(string contextUrl, ICredentials credentials) { ClientContext context; if (!String.IsNullOrEmpty(Realm) && !String.IsNullOrEmpty(AppId) && !String.IsNullOrEmpty(AppSecret)) { AuthenticationManager am = new AuthenticationManager(); context = am.GetAppOnlyAuthenticatedContext(contextUrl, Realm, AppId, AppSecret); } else { context = new ClientContext(contextUrl); context.Credentials = credentials; } return context; }
/// <summary> /// Get an AuthenticationManager instance per host Url. Needed to make this work properly, else we're getting access denied /// because of Invalid audience Uri /// </summary> /// <param name="url">Url of the site</param> /// <returns>An instantiated AuthenticationManager</returns> private AuthenticationManager GetAuthenticationManager(string url) { // drop the wild card if still there Uri uri = new Uri(url.Replace("*", "")); if (this.authenticationManagers.ContainsKey(uri.Host)) { return this.authenticationManagers[uri.Host]; } else { AuthenticationManager am = new AuthenticationManager(); this.authenticationManagers.TryAdd(uri.Host, am); return am; } }
private static ClientContext CreateContext(string contextUrl, ICredentials credentials) { ClientContext context; if (!String.IsNullOrEmpty(AppId) && !String.IsNullOrEmpty(AppSecret)) { AuthenticationManager am = new AuthenticationManager(); if (new Uri(DevSiteUrl).DnsSafeHost.Contains("spoppe.com")) { context = am.GetAppOnlyAuthenticatedContext(contextUrl, Core.Utilities.TokenHelper.GetRealmFromTargetUrl(new Uri(DevSiteUrl)), AppId, AppSecret, acsHostUrl: "windows-ppe.net", globalEndPointPrefix:"login"); } else { context = am.GetAppOnlyAuthenticatedContext(contextUrl, AppId, AppSecret); } } else { context = new ClientContext(contextUrl); context.Credentials = credentials; } context.RequestTimeout = Timeout.Infinite; return context; }
public static PnPClientContext CreatePnPClientContext(int retryCount = 10, int delay = 500) { PnPClientContext context; if (!String.IsNullOrEmpty(AppId) && !String.IsNullOrEmpty(AppSecret)) { AuthenticationManager am = new AuthenticationManager(); ClientContext clientContext = null; if (new Uri(DevSiteUrl).DnsSafeHost.Contains("spoppe.com")) { clientContext = am.GetAppOnlyAuthenticatedContext(DevSiteUrl, Core.Utilities.TokenHelper.GetRealmFromTargetUrl(new Uri(DevSiteUrl)), AppId, AppSecret, acsHostUrl: "windows-ppe.net", globalEndPointPrefix: "login"); } else { clientContext = am.GetAppOnlyAuthenticatedContext(DevSiteUrl, AppId, AppSecret); } context = PnPClientContext.ConvertFrom(clientContext, retryCount, delay); } else { context = new PnPClientContext(DevSiteUrl, retryCount, delay); context.Credentials = Credentials; } context.RequestTimeout = Timeout.Infinite; return context; }
// // gives the IAuthenticationModule a chance to update its internal state. // do any necessary cleanup and update the Complete status of the associated Authorization. // internal void Update(HttpWebRequest httpWebRequest) { // // RAID#86753 // [....]: this is just a fix for redirection & kerberos. // we need to close the Context and call ISC() again with the final // blob returned from the server. to do this in general // we would probably need to change the IAuthenticationMdule public interface and // add this Update() method. for now we just have it internally. // // actually this turns out to be quite handy for 2 more cases: // NTLM auth: we need to clear the connection group after we suceed to prevent leakage. // Digest auth: we need to support stale credentials, if we fail with a 401 and stale is true we need to retry. // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::Update() httpWebRequest#" + ValidationHelper.HashString(httpWebRequest) + " Authorization#" + ValidationHelper.HashString(Authorization) + " ResponseStatusCode:" + httpWebRequest.ResponseStatusCode.ToString()); if (Authorization != null) { PrepareState(httpWebRequest); ISessionAuthenticationModule myModule = Module as ISessionAuthenticationModule; if (myModule != null) { // // the whole point here is to complete the Security Context. Sometimes, though, // a bad cgi script or a bad server, could miss sending back the final blob. // in this case we won't be able to complete the handshake, but we'll have to clean up anyway. // string challenge = httpWebRequest.AuthHeader(AuthenticateHeader); GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::Update() Complete:" + Authorization.Complete.ToString() + " Module:" + ValidationHelper.ToString(Module) + " challenge:" + ValidationHelper.ToString(challenge)); if (!IsProxyAuth && httpWebRequest.ResponseStatusCode == HttpStatusCode.ProxyAuthenticationRequired) { // // don't call Update on the module, since there's an ongoing // handshake and we don't need to update any state in such a case // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::Update() skipping call to " + myModule.ToString() + ".Update() since we need to reauthenticate with the proxy"); } else { bool complete = true; try { complete = myModule.Update(challenge, httpWebRequest); GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::Update() " + myModule.ToString() + ".Update() returned complete:" + complete.ToString()); } catch (Exception exception) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::Update() " + myModule.ToString() + ".Update() caught exception:" + exception.Message); ClearSession(httpWebRequest); #if !FEATURE_PAL if ((httpWebRequest.AuthenticationLevel == AuthenticationLevel.MutualAuthRequired) && (httpWebRequest.CurrentAuthenticationState == null || httpWebRequest.CurrentAuthenticationState.Authorization == null || !httpWebRequest.CurrentAuthenticationState.Authorization.MutuallyAuthenticated)) { throw; } #endif // !FEATURE_PAL } catch { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::Update() " + myModule.ToString() + ".Update() caught exception: Non-CLS Compliant Exception"); ClearSession(httpWebRequest); #if !FEATURE_PAL if ((httpWebRequest.AuthenticationLevel == AuthenticationLevel.MutualAuthRequired) && (httpWebRequest.CurrentAuthenticationState == null || httpWebRequest.CurrentAuthenticationState.Authorization == null || !httpWebRequest.CurrentAuthenticationState.Authorization.MutuallyAuthenticated)) { throw; } #endif // !FEATURE_PAL } Authorization.SetComplete(complete); } } // // If authentication was successful, create binding between // the request and the authorization for future preauthentication // if (Module != null && Authorization.Complete && Module.CanPreAuthenticate && httpWebRequest.ResponseStatusCode != StatusCodeMatch) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::Update() handshake is Complete calling BindModule()"); AuthenticationManager.BindModule(ChallengedUri, Authorization, Module); } } }
// // attempts to authenticate the request: // returns true only if it succesfully called into the AuthenticationManager // and got back a valid Authorization and succesfully set the appropriate auth headers // internal bool AttemptAuthenticate(HttpWebRequest httpWebRequest, ICredentials authInfo) { // // Check for previous authentication attempts or the presence of credentials // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() httpWebRequest#" + ValidationHelper.HashString(httpWebRequest) + " AuthorizationHeader:" + AuthorizationHeader.ToString()); if (Authorization != null && Authorization.Complete) { // // here the design gets "dirty". // if this is proxy auth, we might have been challenged by an external // server as well. in this case we will have to clear our previous proxy // auth state before we go any further. this will be broken if the handshake // requires more than one dropped connection (which NTLM is a border case for, // since it droppes the connection on the 1st challenge but not on the second) // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization!=null Authorization.Complete:" + Authorization.Complete.ToString()); if (IsProxyAuth) { // // so, we got passed a 407 but now we got a 401, the proxy probably // dropped the connection on us so we need to reset our proxy handshake // Consider: this should have been taken care by Update() // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() ProxyAuth cleaning up auth status"); ClearAuthReq(httpWebRequest); } return(false); } if (authInfo == null) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() authInfo==null Authorization#" + ValidationHelper.HashString(Authorization)); return(false); } string challenge = httpWebRequest.AuthHeader(AuthenticateHeader); if (challenge == null) { // // the server sent no challenge, but this might be the case // in which we're succeeding an authorization handshake to // a proxy while a handshake with the server is still in progress. // if the handshake with the proxy is complete and we actually have // a handshake with the server in progress we can send the authorization header for the server as well. // if (!IsProxyAuth && Authorization != null && httpWebRequest.ProxyAuthenticationState.Authorization != null) { httpWebRequest.Headers.Set(AuthorizationHeader, Authorization.Message); } GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() challenge==null Authorization#" + ValidationHelper.HashString(Authorization)); return(false); } // // if the AuthenticationManager throws on Authenticate, // bubble up that Exception to the user // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() challenge:" + challenge); PrepareState(httpWebRequest); try { Authorization = AuthenticationManager.Authenticate(challenge, httpWebRequest, authInfo); } catch (Exception exception) { Authorization = null; GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::PreAuthIfNeeded() PreAuthenticate() returned exception:" + exception.Message); ClearSession(httpWebRequest); throw; } catch { Authorization = null; GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::PreAuthIfNeeded() PreAuthenticate() returned exception: Non-CLS Compliant Exception"); ClearSession(httpWebRequest); throw; } if (Authorization == null) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization==null"); return(false); } if (Authorization.Message == null) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization.Message==null"); Authorization = null; return(false); } UniqueGroupId = Authorization.ConnectionGroupId; GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() AuthorizationHeader:" + AuthorizationHeader + " blob: " + Authorization.Message.Length + "bytes Complete:" + Authorization.Complete.ToString()); try { // // a "bad" module could try sending bad characters in the HTTP headers. // catch the exception from WebHeaderCollection.CheckBadChars() // fail the auth process // and return the exception to the user as InnerException // httpWebRequest.Headers.Set(AuthorizationHeader, Authorization.Message); } catch { Authorization = null; ClearSession(httpWebRequest); throw; } return(true); }