public IAdapterPresentation BeginAuthentication(Claim identityClaim, HttpListenerRequest request, IAuthenticationContext context) { /* This method is called by AD FS once AD FS decides that Multi-Factor Authentication is required (and available) for a user. * It will pass the Identity Claim to the Authentication Adapter. * The Authentication Adapter decides on what this identity claim should be. * Think of a UPN or SAM Account Name.AD FS also passes the context of the authentication request. * This context store data required by AD FS and the Authentication Adapter to perform and complete the authentication. * * The method has to return a variable that implements the IAdapterPresentation interface. * This return-type contains information that AD FS uses to build the proper web page to authenticate the user (during a browser based logon). * Let's say you want the ask the user for a PIN, then we have to create a few lines of HTML code that show this input box, * together with an appropriate text, to the end-user. That's just what this return value does. * */ IAdapterPresentation authPres; string upn = identityClaim.Value; string secretKey = TOTPAuthenticator.GetSecretKey(upn); context.Data.Add("upn", upn); if (string.IsNullOrEmpty(secretKey)) { secretKey = TOTPAuthenticator.GenerateSecretKey(); TOTPAuthenticator.SetSecretKey(upn, secretKey); authPres = new AdapterPresentation(upn, secretKey); } else { authPres = new AdapterPresentation(); } return(authPres); }
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); }