/// <summary> /// Validates the signature of a response. /// </summary> /// <param name="response"></param> private Boolean Validate(RavenResponse response) { // find the public key corresponding to the key used by the // server to generate the response signature String key = String.Format("pubkey{0}", response.CertificateID); if (!this.certificates.ContainsKey(key)) { throw new RavenException("Couldn't find the public key needed to validate the response."); } X509Certificate2 cert = this.certificates[key]; // calculate a hash for the signature data: // 1. convert the signature data into bytes using the ASCII encoding // 2. calculate a SHA1 hash for the bytes SHA1Managed sha1 = new SHA1Managed(); ASCIIEncoding ascii = new ASCIIEncoding(); Byte[] asciiHash = sha1.ComputeHash(ascii.GetBytes(response.SignatureData)); // 3. validate this hash against the signature obtained from the response RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PublicKey.Key; RSAPKCS1SignatureDeformatter def = new RSAPKCS1SignatureDeformatter(csp); def.SetHashAlgorithm("SHA1"); return(def.VerifySignature(asciiHash, response.Signature)); }
/// <summary> /// Generate a Forms authentication ticket for the current session. /// </summary> /// <param name="response"></param> /// <param name="ravenResponse"></param> private void CreateTicket(HttpResponseBase response, RavenResponse ravenResponse) { // generate a ticket for the Raven session FormsAuthenticationTicket ticket = new FormsAuthenticationTicket( 1, ravenResponse.Parameters["principal"], DateTime.Now, ravenResponse.Expires, false, ravenResponse.Principal); // encrypt it so that the client can't mess with its contents String encryptedTicket = FormsAuthentication.Encrypt(ticket); // put it in a cookie HttpCookie formsCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); response.Cookies.Add(formsCookie); }
/// <summary> /// Performs the Raven authentication flow. /// </summary> /// <param name="filterContext"></param> public void Authorize(AuthorizationContext filterContext) { HttpRequestBase request = filterContext.HttpContext.Request; HttpResponseBase response = filterContext.HttpContext.Response; if (this.LoadIdentity(filterContext.HttpContext)) { return; } // if this is not a POST request, then we can look for a response if (!request.HttpMethod.Equals("POST")) { // try to get the response String wlsResponse = request.Params[WLS_RESPONSE_PARAM]; if (!String.IsNullOrWhiteSpace(wlsResponse)) { // parse the response data RavenResponse ravenResponse = new RavenResponse(wlsResponse); // if the server has indicated that authentication was successful, // validate the response signature and set an authentication cookie if (ravenResponse.Status == RavenStatus.OK) { if (!this.Validate(ravenResponse)) { throw new RavenException("Failed to validate response signature."); } // create a Forms authentication ticket and cookie this.CreateTicket(response, ravenResponse); // redirect the user back to where they started response.Redirect(ravenResponse.URL); } else { // check to see if there is a URL we should redirect the user to // if not: throw an exception if (String.IsNullOrWhiteSpace(this.errorURL)) { throw new RavenResponseException( "Authentication failed: " + ravenResponse.Status.ToString(), ravenResponse.Status); } response.Redirect(this.errorURL + (Int32)ravenResponse.Status); } return; } } // if we end up here, then we don't have a Raven session RavenRequest ravenRequest = new RavenRequest(); ravenRequest.Parameters.Add("url", request.Url.AbsoluteUri); // redirect the user so they can set one up response.Redirect(String.Format("{0}{1}{2}", this.baseURL, RAVEN_AUTHENTICATE, ravenRequest.ToString())); }
/// <summary> /// Performs the Raven authentication flow. /// </summary> /// <param name="filterContext"></param> public void Authorize(AuthorizationContext filterContext) { HttpRequestBase request = filterContext.HttpContext.Request; HttpResponseBase response = filterContext.HttpContext.Response; if (this.LoadIdentity(filterContext.HttpContext)) return; // if this is not a POST request, then we can look for a response if (!request.HttpMethod.Equals("POST")) { // try to get the response String wlsResponse = request.Params[WLS_RESPONSE_PARAM]; if (!String.IsNullOrWhiteSpace(wlsResponse)) { // parse the response data RavenResponse ravenResponse = new RavenResponse(wlsResponse); // if the server has indicated that authentication was successful, // validate the response signature and set an authentication cookie if (ravenResponse.Status == RavenStatus.OK) { if (!this.Validate(ravenResponse)) throw new RavenException("Failed to validate response signature."); // create a Forms authentication ticket and cookie this.CreateTicket(response, ravenResponse); // redirect the user back to where they started response.Redirect(ravenResponse.URL); } else { // check to see if there is a URL we should redirect the user to // if not: throw an exception if (String.IsNullOrWhiteSpace(this.errorURL)) { throw new RavenResponseException( "Authentication failed: " + ravenResponse.Status.ToString(), ravenResponse.Status); } response.Redirect(this.errorURL + (Int32)ravenResponse.Status); } return; } } // if we end up here, then we don't have a Raven session RavenRequest ravenRequest = new RavenRequest(); ravenRequest.Parameters.Add("url", request.Url.AbsoluteUri); // redirect the user so they can set one up response.Redirect(String.Format("{0}{1}{2}", this.baseURL, RAVEN_AUTHENTICATE, ravenRequest.ToString())); }
/// <summary> /// Validates the signature of a response. /// </summary> /// <param name="response"></param> private Boolean Validate(RavenResponse response) { // find the public key corresponding to the key used by the // server to generate the response signature String key = String.Format("pubkey{0}", response.CertificateID); if (!this.certificates.ContainsKey(key)) throw new RavenException("Couldn't find the public key needed to validate the response."); X509Certificate2 cert = this.certificates[key]; // calculate a hash for the signature data: // 1. convert the signature data into bytes using the ASCII encoding // 2. calculate a SHA1 hash for the bytes SHA1Managed sha1 = new SHA1Managed(); ASCIIEncoding ascii = new ASCIIEncoding(); Byte[] asciiHash = sha1.ComputeHash(ascii.GetBytes(response.SignatureData)); // 3. validate this hash against the signature obtained from the response RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PublicKey.Key; RSAPKCS1SignatureDeformatter def = new RSAPKCS1SignatureDeformatter(csp); def.SetHashAlgorithm("SHA1"); return def.VerifySignature(asciiHash, response.Signature); }