What does this message mean? User still exist in aws cognito.
NotAuthorizedException: The user has been deleted for the associated refresh token
From the Cognito's Api (here Java), we can see that:
/**
* Constructs a new NotAuthorizedException with the specified error message.
*
* #param message
* Describes the error encountered.
*/
public NotAuthorizedException(String message) {
super(message);
}
Now the message says the user is deleted for token refresh, so I'm assuming somebody disabled the user. Could you verify that there is no diffrerence between the targeted user; and the rest of users? What is the status of the user?
Related
I am fairly new to webapps programming, so I thought of asking here.
I am implementing the SAML2 protocol in an open source app (namely OFBiz) but I am encountering a problem related to session loss after the protocol made its course.
I am following these steps to implement the protocol. Suppose ofbizwebsite.com is the URL of the site.
Installed a custom plugin named SAMLIntegration which exposes the ACS page and the logic for login. To my understanding, a plugin (gradle) is like an indipendent java project, which translates to a new set of resources for the application (the plugin enables, for example, to visit ofbizwebsite.com/SAMLIntegration and setup some resources).
Exposed the ACS page to ofbizwebsite.com/SAMLIntegration/control/acs, as well as metadata ofbizwebsite.com/SAMLIntegration/control/metadata.jsp
Created the logic for login. Basically, an entity called UserLogin is saved in the session and recovered by a "checker" to understand if an user is logged in. Suppose that this checker is a HTTP WebEvent handler which can be called by any resource requiring authentication.
Now, the problem. If redirect the user to a resource on SAMLIntegration (for example ofbizwebsite.com/SAMLIntegration/control/aview or any ofbizwebsite.com/SAMLIntegration/control/* by calling response.sendRedirect("aview")) check works and login is preserved. Visiting any resource (for example ofbizwebsite.com/aplugin/control/anotherview) by navigating the application does not preserve the session.
OFBiz use internally a mechanism for preserving the userLogin between webapps, by creating an HashMap between and UUID and a UserLogin object. The UUID is passed between two different resources, appending this key to each path (so ofbizwebsite.com/aplugin/control/anotherview?externalKey=THEEFFECTIVEUUID)
To my understanding, changing from ofbizwebsite.com/SAMLIntegration/control/* to ofbizwebsite.com/aplugin/control/* determine a session loss. So, my idea was to replace the UUID mechanism with SAML2. However, I do not know how to solve this problem.
In particular, I would like to execute a SAML request each time the checker function is executed. If I can't find the user in the session, a SAML request is fired. However, my problem is HOW to manage the response. Normally, I would redirect it to the acs ofbizwebsite.com/SAMLIntegration/control/acs. Doing so, however, does not allow me to handle the response in the checker function, as the control is passed to another servlet by an external request (the SAML response fired by the IdP). Should I provide a different acs for each different path? (so one for SAMLIntegration and one for aplugin?) And, even if this was the case, how can I return the control to the checker function which has invoked the SAML request?
Here you go for installing the Shibboleth HTTPD module: https://pad.nereide.fr/SAMLWithShibboleth
You also need this method somewhere in OFBiz (I recommend LoginWorker.java, but you can put it where you want). It allows to use the externalAuthId of the userLogin for authentication, with the uid returned by the sso:
public static String checkShibbolethRequestRemoteUserLogin(HttpServletRequest request, HttpServletResponse response) {
LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
Delegator delegator = dispatcher.getDelegator();
// make sure the user isn't already logged in
if (!LoginWorker.isUserLoggedIn(request)) {
String remoteUserId = (String) request.getAttribute("uid"); // This is the one which works, uid at Idp, remoteUserId here
if (UtilValidate.isNotEmpty(remoteUserId)) {
//we resolve if the user exist with externalAuthId
String userLoginId = null;
GenericValue userLogin;
try {
List<GenericValue> userLogins = delegator.findList("UserLogin",
EntityCondition.makeConditionMap("externalAuthId", remoteUserId, "enabled", "Y"),
null, null, null, true);
userLogin = userLogins.size() == 1 ? userLogins.get(0) : null;
} catch (GenericEntityException e) {
Debug.logError(e, module);
return "error";
}
if (userLogin != null) {
userLoginId = userLogin.getString("userLoginId");
}
//now try to log the user found
return LoginWorker.loginUserWithUserLoginId(request, response, userLoginId);
}
}
return "success";
}
You also need to have this method as an OFBiz preprocessor in the webapp controllers. I suggest to have a look at common-controller.xml.
Finally you need the configs that redirect to the SSO page if no session. That should do the job, at least it works for them...
Finally I recommend https://www.varonis.com/blog/what-is-saml in case of need.
I'm busy writing a test harness that will validate a REST API I've been developing. In the normal usage the my REST API will be used by a Web application that is secured and authenticated by OneLogin. My test harness will therefore have to use OneLogin to authenticate before I can call my own functions. I'm struggling to understand the right workflow for logging through an API as my test harness does not have a browser. So far I've got:
Request an Authentication Token using the Client Id and Secret (https://developers.onelogin.com/api-docs/1/oauth20-tokens/generate-tokens)
Request a Session Token using the Authentication Token, Sub-Domain, user name and password (https://developers.onelogin.com/api-docs/1/users/create-session-login-token)
I'm not quite sure what do do with the Session Token. I suspect I might have to create a session (https://developers.onelogin.com/api-docs/1/users/create-session-via-token) but that appears to be using a different URL.
Any ideas?
Updated:
Here is the code that I'm using for that final step. I pass in the Session Token obtained in the previous step.
/** see https://developers.onelogin.com/api-docs/1/users/create-session-via-token */
public void createSession(String sessionToken) {
HttpPost httpPost = new HttpPost("https://admin.us.onelogin.com/session_via_api_token");
List<NameValuePair> postParameters = new ArrayList<>();
postParameters.add(new BasicNameValuePair("session_token", sessionToken));
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpEntity entity = new UrlEncodedFormEntity(postParameters);
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);
int status = response.getStatusLine().getStatusCode();
System.out.println(status);
} catch (Exception e) {
e.printStackTrace();
}
}
The status code returned is 302 and the response headers contain Location: https://<my-company>.onelogin.com.
I'm taking this to mean that the last call has failed for some reason and I'm being redirected back to the log-in page.
You suspect right.
Basically, after your server makes the back-channel requests for the token, you have to hand the token off via the front channel (user's browser) so you can establish a session, get cookies, etc... using the session_via_api_token 'endpoint' (which is a totally different sort of API from the ones to get the token in the first place)
When I send notification to Device Groups I get the following response
{
"success": 2,
"failure": 0
}
I wanted to simulate partial success (https://developers.google.com/cloud-messaging/notifications#http_response) so that I can test my retry logic. A response like below-
{
"success":1,
"failure":2,
"failed_registration_ids":[
"regId1",
"regId2"
]
}
How should I do that?
In order to have a "partial success" response, you need to have not_registered_ids and/or invalid_registration_ids. A "not registered id" is a registration id that was valid. According to GCM documentation: "An existing registration token may cease to be valid in a number of scenarios...". You can try the following to have a partial successful push:
Client app unregisters with GCM.
Client app is automatically unregistered, which can happen if the user uninstalls the application.
Client app is updated but the new version is not configured to receive messages.
A partial successful push may also have to_be_retried_ids so that the user can retry these specific registration ids as they failed because the server returned with InternalServerError or Unavailable.
I'm trying to implement an extra authentication layer with the purpose of authenticating the user only if he has a certain status.
If the status is different, I want to show a custom login error (Your account has been suspended) and not authenticate the user at all, similar to what happens if the credentials are wrong, but with a different error message.
So far I've tried two options:
I've added a check within a listener that checks for an "InteractiveLoginEvent". Here I can check the user status and set a flash error message but I don't see what's the proper way to redirect back to the login page, since this event has no response method, other than using a header() call which I definitely want to avoid.
I implemented a custom voter, set the "access_decision_manager" startegy to "unanimous" and returned "ACCESS_DENIED" if the status is not allowing the user to authenticate. So far so good, the user cannot access the resources but I see he still gets authenticated. And I definitely don't want that.
I'm not for sure if I'm missing something or if I'm going in the wrong direction.
Since symfony 2 makes a clear difference between authentication and authorization seems that option 2) is related to authorization, so option 1) is more suitable.
So among the "InteractiveLoginEvent" listener I just added the proper check for the user status and by throwing the following exception I managed to implement my functionality as needed:
throw new AuthenticationException('suspend error message');
So the listener looks something like this:
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
if ($this->securityContext->isGranted('ROLE_CUSTOMROLE')) {
$user = $this->securityContext->getToken()->getUser();
// ... check for the user status here
throw new AuthenticationException('Your account has been suspended!');
}
}
I am using fusion table APIs to insert/update data in my table. Last week I migrated my API to new version v1 as referred in this sample. But now, when I run the code, the following error displayed.
400 Bad Request
{
"error" : "unauthorized_client"
}
com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "unauthorized_client"
}
at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:303)
at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:323)
at com.google.api.client.auth.oauth2.Credential.executeRefreshToken(Credential.java:607)
at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:526)
at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:287)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:836)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:412)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:345)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:463)
at com.prasanna.survey.pushapis.FusionPush.insertData(FusionPush.java:198)
at com.prasanna.survey.pushapis.FusionPush.main(FusionPush.java:96)
Java Result: 1
How to debug this error?
This error typically occurs if you change the client_id of an application.
The reason is, you already have an access token for the Fusion API that's based on the old client_id. When you request a refresh token (as you can see is happening in the stack trace) with the new client_id, you get that very unhelpful error message.
The easiest way to handle this is to clear the existing credential from the system so it has to receive a clean access token. You can do this programatically with the Google API Java Client, or you can just remove the file from your system. On my Ubuntu machine, it is located at ~/.credentials/<api-name>.json.