/// <summary> /// This method handles the response from Google and returns an <see cref="AuthenticationResponse"/> object /// </summary> /// <returns>AuthenticationResponse with details such as the IDTokenPayload</returns> /// <exception cref="InvalidStateException">Thrown when the CSRF token is missing or there is a mismatch</exception> /// <exception cref="AuthenticationException">Thrown when there was an error in the process of authentication at Google</exception> /// <exception cref="HashAlgorithmNotSupportedException">Thrown when the used algorithm for hashing is not supported</exception> /// <exception cref="SignatureVerificationException">Thrown when the signature seems to be broken</exception> public static AuthenticationResponse HandleResponse() { string code = HttpContext.Current.Request.Params["code"]; string state = HttpContext.Current.Request.Params["state"]; string error = HttpContext.Current.Request.Params["error"]; NameValueCollection stateParameters = HttpUtility.ParseQueryString(state); string responseState = stateParameters[ResponseStateParameter]; bool receiveProfileInformation = Boolean.Parse(stateParameters[ReceiveProfileInformation]); if (!AuthenticationUtility.VerifyCsrfTokenInState(stateParameters)) { throw new InvalidStateException(responseState); } if (!String.IsNullOrWhiteSpace(error)) { throw new AuthenticationException(error, responseState); } NameValueCollection parameters = new NameValueCollection(); parameters.Add("code", code); parameters.Add("client_id", Configuration.ClientID); parameters.Add("client_secret", Configuration.ClientSecret); parameters.Add("redirect_uri", Configuration.RedirectURI); parameters.Add("grant_type", "authorization_code"); TokenInformation token = WebClientUtility.GetIDTokenPayload(parameters); IDTokenPayload idTokenPayload = DecodeAndVerifyIDTokenPayload(token.IDToken, GetRSACryptoServiceProvider(), true); UserInformation userInformation = (receiveProfileInformation)?WebClientUtility.GetUserInformation(token.AccessToken):null; return(new AuthenticationResponse(responseState, idTokenPayload, userInformation)); }
/// <summary> /// Converts the JWKs to a list of <see cref="RSACryptoServiceProvider"/>. /// The JWKs are being downloaded directly from the link provided in /// the OIDC Discovery Document. /// </summary> /// <returns>List of RSACryptoServiceProviders</returns> private static List <RSACryptoServiceProvider> GetRSACryptoServiceProvider() { JsonWebKeyIndex jsonWebKeyIndex = WebClientUtility.GetJsonWebKeyIndex(); List <RSACryptoServiceProvider> providers = new List <RSACryptoServiceProvider>(); jsonWebKeyIndex.Keys.ForEach(jsonWebToken => { RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); provider.ImportParameters(new RSAParameters { Exponent = ConversionUtility.Base64UrlDecode(jsonWebToken.Exponent), Modulus = ConversionUtility.Base64UrlDecode(jsonWebToken.Modulus) }); providers.Add(provider); }); return(providers); }