Google Identity Toolkit - Password Reset flow is broken - google-identity-toolkit

I have been using Google Identity Toolkit (for web) on my site for more than 2 years. Recently I found that the password reset flow is broken. When I try to "Forgot Password", check the recaptcha checkbox and click Continue, I get an error "Request failed. Please try again."
In the console I see this:
[ 28.949s] [identitytoolkit] Error: Invalid JSON string: Password reset email sent successfully.
Gj # gitkit.js:254
Ej.addLogRecord # gitkit.js:254
Zi.log # gitkit.js:237
R # gitkit.js:254
(anonymous) # gitkit.js:255
Yc # gitkit.js:44
g.dispatchEvent # gitkit.js:42
tj # gitkit.js:247
lj.onReadyStateChangeEntryPoint_ # gitkit.js:245
lj.onReadyStateChange_ # gitkit.js:245
XMLHttpRequest.send (async)
lj.send # gitkit.js:242
Mj # gitkit.js:255
Lj.requestRpEndpoint # gitkit.js:256
g.requestRpEndpoint # gitkit.js:259
(anonymous) # gitkit.js:4
N # gitkit.js:190
Fh # gitkit.js:190
Sm # gitkit.js:334
(anonymous) # gitkit.js:335
(anonymous) # gitkit.js:80
(anonymous) # gitkit.js:77
Yc # gitkit.js:44
g.dispatchEvent # gitkit.js:42
fd # gitkit.js:47
ed.handleClick_ # gitkit.js:47
Uc # gitkit.js:39
Rc # gitkit.js:41
Pc.b # gitkit.js:37
Even though the error says "email sent successfully", it's not sent. I do not know how long it has been broken for. I only found it yesterday.
I'm using this script:
https://www.gstatic.com/authtoolkit/js/gitkit.js on my web site.
I hope someone from the Gooogle Identity Toolkit team can help on this.
UPDATE 1:
Server side code:
OobResponse oobResponse = gitkitClient.getOobResponse(request);
OobAction oobAction = oobResponse.getOobAction();
// For DEBUG
logger.info("oobAction : " + oobAction);
String action = request.getParameter("action");
logger.info("action : " + action); // returns null
logger.info("response: " + request.getParameter("response")); // returns a long string
logger.info("responseBody : " + oobResponse.getResponseBody()); // returns {"error": "CAPTCHA_CHECK_FAILED" }
logger.info("email : " + oobResponse.getEmail()); // returns null
// If reset password
if (OobAction.RESET_PASSWORD.equals(oobAction)) {
Optional<String> forgotPasswordLinkOpt = oobResponse.getOobUrl();
String passwordResetLink = forgotPasswordLinkOpt.get();
sendMailService.sendPasswordResetEmail(oobResponse.getEmail(), passwordResetLink);
return(oobResponse.getResponseBody());
}
The oobAction is coming out to be null and therefore the link is not being sent. But action has a value of resetPassword. 'responseBody' is returning
{"error": "CAPTCHA_CHECK_FAILED" }. Do I need to do some configuration for the recaptcha string at my end?
I'm using v1.2.7 of gitkitclient from the Maven repo:
https://mvnrepository.com/artifact/com.google.identitytoolkit/gitkitclient

The issue was fixed by the Google team on the backend without any change from my end. See comments on the original issue for details.

Related

How to Validate an auth0 token in R Shiny and handle errors?

I am not new to programming, but I am very new to R Shiny.
A web portal will be linking to my R Shiny app (the app will be deployed to a shiny-server in a docker container), and the web portal will be passing some query string parameters to my app - an auth0 token, aud value, and the auth0 url where I should validate the token.
What I want to happen is once my app starts up, it gets the query parameters from the query string, validates the token with the auth0 url, and check that the "aud" value matches what is in the validated token.
I also want catch any errors and show just a "403 Forbidden" text . Currently, I've been bashing my head around trying to get this to work, but because of my limited experience with R and shiny, I have very little that works in my code. Any thorough explanation of code solutions would be super helpful.
What I have so far
server <- function(input, output, session){
# gets query string values
token <- reactive({getQueryString()$token})
authurl <- reactive({getQueryString()$authurl})
aud <- reactive({getQueryString()$aud})
# this currently makes sure the token validates and compares the "aud" value to what
# was received in the query string but i need to break this apart some how, to:
# 1) show "403 Forbidden" if the authurl is not present/bad/cannot connect
# 2) show "403 Forbidden" if the token is not present/bad
# 3) show "403 Forbidden" if the aud is not present/bad
# 4) show "OK" (eventually the app itself) if result is True and all is valid
result <- reactive({jwt_decode_sig(token(), read_jwk(fromJSON(rawToChar(GET(paste0("https://",authurl(),"/.well-known/jwks.json"))[["content"]]))$keys[[1]]))$aud == aud()})
# I'm using this to printout the value of the result() call as a test
output$token <- renderText({result()})
# this is what I'd like to use (or something like this) to determine if the user should
# be shown a "403" or the app itself. In running some tests, I don't believe this code
# actually executes. I don't know why.
shinyCatch(
if(result() == TRUE){
shinyjs::show("app-content")
shinyjs::hide("loading-content")
}
else{
shinyjs::show("error")
shinyjs::hide("loading-content")
}
)
}
TIA
With the help of #MrFlick's suggestion, I was able to get this to work the way I wanted it to. This is what I did:
in the ui function, here are my divs:
div(
id = "loading-content",
h2("Authenticating...")
),
hidden(
div(
id = "app-content",
...
)
),
hidden(
div(
id = "error",
h2("Error 403: Forbidden User")
)
)
in my server function, the code change is in the "result" function/value. Basically it will show the error text if the token, aud, or the authurl is invalid. And it will show the app if everything is validated.
token <- reactive({getQueryString()$token})
authurl <- reactive({getQueryString()$authurl})
aud <- reactive({getQueryString()$aud})
result <- reactive({
tryCatch(
{jwt_decode_sig(token(), read_jwk(fromJSON(rawToChar(GET(paste0("https://",authurl(),"/.well-known/jwks.json"))[["content"]]))$keys[[1]]))$aud == aud()},
error = function(e){
message("bad authentication params: token or authurl")
return(FALSE)
}
)
})
observe({
if(result() == TRUE){
shinyjs::show("app-content")
shinyjs::hide("loading-content")
}
else{
shinyjs::show("error")
shinyjs::hide("loading-content")
}
})

WSO2 3 : Error while generating PRODUCTION token for application

I was able to get past invalid_callback error. Ref: Wso2 apiman: INVALID REQUEST, invalid_callback
However, I'm not able to generate tokens for api. Any workaround is much appreciated.
Caused by: javax.net.ssl.SSLException: hostname in certificate didn't match: localhost != dev.org
2020-03-01T12:06:46,418 [-] [https-jsse-nio-9443-exec-40] ERROR APIConsumerImpl Error while re-generating AccessToken
org.wso2.carbon.apimgt.api.APIManagementException: Error while creating tokens - hostname in certificate didn't match: localhost != dev.org
Any other changes to be made?
The workaround for "Error generating PRODUCTION token" is :
Un-comment section [apim.oauth_config] 'revoke_endpoint' lines as
shown below.
Replace
Change this : revoke_endpoint = "https://localhost:${https.nio.port}/revoke"
To :revoke_endpoint = "https://dev.apigw.org:${https.nio.port}/revoke"
[apim.oauth_config]
#enable_outbound_auth_header = false
#auth_header = "Authorization"
revoke_endpoint = "https://dev.apigw.org:${https.nio.port}/revoke"
#enable_token_encryption = false
#enable_token_hashing = false
One other approach you can follow is adding localhost as a SAN when you generate the new certificate/keystore.

How to send oauth2.0 id_token in http header? Incorrect padding error

I'm trying to send a googleId and id_token in an http header. For some reason, I cannot verify the token due to an incorrect padding error.
I'm following this guide: https://developers.google.com/identity/sign-in/web/backend-auth
I tried copying the id_token string into my code (replacing the variable request_user_id_token), and the verify_oauth2_token works just fine. There's a problem because I'm reading it off the http header.
I also printed the value of request_user_id_token and it is exactly the same as expected.
#app.before_request
def before_request():
try:
request_user_id = request.headers.get('google-id')
request_user_id_token = request.headers.get('google-id-token')
if not (request_user_id and request_user_id_token):
raise ValueError('Missing id and id token in request headers')
# THIS LINE THROWS
id_token.verify_oauth2_token(request_user_id_token, requests.Request(), os.environ.get("ELEVATE_GOOGLE_CLIENT_ID"))
print(google_id_info)
if google_id_info['iss'] not in ['accounts.google.com', 'https://accounts.google.com']:
raise ValueError('Wrong issuer.')
# ID token is valid. Get the user's Google Account ID from the decoded token.
google_user_id = int(google_id_info['sub'])
if request_user_id != google_user_id:
raise ValueError('The supplied google id does not match the supplied id token')
# Authentication Error (Incliding Expired Token)
except ValueError as error:
print(error)
pass
Printing the error at the end just outputs 'Incorrect Padding'

Error: Your session expired due to inactivity. ATG REST API session confirmation Number Missmatch

I am working on ATG portal using REST API, all ATG API's are tested using PostMan.
It is giving an error when I started working in JS. below is the Test Code:
http({
method : "GET",
url : "http://IP:PORT/rest/model/atg/rest/SessionConfirmationActor/getSessionConfirmationNumber"
}).then(function mySucces(response){
// localStorage.setItem("getSessionConfirmationNumer", response.data.sessionConfirmationNumber);
// localStorage.getItem("getSessionConfirmationNumer");
http({
method : "GET",
url : "http://IP:PORT/rest/model/atg/userprofiling/ProfileActor/login?_dynSessConf="+response.data.sessionConfirmationNumber+"&login=atgcust1&password=atgcust1",
// url : "http://IP:PORT/rest/model/atg/userprofiling/ProfileActor/login",
// data:formData
}).then(function mySucces(response){
console.log("done");
},function errorCallback(response) {
console.log(response);
});
});
OutPut from Console:
angular.js:10722 GET http://IP:PORT/rest/model/atg/userprofiling/ProfileActor/login?_dynSessConf=9030570900570011195&login=atgcust1&password=atgcust1 409 (Conflict)(anonymous function) # angular.js:10722p # angular.js:10515g # angular.js:10222(anonymous function) # angular.js:14745n.$eval # angular.js:15989n.$digest # angular.js:15800n.$apply # angular.js:16097(anonymous function) # angular.js:23554n.event.dispatch # jQuery-2.1.4.min.js:3r.handle # jQuery-2.1.4.min.js:3
functions.js:75
Object {data: "Your session expired due to inactivity.", status: 409, config: Object, statusText: "Conflict"}
Session Confirmation Number Can be Accessible only once after that it will give 500 internal server error (This Logic I have written not included here),
Login is working when I get session confirmation Number manually from browser and giving that as _dynSessConf value manually in the code
Please help.
Some JSON libraries like org.json have a problem parsing large longs.
They yield a slightly different value for large longs which is exactly happend to my code,
SessionConfirmationNumber Returning Via JSON as Data type of Long and I was getting rounded value as the SessionConfirmationNumber was large.
I have used xmlHttp request for solving this issue.
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "http://IP:PORT/rest/model/atg/rest/SessionConfirmationActor/getSessionConfirmationNumber", false );
xmlHttp.send();
console.log(xmlHttp.responseText);
Thank God :)

Refresh Token for Access Token Google API: R Code

I am attempting to retrieve an access token using my refresh token, client id and client secret for the youtube api using R Code.
This is google's example of how to POST a request.
POST /o/oauth2/token HTTP/1.1 Host: accounts.google.com Content-Type: application/x-www-form-urlencoded client_id=21302922996.apps.googleusercontent.com&client_secret=XTHhXh1SlUNgvyWGwDk1EjXB&refresh_token=1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ&grant_type=refresh_token
This was my r code:
library(httr)
url<- paste("https://accounts.google.com/o/oauth2/token?client_id=", client_id, "&client_secret=", client_secret, "&refresh_token=", refresh_token, "&grant_type=access_token", sep="")
POST(url)
And I keep getting this response:
Response [https://accounts.google.com/o/oauth2/token?client_id=xxxxxxxxxx&client_secret=xxxxxxxx&refresh_token=xxxxxxxxxxxxxxxxxxxxxx&grant_type=refresh_token]
Date: 2015-09-02 16:43
Status: 400
Content-Type: application/json
Size: 102 B
{
"error" : "invalid_request",
"error_description" : "Required parameter is missing: grant_type"
Is there a better way to do this? Maybe using RCurl? If so, what would the format of the request be? I would appreciate help on this!
The RAdwords package has a function to retrieve the refresh token. If you don't want to add the entire package you can just add the following code to your script.
refreshToken = function(google_auth) {
# This function refreshes the access token.
# The access token deprecates after one hour and has to updated
# with the refresh token.
#
# Args:
# access.token$refreh_token and credentials as input
# Returns:
# New access.token with corresponding time stamp
rt = rjson::fromJSON(RCurl::postForm('https://accounts.google.com/o/oauth2/token',
refresh_token=google_auth$access$refresh_token,
client_id=google_auth$credentials$c.id,
client_secret=google_auth$credentials$c.secret,
grant_type="refresh_token",
style="POST",
.opts = list(ssl.verifypeer = FALSE)))
access <- rt
access
}

Resources