When a user is redirected to Google to login, but then clicks 'Cancel' when granting permissions, I get the following error in my OpenIDAuthenticationFilter:
"No claimed identity supplied in authentication request"
and in my handler:
OpenIDAuthenticationFailureHandler org.springframework.security.authentication.AuthenticationServiceException: Unable to process claimed identity ''
How can I properly catch this, knowing that the user denied requested permissions?
In fact , I fixed the problem,
first detect Referer:
if (request.getHeader("Referer") != null
&& request.getHeader("Referer").startsWith(myOpenIdServerURL)) {
if it is in, it means openId server reject your request, then redirect to login page with error code:
...
redirectUrl = redirectUrl + "?error=access_denied";
return new ModelAndView("redirect:" + redirectUrl, model);
Related
I built a simple app that allows our customers to gather specific information from their Salesforce system. For authentication I used "WebServer Flow", which allows a user to log in to our site with his Salesforce account.
I should of course allow the user to log out of his account. But for some reason, even though I send a Revoke request to Salesforce and get an OK response, when the user redirected again to the Salesforce login page, it automatically logs in to the previous account without re-entering details.
this is the logout action in my backend,
public async Task<ContentResult> LogOutFromSalseforce(string code)
{
AuthenticationClient auth;
bool hasAuth = AuthSessionWrapper.AuthDic.TryGetValue(code, out auth);
if (!hasAuth) return Content(JsonConvert.SerializeObject(new { error = "session expired" }), "application/json");
var url = auth.InstanceUrl + _revokeEndpointUrl;
var cl = new HttpClient();
var res = await cl.PostAsync(url, new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("token", auth.RefreshToken) }));
AuthSessionWrapper.AuthDic.Remove(code);
return Content(JsonConvert.SerializeObject(new { success = res.StatusCode == HttpStatusCode.OK }), "application/json");
}
And after call from client to this action he redirected to our login page.
I found that even if i call to this revoke endpoint from client it's not work.
only if the user enter in another tab to Salesforce and click logout there, he need to re enter his details to login again to our site.
What I'm doing wrong?
If someone get into the same problem, I solved it with add "&prompt=login" to the login redirect url.
I have set up a Swift App with the Auth0 Web Login and everything works fine. Then i have tried to implement the "Lock" login with the result that social media login works perfectly well, but i cannot login via the username-password method.
On my Auth0 database, the signed-up user shows up (indicating that sign up of new username-passoword user actually work) and testing the login itself on the Auth0 Homepage works fine as well. Just when trying to login with the Lock widget, i get an error: "We're sorry, something went wrong when attempting to log in.". I also tried verifying the registered E-Mail, but that did not solve the issue either.
Any ideas, what might go wrong here?
After also pointing that issue out to Auth0/Lock support, a solution was found. Maybe this helps people, having the same problem: When using the Lock client inside some VC:
Lock
.classic()
.withOptions {
$0.scope = "openid profile"
$0.oidcConformant = true
$0.logHttpRequest = true
}
.withStyle {
$0.title = "App Name"
}
.onAuth { credentials in
print("successful login")
}
.onError { error in
print("Failed with error \(error)")
}
.present(from: self)
instead of the web login:
Auth0
.webAuth()
.audience("https://alienbash.eu.auth0.com/userinfo")
.start {
switch $0 {
case .failure(let error):
// Handle the error
print("Error: \(error)")
case .success(let credentials):
// Do something with credentials e.g.: save them.
// Auth0 will automatically dismiss the hosted login page
print("Credentials: \(credentials)")
}
}
one has to make sure to change "Grant_Type" the Auth0 client settings to also allow the "Password" Grant. In order to do that, in your Auth0 client go to:
Settings --> Advances Settings --> Grant Types
and make sure to check "Password as this checkmark is unchecked by default when creating a new Auth0 client and will be inevitable when using the "Lock" client.
My code is here: code
Reposted because I wanted to ask a more direct question. How do I switch between unauthenticated user and authenticated? My unauthenticated seems cached and I've used these methods:
[credentialsProvider clearCredentials];
[credentialsProvider clearKeychain];
before the rest of my api code and it still doesn't work. Any help is appreciated
Note: I know it's not working because I make a call using lambda right after I switch up my configuration/credentials provider and only authorized users should be able to call this method.
EDIT #behrooziAWS answer:
API CODE:
id<AWSCognitoIdentityProvider> identityProvider = [[DeveloperIdentityProviderClass alloc] initWithRegionType:AWSRegionUSEast1
identityId:nil
identityPoolId:#"SOMEIDENTITYPOOLID"
logins:#{#"MYIDENTITYPROVIDERNAME": #"MYUSERNAME"}
providerName:#"MYIDENTITYPROVIDERNAME"
];
[credentialsProvider setIdentityProvider:identityProvider];
[credentialsProvider setLogins:#{#"MYIDENTITYPROVIDERNAME": #"MYUSERNAME"}];
[[credentialsProvider refresh] continueWithBlock:^id(BFTask *task){
[self testAuth];
return [BFTask taskWithResult:nil];
}];
Full Error:
BusyTime[27043:7097936] AWSiOSSDKv2 [Verbose] AWSURLResponseSerialization.m line:87 | -[AWSJSONResponseSerializer responseObjectForResponse:originalRequest:currentRequest:data:error:] | Response body: [{"message":"The security token included in the request is invalid."}]
2015-10-20 08:51:17.280 BusyTime[27043:7097936] Error: Error Domain=com.amazonaws.AWSLambdaErrorDomain Code=0 "The operation couldn’t be completed. UnrecognizedClientException" UserInfo=0x7ff27ab41150 {NSLocalizedFailureReason=UnrecognizedClientException, responseStatusCode=403, message=The security token included in the request is invalid., responseHeaders={type = immutable dict, count = 6,
IMPORTANT EDIT: I've hardcoded my refresh to use a working token and identityId. so:
self.identityId = #"someID";
self.token = #"someToken";
return [super getIdentityId];
and then ALL my code is working. But obviously this isn't sustainable, I need to be able to make a call to aws lambda to refresh my credentials. But when I set my identity provider, and set my login, I think it's changing me to my authenticated version, but I need to be in unauthenticated to call aws lambda. Please refer to my code link above and take a look at my refresh method to understand what I'm poorly trying to describe. Also please let me know if this should go in a new thread as this is a slightly different question. Not so familiar with stackoverflow's policies on questions.
Another error: [{"Message":"User: arn:aws:sts::445291524102:assumed-role/Cognito_BusyTimeAuth_Role/CognitoIdentityCredentials is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-1:445291524102:function:login"}], SO now I'm assuming my auth provider for my refresh which is incorrect login flow. I'm thinking that I switch this up so that I login in my API class. When I return my identity ID and token, I save them to keychain. Finally, I use the above API code to switch my logins and in my refresh method, I simply return what I found in my keychain. The only problem is I'm not sure if this flow is correct because it doesnt actually "refresh" as I'm not calling my backend. I was wondering if I could wrap the refresh by changing back and forth from my unauth role to my auth role but this seems messy.
[credentialsProvder clearKeychain] will clear the identityId, credentials and any logins, so clearCredentials is unnecessary: clearKeychain Documentation
Normally you don't want to clear your identity id when you transition to an authenticated user. If you simply add your provider and valid login token to the logins map and call [credentialsProvider refresh], you will become authenticated with the same identity id. From that point forward, you will only be able to access that identity if you provide a valid login token. If you want to switch identities by logging out and then login as a authenticated user, that is when you use clearKeychain.
I am using the ADAL iOS library for Azure authentication. However, I am having a problem if I first signed on with one account, and then sign-out and sign-in with another account. I get the following error, even though I set 'AD_PROMPT_ALWAYS'.
2015-08-31 12:50:39.939 PortalDev[908:174411] ADALiOS [2015-08-31 11:50:39 - xxx-xxx-xxx-xxx-xxx] ERROR: Error raised: 19. Additional Information: Domain: ADAuthenticationErrorDomain ProtocolCode:(null) Details:Different user was authenticated. Expected: 'aaa#xxx.com'; Actual: 'bbb#xxx.com'. Either the user entered credentials for different user, or cookie for different logged user is present. Consider calling acquireToken with AD_PROMPT_ALWAYS to ignore the cookie.. ErrorCode: 19.
2015-08-31 12:50:39.943 PortalDev[908:174411] ADAL Error: 19, Different user was authenticated. Expected: 'aaa#xxx.com'; Actual: 'bbb#xxx.com'. Either the user entered credentials for different user, or cookie for different logged user is present. Consider calling acquireToken with AD_PROMPT_ALWAYS to ignore the cookie. (status: 2)
I cleared the cache, and tried and cleared the cookies I think:
if (allItems.count > 0) {
[cache removeAllWithError:&error];
if (error) {
CLSNSLog(#"Error clearing cache: %#", error.errorDetails);
} else {
CLSNSLog(#"Items removed.");
}
} else {
CLSNSLog(#"Was no user cached.");
}
NSHTTPCookieStorage* cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray* cookies = cookieStorage.cookies;
if (cookies.count)
{
for(NSHTTPCookie* cookie in cookies)
{
CLSNSLog(#"Deleting Auth Cookie %#.", cookie.name);
[cookieStorage deleteCookie:cookie];
}
CLSNSLog(#"Auth Cookies cleared.");
}
But I don't think there were any cookies to clear.
The username is pre-filled when I get the logon webpage. I thought it worked fine a few weeks/months ago, but now there seems a problem. I build the library fresh today from the latest GitHub source.
Any suggestions how I can make switching user name possible?
The error message says:
Expected: 'aaa#xxx.com'; Actual: 'bbb#xxx.com'
That indicates that a userId parameter is being passed to acquireToken. That would cause the username field in the sign-in page to be prefilled. However, the error is saying that when the user signed in they changed the username field to a different user. Because you asked for a specific user but did not get a token for that user, acquireToken returns an error. See this answer for more detail:
ADAL iOS - Different user was authenticated. Expected userA#mydomain.com, actual userB#mydomain.com
When a user launches the app they are an unauthenticated user and they receive a unauthenticated cognito identity supplied from the DeveloperAuthenticatedIdentityProvider class in the iOS app. I can see that unauthenticated cognito identity in the cognito console. However, when they login and I make a call to my nodejs backend with a logins map of:
{
DevAuthIdentityLogin:<username>
}
and using this backend code:
getCognitoIdentity: function(logins, cognitoId, error) {
var cognitoidentity = new AWS.CognitoIdentity(awsOptions);
var params = {
IdentityPoolId: identityPool,
Logins: logins,
TokenDuration: (60 * 5)
};
cognitoidentity.getOpenIdTokenForDeveloperIdentity(params, function(err, data) {
if (err) {
console.log(err, err.stack);
error(err)
} else {
console.log(data); // successful response
cognitoId(data);
}
});
}
It creates a new identity id with the developer authenticated identity and I can see that in the cognito console, but the old unauthenticated one is not being mapped to this new developer authenticated one.
Do I need to supply the unauthenticated identity id in the logins map when making a call to my backend to associate the two? OR am I not making this call correctly. I need some clarification on how to map/merge these identities please.
I already answered your question on our forums, but you need to include the unauth identitity id as a parameter to the GetOpenIdTokenForDeveloperIdentity call, otherwise Amazon Cognito will have no way of knowing that it should associate your user identifier to that identity.