private static void AddUserToCache(X509Identifier certificateId, ADUser user) { if (!CertificateAuthenticationModule.IsUserCacheEnabled()) { return; } CertificateAuthenticationModule.certCache.AddUser(certificateId, user); }
private static ADUser GetUserFromCache(X509Identifier certificateId) { if (!CertificateAuthenticationModule.IsUserCacheEnabled()) { return(null); } return(CertificateAuthenticationModule.certCache.GetUser(certificateId)); }
private static void OnAuthenticateRequest(object source, EventArgs args) { Logger.EnterFunction(ExTraceGlobals.CertAuthTracer, "OnAuthenticateRequest"); HttpApplication httpApplication = (HttpApplication)source; HttpContext context = httpApplication.Context; if (context.Request.IsAuthenticated) { Logger.ExitFunction(ExTraceGlobals.CertAuthTracer, "OnAuthenticateRequest"); return; } if (context.Request.ClientCertificate == null || !context.Request.ClientCertificate.IsPresent) { Logger.LogVerbose("No client certificate is found in authenticated request"); Logger.ExitFunction(ExTraceGlobals.CertAuthTracer, "OnAuthenticateRequest"); return; } CertificateAuthenticationModule.InternalOnAuthenticate(context); Logger.ExitFunction(ExTraceGlobals.CertAuthTracer, "OnAuthenticateRequest"); }
private static ADUser ResolveCertificateFromCacheOrAD(HttpClientCertificate certificate, string orgName) { Logger.EnterFunction(ExTraceGlobals.CertAuthTracer, "ResolveCertificateFromCacheOrAD"); X509Identifier x509Identifier = CertificateAuthenticationModule.CreateCertificateIdentity(certificate); ADUser aduser = CertificateAuthenticationModule.GetUserFromCache(x509Identifier); if (aduser == null) { aduser = CertificateAuthenticationModule.ResolveCertificate(x509Identifier, orgName); if (aduser != null) { CertificateAuthenticationModule.AddUserToCache(x509Identifier, aduser); } } else { HttpLogger.SafeAppendGenericInfo("ResolveCertificateFromCacheOrAD", "Cache"); } if (aduser == null) { Logger.LogEvent(CertificateAuthenticationModule.eventLogger, TaskEventLogConstants.Tuple_CertAuth_UserNotFound, certificate.Subject, new object[] { certificate.Subject }); Logger.LogVerbose("Found no user by certificate {0}", new object[] { certificate.Subject }); } else { Logger.LogVerbose("Found user {0} by certificate {1}", new object[] { aduser.Name, certificate.Subject }); } Logger.ExitFunction(ExTraceGlobals.CertAuthTracer, "ResolveCertificateFromCacheOrAD"); return(aduser); }
private static X509Identifier CreateCertificateIdentity(HttpClientCertificate certificate) { return(new X509Identifier(CertificateAuthenticationModule.InvertDn(certificate.Issuer), CertificateAuthenticationModule.InvertDn(certificate.Subject))); }
private static void InternalOnAuthenticate(HttpContext context) { Logger.EnterFunction(ExTraceGlobals.CertAuthTracer, "InternalOnAuthenticate"); HttpRequest request = context.Request; Logger.LogVerbose("Request of Authentication for certificate {0}.", new object[] { request.ClientCertificate.Subject }); int i = 0; ADUser aduser = null; NameValueCollection urlProperties = RedirectionHelper.GetUrlProperties(request.Url); string orgName = urlProperties[CertificateAuthenticationModule.OrganizationDomain]; while (i < CertificateAuthenticationModule.maxRetryForADTransient) { try { aduser = CertificateAuthenticationModule.ResolveCertificateFromCacheOrAD(request.ClientCertificate, orgName); if (aduser != null && !string.IsNullOrEmpty(aduser.UserPrincipalName)) { CertificateAuthenticationFaultInjection.FaultInjectionTracer.TraceTest <string>(3745918269U, aduser.UserPrincipalName); } break; } catch (ADTransientException ex) { if (i == 0) { Logger.LogEvent(CertificateAuthenticationModule.eventLogger, TaskEventLogConstants.Tuple_CertAuth_TransientError, null, new object[] { ex, request.ClientCertificate.Subject }); HttpLogger.SafeAppendGenericInfo("ResolveCertificateFromCacheOrAD-TransientException", ex.Message); } if (i == CertificateAuthenticationModule.maxRetryForADTransient - 1) { HttpLogger.SafeAppendGenericError("ResolveCertificateFromCacheOrAD", ex, new Func <Exception, bool>(KnownException.IsUnhandledException)); } Logger.LogError(string.Format("AD Transient Error when processing certificate authentication {0}.", request.ClientCertificate.Subject), ex); } catch (Exception ex2) { HttpLogger.SafeAppendGenericError("CertAuthNModule.InternalOnAuthenticate", ex2, new Func <Exception, bool>(KnownException.IsUnhandledException)); Logger.LogEvent(CertificateAuthenticationModule.eventLogger, TaskEventLogConstants.Tuple_CertAuth_ServerError, null, new object[] { ex2, request.ClientCertificate.Subject }); Logger.LogError(string.Format("Unknown error when processing certificate authentication {0}.", request.ClientCertificate.Subject), ex2); if (GrayException.IsGrayException(ex2)) { ExWatson.SendReport(ex2, ReportOptions.DoNotCollectDumps, null); } CertificateAuthenticationModule.ReportCustomError(context.Response, HttpStatusCode.InternalServerError, 200, Strings.UnknownInternalError(request.ClientCertificate.Subject)); } i++; } if (i > 0) { HttpLogger.SafeAppendGenericInfo("ResolveCertificateFromCacheOrAD-Retry", i.ToString()); } if (i >= CertificateAuthenticationModule.maxRetryForADTransient) { CertificateAuthenticationModule.ReportCustomError(context.Response, HttpStatusCode.InternalServerError, 201, Strings.ADTransientError(request.ClientCertificate.Subject)); } else if (aduser == null) { HttpLogger.SafeAppendGenericError("ResolveCertificateFromCacheOrAD-ResolvedUser", "null", false); if (request.Headers["Authorization"] == "http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/https/mutual") { CertificateAuthenticationModule.ReportCustomError(context.Response, HttpStatusCode.BadRequest, 102, Strings.UserNotFound(request.ClientCertificate.Subject)); } } else { Logger.LogVerbose("User correctly authenticated and linked to Certificate {0}.", new object[] { request.ClientCertificate.Subject }); if (i > 0) { Logger.LogEvent(CertificateAuthenticationModule.eventLogger, TaskEventLogConstants.Tuple_CertAuth_TransientRecovery, null, new object[] { request.ClientCertificate.Subject, i }); } X509Identifier certId = CertificateAuthenticationModule.CreateCertificateIdentity(request.ClientCertificate); CertificateAuthenticationModule.SetAuthenticatedInfo(context, aduser, certId); } Logger.ExitFunction(ExTraceGlobals.CertAuthTracer, "InternalOnAuthenticate"); }
private static void OnAuthenticateRequest(object source, EventArgs args) { HttpApplication httpApplication = (HttpApplication)source; HttpContext context = httpApplication.Context; if (context.Request.IsAuthenticated) { return; } HttpRequest request = context.Request; if (!CertificateHeaderAuthModule.IsValidCertificateHeaderRequest(request)) { return; } Logger.LogVerbose("Request of Authentication for certificate {0}.", new object[] { request.Headers["X-Exchange-PowerShell-Client-Cert-Subject"] }); int i = 0; while (i < CertificateHeaderAuthModule.maxRetryForADTransient) { try { X509Identifier x509Identifier = CertificateHeaderAuthModule.CreateCertificateIdentity(request); ADUser aduser = CertificateHeaderAuthModule.GetUserFromCache(x509Identifier); if (aduser == null) { aduser = CertificateAuthenticationModule.ResolveCertificate(x509Identifier, null); if (aduser != null) { CertificateHeaderAuthModule.AddUserToCache(x509Identifier, aduser); } } if (aduser == null) { Logger.LogEvent(CertificateHeaderAuthModule.eventLogger, TaskEventLogConstants.Tuple_CertAuth_UserNotFound, request.Headers["X-Exchange-PowerShell-Client-Cert-Subject"], new object[] { request.Headers["X-Exchange-PowerShell-Client-Cert-Subject"], "CertificateHeader" }); Logger.LogVerbose("Certificate authentication succeeded but certificate {0} cannot be mapped to an AD account.", new object[] { request.Headers["X-Exchange-PowerShell-Client-Cert-Subject"] }); break; } IIdentity identity; if (aduser.RecipientTypeDetails == RecipientTypeDetails.LinkedUser) { identity = new GenericIdentity(aduser.Sid.ToString(), "CertificateLinkedUser"); } else { identity = new WindowsIdentity(aduser.UserPrincipalName); } if (!OrganizationId.ForestWideOrgId.Equals(aduser.OrganizationId)) { HttpContext.Current.Items[CertificateAuthenticationModule.TenantCertificateOrganizaitonItemName] = aduser.OrganizationId.OrganizationalUnit.Name; } context.User = new GenericPrincipal(identity, new string[0]); Logger.LogVerbose("User correctly authenticated and linked to Certificate {0}.", new object[] { request.Headers["X-Exchange-PowerShell-Client-Cert-Subject"] }); if (i > 0) { Logger.LogEvent(CertificateHeaderAuthModule.eventLogger, TaskEventLogConstants.Tuple_CertAuth_TransientRecovery, null, new object[] { request.Headers["X-Exchange-PowerShell-Client-Cert-Subject"], i, "CertificateHeader" }); } break; } catch (ADTransientException ex) { i++; if (i == 1) { Logger.LogEvent(CertificateHeaderAuthModule.eventLogger, TaskEventLogConstants.Tuple_CertAuth_TransientError, null, new object[] { ex, request.Headers["X-Exchange-PowerShell-Client-Cert-Subject"], "CertificateHeader" }); } Logger.LogError(string.Format("AD Transient Error when processing certificate authentication {0}.", request.Headers["X-Exchange-PowerShell-Client-Cert-Subject"]), ex); if (i > CertificateHeaderAuthModule.maxRetryForADTransient) { throw; } } catch (Exception ex2) { Logger.LogEvent(CertificateHeaderAuthModule.eventLogger, TaskEventLogConstants.Tuple_CertAuth_ServerError, null, new object[] { ex2, request.Headers["X-Exchange-PowerShell-Client-Cert-Subject"], "CertificateHeader" }); Logger.LogError(string.Format("AD Transient Error when processing certificate authentication {0}.", request.Headers["X-Exchange-PowerShell-Client-Cert-Subject"]), ex2); throw; } } }