public IAdapterPresentation TryEndAuthentication(IAuthenticationContext context, IProofData proofData, System.Net.HttpListenerRequest request, out System.Security.Claims.Claim[] claims)
        {
            if (proofData?.Properties == null ||
                !proofData.Properties.ContainsKey("ChallengeQuestionAnswer") ||
                context?.Data == null ||
                !context.Data.ContainsKey("upn") ||
                string.IsNullOrEmpty((string)context.Data["upn"]))
            {
                throw new ExternalAuthenticationException("No answer found or corrupted context.", context);
            }

            claims = null;
            IAdapterPresentation result = null;

            var upn  = (string)context.Data["upn"];
            var code = (string)proofData.Properties["ChallengeQuestionAnswer"];

            var secretKey = _secretStorageProvider.GetSecretKey(upn);

            if (TotpAuthenticator.CheckCode(upn, secretKey.Key, code, _usedCodeProvider))
            {
                var claim = new System.Security.Claims.Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://schemas.microsoft.com/ws/2012/12/authmethod/otp");

                claims = new[] { claim };

                if (!secretKey.Activated)
                {
                    secretKey.Activated = true;

                    _secretStorageProvider.SetSecretKey(upn, secretKey);
                }
            }
            else
            {
                result = new AdapterPresentation();
            }

            return(result);
        }
        public IAdapterPresentation TryEndAuthentication(IAuthenticationContext context, IProofData proofData, HttpListenerRequest request, out Claim[] claims)
        {
            /* This method is called by AD FS when the Authentication Adapter should perform the actual authentication.
             * It will pass the IAuthenticationContext to the method, which we have seen before.
             * It will also pass the proofData variable, that implements IProofData.
             * This is a dictionary of strings to objects, that represents whatever you have asked the customer for during the BeginAuthentication method.
             *
             * The method allows you to use the "claims" out parameter. If the Authentication Adapter has successfully performed the authentication,
             * this variable should contain at least one claim with type http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod.
             * The value of this claim should contain the method of authentication used.
             * It must be one of the values listed in the AuthenticationMethods parameter of the class that implements IAuthenticationAdapterMetadata.
             *
             * The method returns a variable of a type that implements IAdapterPresentation.
             * Typically, when authentication has succeeded you add the proper authentication method claim to the claims out parameter, and return null.
             * Whenever authentication has failed, you can create a nice error message for the user and return this in the return variable.
             * */

            if (proofData == null || proofData.Properties == null || !proofData.Properties.ContainsKey("ChallengeQuestionAnswer") || context == null || context.Data == null || !context.Data.ContainsKey("upn") || string.IsNullOrEmpty((string)context.Data["upn"]))
            {
                throw new ExternalAuthenticationException("No answer found or corrupted context.", context);
            }

            claims = null;
            IAdapterPresentation result = null;
            string upn  = (string)context.Data["upn"];
            string code = (string)proofData.Properties["ChallengeQuestionAnswer"];

            if (TOTPAuthenticator.CheckCode(upn, code))
            {
                System.Security.Claims.Claim claim = new System.Security.Claims.Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://schemas.microsoft.com/ws/2012/12/authmethod/otp");
                claims = new System.Security.Claims.Claim[] { claim };
            }
            else
            {
                result = new AdapterPresentation();
            }
            return(result);
        }
        /// <summary>
        /// Called by AD FS to perform the actual authentication.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="proofData"></param>
        /// <param name="request"></param>
        /// <param name="claims"></param>
        /// <returns> If the Authentication Adapter has successfully performed
        /// the authentication a claim of type
        /// http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod
        /// is returned
        /// </returns>
        public IAdapterPresentation TryEndAuthentication(IAuthenticationContext context, IProofData proofData, System.Net.HttpListenerRequest request, out System.Security.Claims.Claim[] claims)
        {
            claims = null;
            IAdapterPresentation result = null;

            // Ensure the submitted form isn't empty.
            if (proofData == null || proofData.Properties == null || !proofData.Properties.ContainsKey("pin"))
            {
                if (this.debugLogging)
                {
                    Logging.LogMessage("Either proofData is null or does not contain required property");
                }
                throw new ExternalAuthenticationException(resMgr.GetString("Error_InvalidPIN", new System.Globalization.CultureInfo(context.Lcid)), context);
            }
            string pin      = proofData.Properties["pin"].ToString();
            string userName = this.identityClaim.Split('\\')[1];

            // Construct RADIUS auth request.
            var authPacket = radiusClient.Authenticate(userName, pin);

            byte[] bIP = IPAddress.Parse(appConfig.NasAddress).GetAddressBytes();
            authPacket.SetAttribute(new RadiusAttribute(RadiusAttributeType.NAS_IP_ADDRESS, bIP));
            var receivedPacket = radiusClient.SendAndReceivePacket(authPacket).Result;

            // Handle no response from RADIUS server.
            if (receivedPacket == null)
            {
                if (this.debugLogging)
                {
                    Logging.LogMessage("No response received from RADIUS server.");
                }
                throw new ExternalAuthenticationException(resMgr.GetString("Error_RADIUS_NULL", new System.Globalization.CultureInfo(context.Lcid)), context);
            }

            // Examine the different RADIUS responses
            switch (receivedPacket.PacketType)
            {
            case RadiusCode.ACCESS_ACCEPT:
                System.Security.Claims.Claim claim = new System.Security.Claims.Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://schemas.microsoft.com/ws/2012/12/authmethod/otp");
                claims = new System.Security.Claims.Claim[] { claim };
                break;

            case RadiusCode.ACCESS_CHALLENGE:
                // No way to cater for this. Fail.
                result = new AdapterPresentation(resMgr.GetString("Error_RADIUS_ACCESS_CHALLENGE", new System.Globalization.CultureInfo(context.Lcid)), false);
                break;

            case RadiusCode.ACCESS_REJECT:
                result = new AdapterPresentation(resMgr.GetString("Error_InvalidPIN", new System.Globalization.CultureInfo(context.Lcid)), false);
                break;

            default:
                result = new AdapterPresentation(resMgr.GetString("Error_RADIUS_OTHER", new System.Globalization.CultureInfo(context.Lcid)), false);
                break;
            }

            if (this.debugLogging)
            {
                Logging.LogMessage(
                    "Processed authentication response." + Environment.NewLine +
                    "Packet Type: " + receivedPacket.PacketType.ToString() + Environment.NewLine +
                    "User: " + this.identityClaim);
            }

            return(result);
        }
Example #4
0
        public IAdapterPresentation TryEndAuthentication(IAuthenticationContext context, IProofData proofData, System.Net.HttpListenerRequest request, out System.Security.Claims.Claim[] claims)
        {
            claims = null;
            IAdapterPresentation result = null;
            string userName             = proofData.Properties["upn"].ToString();
            string userID = proofData.Properties["userID"].ToString();
            string pin    = proofData.Properties["pin"].ToString();

            string windir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);

            System.Configuration.ExeConfigurationFileMap fileMap = new System.Configuration.ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = windir + "\\ADFS\\OktaMFA-ADFS.dll.config";

            System.Configuration.Configuration cfg =
                System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, System.Configuration.ConfigurationUserLevel.None);
            string oktaTenant   = cfg.AppSettings.Settings["Tenant"].Value;
            string authToken    = cfg.AppSettings.Settings["apiKey"].Value;
            string baseUrl      = oktaTenant + "/api/v1/";
            string pinSuccess   = "no";
            string verifyResult = "false";

            HttpWebRequest factorRequest = (HttpWebRequest)WebRequest.Create(baseUrl + "users/" + userID + "/factors");

            factorRequest.Headers.Add("Authorization", authToken);
            factorRequest.Method      = "GET";
            factorRequest.ContentType = "application/json";
            factorRequest.Accept      = "application/json";
            var factorResponse = (HttpWebResponse)factorRequest.GetResponse();
            var factorReader   = new StreamReader(factorResponse.GetResponseStream());
            var factorList     = factorReader.ReadToEnd();

            RootObject[] factors  = JsonConvert.DeserializeObject <RootObject[]>(factorList);
            string       factorID = "";

            foreach (RootObject factor in factors)
            {
                if (factor.factorType == "sms")
                {
                    factorID = factor.id;
                    HttpWebRequest verifyRequest = (HttpWebRequest)WebRequest.Create(baseUrl + "users/" + userID + "/factors/" + factorID + "/verify");
                    verifyRequest.Headers.Add("Authorization", authToken);
                    verifyRequest.Method      = "POST";
                    verifyRequest.ContentType = "application/json";


                    otpCode otpCode = new otpCode
                    {
                        passCode = pin
                    };
                    string otpString = JsonConvert.SerializeObject(otpCode);
                    using (var streamWriter = new StreamWriter(verifyRequest.GetRequestStream()))
                    {
                        streamWriter.Write(otpString);
                    }

                    try
                    {
                        var verifyResponse = (HttpWebResponse)verifyRequest.GetResponse();
                        if (verifyResponse.StatusCode.ToString() == "OK" && pin != "")
                        {
                            pinSuccess = "yes";
                            Claim claim = new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://schemas.microsoft.com/ws/2012/12/authmethod/otp");
                            claims = new Claim[] { claim };
                            return(result);
                        }
                    }
                    catch (WebException we)
                    {
                        var failResponse = we.Response as HttpWebResponse;
                        if (failResponse == null)
                        {
                            throw;
                        }
                        result = new AdapterPresentation("Authentication was unsuccessful, did you enter the sms code correctly?", proofData.Properties["upn"].ToString(), false, proofData.Properties["userID"].ToString());
                    }
                }
            }

            if (pinSuccess == "yes")
            {
                Claim claim = new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://schemas.microsoft.com/ws/2012/12/authmethod/otp");
                claims = new Claim[] { claim };
                return(result);
            }
            else
            {
                result = new AdapterPresentation("Authentication was unsuccessful, did you enter the sms code correctly?", proofData.Properties["upn"].ToString(), false, proofData.Properties["userID"].ToString());
            }
            return(result);
        }
Example #5
0
        public IAdapterPresentation TryEndAuthentication(IAuthenticationContext context, IProofData proofData, System.Net.HttpListenerRequest request, out System.Security.Claims.Claim[] claims)
        {
            claims = null;
            IAdapterPresentation result = null;
            string userName             = proofData.Properties["upn"].ToString();
            string pin             = proofData.Properties["pin"].ToString();
            string pollingEndpoint = proofData.Properties["pollingEndpoint"].ToString();

            string windir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);

            System.Configuration.ExeConfigurationFileMap fileMap = new System.Configuration.ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = windir + "\\ADFS\\OktaMFA-ADFS.dll.config";
            System.Configuration.Configuration cfg =
                System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, System.Configuration.ConfigurationUserLevel.None);
            string oktaTenant = cfg.AppSettings.Settings["Tenant"].Value;
            string authToken  = cfg.AppSettings.Settings["apiKey"].Value;
            string baseUrl    = oktaTenant + "/api/v1/";

            string pinSuccess   = "no";
            string verifyResult = "false";

            HttpWebRequest upnRequest = (HttpWebRequest)WebRequest.Create(baseUrl + "users/" + userName);

            upnRequest.Headers.Add("Authorization", authToken);
            upnRequest.Method      = "GET";
            upnRequest.ContentType = "application/json";
            var upnResponse = (HttpWebResponse)upnRequest.GetResponse();
            var idReader    = new StreamReader(upnResponse.GetResponseStream());
            var id          = idReader.ReadToEnd();

            RootObject userProfile = JsonConvert.DeserializeObject <RootObject>(id);

            string userID = userProfile.id.ToString();

            HttpWebRequest factorRequest = (HttpWebRequest)WebRequest.Create(baseUrl + "users/" + userID + "/factors");

            factorRequest.Headers.Add("Authorization", authToken);
            factorRequest.Method      = "GET";
            factorRequest.ContentType = "application/json";
            factorRequest.Accept      = "application/json";
            var factorResponse = (HttpWebResponse)factorRequest.GetResponse();
            var factorReader   = new StreamReader(factorResponse.GetResponseStream());
            var factorList     = factorReader.ReadToEnd();

            RootObject[] factors  = JsonConvert.DeserializeObject <RootObject[]>(factorList);
            string       factorID = "";

            foreach (RootObject factor in factors)
            {
                if (factor.provider == "OKTA" && factor.factorType == "push")
                {
                    //   string pushfactorID = factor.id;
                    //    HttpWebRequest pushRequest = (HttpWebRequest)WebRequest.Create(baseUrl + "users/" + userID + "/factors/" + pushfactorID + "/verify");
                    //    pushRequest.Headers.Add("Authorization", authToken);
                    //    pushRequest.Method = "POST";
                    //    pushRequest.ContentType = "application/json";
                    //    pushRequest.Accept = "application/json";
                    //    pushRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36";
                    //    var pushResponse = (HttpWebResponse)pushRequest.GetResponse();
                    //    var pushReader = new StreamReader(pushResponse.GetResponseStream());
                    //    var pushStatus = pushReader.ReadToEnd();
                    //    RootObject pushResult = JsonConvert.DeserializeObject<RootObject>(pushStatus);
                    //    string pollingEndpoint = pushResult._links.poll.href.ToString();


                    int attemptPoll = 1;
                    while (verifyResult == "false" && attemptPoll <= 20 && pinSuccess == "no")
                    {
                        HttpWebRequest verifyRequest = (HttpWebRequest)WebRequest.Create(pollingEndpoint);
                        verifyRequest.Headers.Add("Authorization", authToken);
                        verifyRequest.Method      = "GET";
                        verifyRequest.ContentType = "application/json";
                        verifyRequest.Accept      = "application/json";
                        verifyRequest.UserAgent   = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36";
                        var        pushAnswer  = (HttpWebResponse)verifyRequest.GetResponse();
                        var        pushStatus2 = new StreamReader(pushAnswer.GetResponseStream());
                        var        pushStatus3 = pushStatus2.ReadToEnd();
                        RootObject pushWait    = JsonConvert.DeserializeObject <RootObject>(pushStatus3);
                        if (pushWait.factorResult == "SUCCESS")
                        {
                            verifyResult = "true";
                            Claim claim = new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://schemas.microsoft.com/ws/2012/12/authmethod/otp");
                            claims = new Claim[] { claim };
                            return(result);
                        }
                        else
                        {
                            attemptPoll++;
                        }
                    }
                    return(result);
                }
                if (factor.provider == "OKTA" && factor.factorType == "token:software:totp" && verifyResult == "false" && pin != "")
                {
                    factorID = factor.id;
                    HttpWebRequest httprequest = (HttpWebRequest)WebRequest.Create(baseUrl + "users/" + userID + "/factors/" + factorID + "/verify");
                    httprequest.Headers.Add("Authorization", authToken);
                    httprequest.Method      = "POST";
                    httprequest.ContentType = "application/json";
                    otpCode otpCode = new otpCode
                    {
                        passCode = pin
                    };
                    string otpString = JsonConvert.SerializeObject(otpCode);
                    using (var streamWriter = new StreamWriter(httprequest.GetRequestStream()))
                    {
                        streamWriter.Write(otpString);
                    }
                    try
                    {
                        var httpResponse = (HttpWebResponse)httprequest.GetResponse();
                        if (httpResponse.StatusCode.ToString() == "OK" && pin != "")
                        {
                            pinSuccess = "yes";
                            Claim claim = new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://schemas.microsoft.com/ws/2012/12/authmethod/otp");
                            claims = new Claim[] { claim };
                            return(result);
                        }

                        // using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                        //  {
                        //       var factorResult = streamReader.ReadToEnd();
                        //   }
                    }
                    catch (WebException we)
                    {
                        var failResponse = we.Response as HttpWebResponse;
                        if (failResponse == null)
                        {
                            throw;
                        }
                        result = new AdapterPresentation("Authentication failed.", proofData.Properties["upn"].ToString(), false);
                    }
                }
            }

            //HttpWebRequest httprequest = (HttpWebRequest)WebRequest.Create(baseUrl + "users/" + userID + "/factors/" + factorID + "/verify");
            //httprequest.Headers.Add("Authorization", authToken);
            //httprequest.Method = "POST";
            //httprequest.ContentType = "application/json";
            //otpCode otpCode = new otpCode
            //{ passCode = pin };
            //string otpString = JsonConvert.SerializeObject(otpCode);
            //using (var streamWriter = new StreamWriter(httprequest.GetRequestStream()))
            //{

            //    streamWriter.Write(otpString);
            //}
            //try
            //{
            //    var httpResponse = (HttpWebResponse)httprequest.GetResponse();
            //    if (httpResponse.StatusCode.ToString() == "OK")
            //    {
            //     System.Security.Claims.Claim claim = new System.Security.Claims.Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://schemas.microsoft.com/ws/2012/12/authmethod/otp");
            //     claims = new System.Security.Claims.Claim[] { claim };

            //    }
            //    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            //    {
            //        var factorResult = streamReader.ReadToEnd();
            //    }

            //}
            //catch (WebException we)
            //{
            //    var failResponse = we.Response as HttpWebResponse;
            //    if (failResponse == null)
            //        throw;
            //    result = new AdapterPresentation("Authentication failed.", proofData.Properties["upn"].ToString(), false);
            //}
            if (pinSuccess == "yes" || verifyResult == "true")
            {
                Claim claim = new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://schemas.microsoft.com/ws/2012/12/authmethod/otp");
                claims = new Claim[] { claim };
                return(result);
            }
            else
            {
                result = new AdapterPresentation("Authentication failed.", proofData.Properties["upn"].ToString(), false);
            }
            return(result);
        }
Example #6
0
        static void Main(string[] args)
        {
            //claims = null;
            IAdapterPresentation result = null;
            //string pin = proofData.Properties["pin"].ToString();
            string tenantName = "marcjordan";
            string userName   = "******";
            //string baseUrl = "https://" + tenantName + ".oktapreview.com/api/v1/";
            //string authToken = "SSWS 009RUU8EeUvD-EpOEH1qHL0OZwmCTJK71kzFjsQufr";
            string userID = "";

            string windir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);

            System.Configuration.ExeConfigurationFileMap fileMap = new System.Configuration.ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = windir + "\\ADFS\\OktaMFA-ADFS.dll.config";
            System.Configuration.Configuration cfg =
                System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, System.Configuration.ConfigurationUserLevel.None);
            string oktaTenant = cfg.AppSettings.Settings["Tenant"].Value;
            string authToken  = cfg.AppSettings.Settings["apiKey"].Value;
            //string upn = identityClaim.Value;
            //string tenantName = "marcjordan";
            string baseUrl      = oktaTenant + "/api/v1/";
            string pinSuccess   = "no";
            string verifyResult = "false";



            HttpWebRequest upnRequest = (HttpWebRequest)WebRequest.Create(baseUrl + "users/" + userName);

            upnRequest.Headers.Add("Authorization", authToken);
            upnRequest.Method      = "GET";
            upnRequest.ContentType = "application/json";
            var upnResponse = (HttpWebResponse)upnRequest.GetResponse();
            var idReader    = new StreamReader(upnResponse.GetResponseStream());
            var id          = idReader.ReadToEnd();

            RootObject userProfile = JsonConvert.DeserializeObject <RootObject>(id);

            userID = userProfile.id.ToString();

            HttpWebRequest factorRequest = (HttpWebRequest)WebRequest.Create(baseUrl + "users/" + userID + "/factors");

            factorRequest.Headers.Add("Authorization", authToken);
            factorRequest.Method      = "GET";
            factorRequest.ContentType = "application/json";
            factorRequest.Accept      = "application/json";
            var factorResponse = (HttpWebResponse)factorRequest.GetResponse();
            var factorReader   = new StreamReader(factorResponse.GetResponseStream());
            var factorList     = factorReader.ReadToEnd();

            RootObject[] factors  = JsonConvert.DeserializeObject <RootObject[]>(factorList);
            string       factorID = "";

            foreach (RootObject factor in factors)
            {
                if (factor.factorType == "sms")
                {
                    factorID = factor.id;
                    HttpWebRequest httprequest = (HttpWebRequest)WebRequest.Create(baseUrl + "users/" + userID + "/factors/" + factorID + "/verify");
                    httprequest.Headers.Add("Authorization", authToken);
                    httprequest.Method      = "POST";
                    httprequest.ContentType = "application/json";
                    var httpResponse = (HttpWebResponse)httprequest.GetResponse();
                    Console.WriteLine("Enter Pin");
                    string pin = Console.ReadLine();

                    HttpWebRequest verifyRequest = (HttpWebRequest)WebRequest.Create(baseUrl + "users/" + userID + "/factors/" + factorID + "/verify");
                    verifyRequest.Headers.Add("Authorization", authToken);
                    verifyRequest.Method      = "POST";
                    verifyRequest.ContentType = "application/json";


                    otpCode otpCode = new otpCode
                    {
                        passCode = pin
                    };
                    string otpString = JsonConvert.SerializeObject(otpCode);
                    using (var streamWriter = new StreamWriter(verifyRequest.GetRequestStream()))
                    {
                        streamWriter.Write(otpString);
                    }

                    try
                    {
                        var verifyResponse = (HttpWebResponse)verifyRequest.GetResponse();
                        if (verifyResponse.StatusCode.ToString() == "OK" && pin != "")
                        {
                            pinSuccess = "yes";
                            Claim claim = new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://schemas.microsoft.com/ws/2012/12/authmethod/otp");
                            //claims = new Claim[] { claim };
                            //return result;
                        }
                    }
                    catch (WebException we)
                    {
                        var failResponse = we.Response as HttpWebResponse;
                        if (failResponse == null)
                        {
                            throw;
                        }
                        //result = new AdapterPresentation("Authentication failed.", proofData.Properties["upn"].ToString(), false);
                    }
                    Console.ReadLine();
                }
            }

            //if (pinSuccess == "yes")
            //{
            //    Claim claim = new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://schemas.microsoft.com/ws/2012/12/authmethod/otp");
            //    claims = new Claim[] { claim };
            //    return result;
            //}
            //else
            //{
            //    result = new AdapterPresentation("Authentication failed.", proofData.Properties["upn"].ToString(), false);
            //}
            //return result;
        }