예제 #1
0
 private static void AddUserToCache(X509Identifier certificateId, ADUser user)
 {
     if (!CertificateAuthenticationModule.IsUserCacheEnabled())
     {
         return;
     }
     CertificateAuthenticationModule.certCache.AddUser(certificateId, user);
 }
예제 #2
0
 private static ADUser GetUserFromCache(X509Identifier certificateId)
 {
     if (!CertificateAuthenticationModule.IsUserCacheEnabled())
     {
         return(null);
     }
     return(CertificateAuthenticationModule.certCache.GetUser(certificateId));
 }
예제 #3
0
        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");
        }
예제 #4
0
        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);
        }
예제 #5
0
 private static X509Identifier CreateCertificateIdentity(HttpClientCertificate certificate)
 {
     return(new X509Identifier(CertificateAuthenticationModule.InvertDn(certificate.Issuer), CertificateAuthenticationModule.InvertDn(certificate.Subject)));
 }
예제 #6
0
        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;
                }
            }
        }