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); }
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); }
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); }
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; }