As we are migrating our app from Firebase to Couchbase, we also need to change the authentication part. We are using the google_sign_in package and would like to continue using it to have the native Google Sign In popup. Using the package we can get a serverAuthCode, which from my understanding we can then send to the _oidc_callback endpoint of Couchbase Sync Gateway. First I had to set disable_callback_state to true in the Sync Gateway configuration ("DisableCallbackState determines whether or not to maintain state between the /_oidc and /_oidc_callback endpoints."). However, when I now send the serverAuthCode to the _oidc_callback endpoint, I get the following error with status code 500:
body: {"error": "Internal Server Error", "reason": "Failed to exchange token: oauth2: cannot fetch token: 400 Bad Request\nResponse: {\n \"error\": \"invalid_grant\",\n \"error_description\": \"Bad Request\"\n}"}
I assume it is because the login was done using the package and not through the browser with a redirect to the app afterwards. Now I have no idea how to do this correctly though, that I sign in with the google_sign_in package and then use the code to get the tokens from the Sync Gateway. I can't find any helpful information for this problem.
I would be very happy if someone could help me, possibly in a call. Maybe this way something like this can be solved faster.
I'm using my organization's Azure AD to authenticate users on a corporate web app. I intend for this to be a single-tenant application. When I run it, I'm prompted to log in with my organization's credentials, as expected. On submitting my credentials, however, I get this error:
Sorry, but we’re having trouble signing you in.
AADSTS50194: Application 'appId'(appname) is not configured as a multi-tenant application. Usage of the /common endpoint is not supported for such applications created after '10/15/2018'. Use a tenant-specific endpoint or configure the application to be multi-tenant.
The thing is, I'm not trying to use the /common endpoint. Here is the relevant bit of my appsettings.json:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "COMPANYDOMAIN.onmicrosoft.com",
"TenantId": "MYTENANTID-xxxx-xxxx-xxxx-xxxx",
"ClientId": "MYCLIENTID-yyyy-yyyy-yyyy-yyyy",
"CallbackPath": "/signin-oidc"
},
And here's the app's settings in the Azure portal (Home>AppRegistrations>App>PlatformConfigurations>Authentication):
My startup.cs, which I assumed set the endpoint in question, is taken directly from the Microsoft-provided sample:
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
});
I've also set false to true for kicks, but the result was the same.
What am I doing wrong, here? Why does Azure AD continue to believe I want to use the /common endpoint?
Edit: As I continued to search, I happened on #jack-jia's answer here: Application is not configured as a multi-tenant application
I haven't quite solved my issue, but their answer offered some promising clues.
Since you have configured it as single tenant application on Azure portal, this issue must occurred due to the wrong authorization endpoint. Please check the value of options.Authority again. If it is identified as single tenant, you can use fiddler to capture the request, the request is something like
GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=form_post
&scope=openid
&state=12345
&nonce=678910
Check if the endpoint is correct.
I came here with the same error but using python to authenticate my API calls.
Specifically I was using authOAuthDesktopMobileAuthCodeGrant class from bingads.authorization
The solution I ended up with is as follows:
The init for authOAuthDesktopMobileAuthCodeGrant shows the following, note that tenant is defaulted to "common".
def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION, oauth_scope=MSADS_MANAGE, **tenant='common'**):
Therefore, in order to overwrite /common like others here have done. I had to set this tenant component here to my app's tenant ID
authentication = OAuthDesktopMobileAuthCodeGrant(
client_id=client_id,
tenant="{YOUR_TENANT_ID}",
env='production'
Hope this is useful to others who are working out of python.
I'm working on an ASP.NET Core project that will be deployed to AWS. Recently the client came back and requested to pull a few values from AWS SecretsManager. I'm using the permissions inherited from the IAM Role associated to the EC2 instance that the service is deployed to.
In production use this service will be hosted by the client themselves on their own AWS account.
When I deploy to my own test AWS account the process works just fine but when the client deploys to their own AWS account they are getting a 403 Forbidden response on the call to get the secret value. They have the secret and permissions policy set up like I do but still the 403 error.
AmazonSecretsManagerClient client = new AmazonSecretsManagerClient();
var secretRequest = new GetSecretValueRequest
{
SecretId = "MySecretName"
};
// FAILS HERE
GetSecretValueResponse secretResponse = await client.GetSecretValueAsync(secretRequest);
It is a HttpRequestException with a message of "Response status code does not indicate success: 403 (Forbidden)."
My question isn't really a coding issue since this does work on my test AWS account. This seems like it must be an environment issue with the client's AWS account.
My experience with AWS is very limited so I have no idea what would be causing this.
Is the customer trying to fetch the exact same secret you are using in your account? This would require using a custom CMK and adding a resource policy granting access as described in the AWS docs.
How do i make logins happen via Amazon Cognito REST APIs (for user pools) on platforms for which there is no official SDK? - Note that i am asking for user pools - not identity pools.
Synopsis
Amazon cognito provides 3 kinds of logins:
federated logins (creates identity pools) - using social connects like FB, Twitter, G+ etc
AWS managed logins (creates user pools) - using Amazon's own managed signup, signin, forgot password, reset password services
developer provided logins (my custom designed authentication service managed by myself)
I am using the second one (with User Pools)
Amazon cognito has several SDKs for android, iOS, javascript, Xamarin etc. Cognito also provides REST APIs for building on platforms other than those supported by official SDKs. I am building an app for a different platform and, hence, REST API is my only way as there is no official SDK for my platform.
The Cognito REST API provides various endpoints for 'sign up', 'forgot password', 'confirm verification' etc, but surprisingly, the REST API does not have any endpoint for simple signin / login.
From Cognito CLI API docs I have all the OFFICIAL CLI APIs necessary to "signup users", "confirm signups", "change passwords", "verify phone numbers", "forgot passwords" etc. Surprisingly there is no CLI API mentioned for LOGINs. I was hoping there should be some CLI API like "$ aws cognito-idp log-in" just like there is for "$ aws cognito-idp sign-up" or for "$ aws cognito-idp forgot-password" etc.
Also from this getting started tutorial it talks about "*what should be done with tokens received AFTER successful authentication of a user*". However, it doesn't talk about HOW TO make the successful authentication happen on the first place with Cognito User Pool APIs. Examples are available only for Android, iOS, javascript SDKs. There are no authentication examples available for platforms which do not have SDKs.
Hence, How do i make logins happen via Amazon Cognito REST APIs (for user pools) on platforms for which there is no official SDK?
This curl command works for me:
curl -X POST --data #aws-auth-data.json \
-H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
-H 'Content-Type: application/x-amz-json-1.1' \
https://cognito-idp.us-east-1.amazonaws.com/
Where aws-auth-data.json is:
{
"AuthParameters" : {
"USERNAME" : "yourusername#example.com",
"PASSWORD" : "yourpassword"
},
"AuthFlow" : "USER_PASSWORD_AUTH",
"ClientId" : "75........................"
}
The user pool client must allow USER_PASSWORD_AUTH for this to work - that's an AWS-side setting.
Update:
As you pointed out in the comments below, the authentication flow is documented here: http://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html. This might help to clarify the authentication flow
It is somewhat counter-intuitive, but it does make sense for mobile apps where you don't want to have the user explicitly sign in, but instead carry tokens around for the user. Note that there is an explicit signin (login) API in the AWS Userpools SDK for iOS. I have not used it, but I suppose it is just an alternate client side API to get through the same InitiateAuth() followed by a RespondToAuthChallenge() flow. The iOS signin example is documented here - IOS SDK Example: Sign in a User
Original Post:
The Cognito User Pools API documentation for initiating auth is available here
The way it works becomes clearer if you implement a user pools application in one of the SDK's (I did one in Swift for iOS, it is clarified because the logging of the JSON responses is verbose and you can kind of see what is going on if you look through the log).
But assuming I understand your question: In summary you should InitiateAuth() and the response to that (from the Cognito User Pools server) is a challenge. Then you do RespondToAuthChallenge() (also documented in that API doc) and the response to that is an authentication result - assuming that the password / session / token were accepted.
The combination of those two things is, I believe, what you are calling LOGIN, and it works like a login. In the API's, the way it is set up is that attempts to get user information when the user is unauthenticated kicks off that InitiateAuth() and (in iOS anyway) the API does a callback to the code you write to ask for passwords, and send a RespondToAuthChallenge() request etc.
Just to add to #andrewjj's answer. You might get back a challenge (NEW_PASSWORD_REQUIRED) as InitiateAuth response. It is when you are being asked to change passport on initial signin.
You can use Postman or curl command. This example expects Postman being used.
InitiateAuth - This step is same as #andrewjj
Add this to Body as raw values
{
"AuthParameters": {
"USERNAME": "youremail#example.com",
"PASSWORD": "temporary-password",
},
"AuthFlow": "USER_PASSWORD_AUTH",
"ClientId": "2s........................"
}
Set headers
X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth
Content-Type: application/x-amz-json-1.1
Send a request to https://cognito-idp.us-east-1.amazonaws.com/ You might have to change region.
If you receive this response then your are ok, otherwise continue with step 2.
{
"AuthenticationResult": {
"AccessToken": "eyJra........",
"ExpiresIn": 3600,
"IdToken": "eyJra........",
"RefreshToken": "eyJjd........",
"TokenType": "Bearer"
},
"ChallengeParameters": {}
}
RespondToAuthChallenge - this is new step
In case you receive Challenge back like this one:
{
"ChallengeName": "NEW_PASSWORD_REQUIRED",
"ChallengeParameters": {
"USER_ID_FOR_SRP": "1231-......",
"requiredAttributes": "[]",
"userAttributes": "{\"email_verified\":\"true\",\"email\":\"youremail#example.com\"}"
},
"Session": "Sfas......"
}
You need to set new password. Add this to Body as raw values
{
"ChallengeName": "NEW_PASSWORD_REQUIRED",
"ChallengeResponses": {
"USERNAME": "youremail#example.com",
"NEW_PASSWORD": "newpassword"
},
"ClientId": "2s........................",
"Session": "Sfas......(use one from the InitiateAuth response)"
}
Set headers
X-Amz-Target: AWSCognitoIdentityProviderService.RespondToAuthChallenge
Content-Type: application/x-amz-json-1.1
Send a request to https://cognito-idp.us-east-1.amazonaws.com/ You might have to change region.
Do step 1 again to receive tokens.
Sharing curl direct may help to anyone
curl -X POST --data #user-data.json \
-H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
-H 'Content-Type: application/x-amz-json-1.1' \
https://cognito-idp.<just-replace-region>.amazonaws.com/
file json user-data.json
{"AuthParameters" : {"USERNAME" : "sadfsf", "PASSWORD" : "password"}, "AuthFlow" : "USER_PASSWORD_AUTH", "ClientId" : "csdfhripnv7sq027kktf75"}
make sure your app client does not contain app-secret or create new app without secret. also inside app enable USER_PASSWORD_AUTH
One of the developers from AWS Cognito team here.
To add to #md-abdul-munim's answer, we recommend using one of the client side SDKs. If you are building a REST API and then a front end which talks to those APIs, it is better to just integrate Cognito from your front end.
If you absolutely need to use Cognito from a back end, the authentication APIs will be available with our GA release. In our Cognito User Pools beta release authentication is only available through client SDKs.
From what you have discussed, I consider you are trying to do that from a web frontend. Cause, cognito is providing you the necessary backend support and it expects you to communicate(e.g. authenticate, sign up etc.) from a presentation layer- that's why you found SDK's for different mobile platforms. They also have SDK for web app- the access is available via their Javascript SDK.
Here's a detailed tutorial to achieve what you have asked from a web frontend using their JS SDK-
Accessing Your User Pools using the Amazon Cognito Identity SDK for JavaScript
I have a similar problem and was wondering how to integrate Cognito within an Elixir backend and found this library: https://github.com/aws-beam/aws-elixir
From what I can understand by reading its source code, they ultimately make a POST request that contains the header "X-Amz-Target": "AWSCognitoIdentityProviderService.#{name_of_api_action}" (this is here: https://github.com/aws-beam/aws-elixir/blob/master/lib/aws/cognito_identity_provider.ex#L564). That's without the authorization headers, they are added elsewhere, but I found it interesting. The functions that construct the request URL are following, so you should be able to get an idea of the endpoint that gets called.
I must say I tried following this article written in Japanese - https://qiita.com/yujikawa/items/e79929ed14277102f4b8, and couldn't manage to make it work, maybe because I was not sure what the proper AWS_ENDPOINT environment variable should be. I am currently thinking of trying out the Ruby SDK, from the looks of the documentation it seems fine. But, nonetheless, this information may still help someone.
Thank #andrewjj, your answer is a big help.
Here is additional info for someone who has trouble with client secret. You don't need to turn it off.
You need to generate a secret hash from username, clientId, client secret, as following:
message = bytes(username+app_client_id,'utf-8')
key= bytes(clientSecret,'utf-8')
secret_hash = base64.b64encode(hmac.new(key, message, digestmod=hashlib.sha256).digest()).decode()
src: https://aws.amazon.com/premiumsupport/knowledge-center/cognito-unable-to-verify-secret-hash/
Then add the secret hash to your AuthParameters, as following:
{
"AuthParameters" : {
"USERNAME" : "...",
"PASSWORD" : "...",
"SECRET_HASH" : "..."
},
"AuthFlow" : "USER_PASSWORD_AUTH",
"ClientId" : "..."
}
I have successfully installed WSO2 API Manager and WSO2 BAM. I can access my IP::9443/publisher/, IP:9443/stores/, IP:9443/carbon/ and :9444/publisher/ application from browser.
I'm trying to access the publishers and stores via APIs in order to have this available for customers. I'm referring the documentation for it at http://docs.wso2.org/wiki/display/AM140/Publisher+APIs but when I try to hit my application with
curl -X POST -c cookies http://IP:9763/publisher/site/blocks/user/login/ajax/login.jag -d 'action=login&username=MY_USERNAME&password=MY_PASSWORD'
it gives output as below
{"error" : false}
and I see following in cookie file.
# cat cookies
# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This file was generated by libcurl! Edit at your own risk
# HttpOnly_IP_HERE FALSE /publisher/ FALSE 0 JSESSIONID XYZ_SESSION_ID_HERE
I couldnt find any article related to this so posting it here. I tried the same for /stores too and it also failing with the same messeage. Am I missing something to get this working? Appreciate any resolution if any one is aware of.
Thank you!
There is no issue here. {"error" : false} means No error. The login is Successful. If there is any issue the response will be different and error message will include in the response with error:true.
You can call the publisher API after this. It should work.