I have a Cognito app client configured to use USER_PASSWORD_AUTH flow. By POSTing this request:
{
"AuthParameters": {
"USERNAME": "{{Username}}",
"PASSWORD": "{{Password}}"
},
"AuthFlow": "USER_PASSWORD_AUTH",
"ClientId": "{{AppClientId}}"
}
to "cognito-idp.us-east-1.amazonaws.com", I am able to successfully authenticate and retrieve JWTs.
I would like to CNAME the URL to be something like "auth.mydomain.com", but when I do that, I get a client certificate validation error. Is there anyway to associate a valid certificate so I can CNAME the URL successfully?
You can configure a custom domain within your Cognito user pool. That's what we had to do to make this work. Check out this Cognito documentation. It discuses using the hosted UI stuff, but it should also apply to your scenario where you provide the login UI.
Related
I would like to ask how to properly setup the authentication for Portainer CE v2.9.3 using OAuth2 with Azure AD.
The following fields in the Custom OAuth2 UI needs to be filled:
Client ID
Client secret
Authorization URL
Access token URL
Resource URL
Redirect URL
Logout URL
User identifier
Scopes
Currently, I use the following values:
Client ID: <tentant id>
Client secret: <created secret for the app in Azure AD>
Authorization URL: https://login.microsoftonline.com/``/oauth2/v2.0/authorize
Access token URL: https://login.microsoftonline.com/``/oauth2/v2.0/token
Resource URL: https://graph.microsoft.com/oidc/userinfo
Redirect URL: <our internal URL for the Portainer deployment>
Logout URL: <our internal URL for the Portainer deployment>
User identifier: email
Scopes: <Application ID URI>
When using these values, I get the following error:
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token validation failure. Invalid audience.",
"innerError": {
"date": <some date>,
"request-id": <some request id>,
"client-request-id": <some client request id>
}
}
}
I need to use Portainer CE with the Customer OAuth Provider.
Thank you for any usefull advice.
Possible causes of Audience invalid error and workarounds
Client ID must be either the ApplicationId or ApplicationIdUri
depending on the app configuration.(not tenant Id)
Note :first try clientId:<Application Id> and if that is giving the
same error , change clientId to ApplicationIdUri i.e; clientId:api://<Application Id>
Scope is something that you see under add a scope blade .
When you click on add a scope ,you can mention any permission and it appears as a scope like below:
This scope must be in scopes value
Make sure to grant admin consent if required if app registration has permissions.
Example:
Another is the end point from which you are getting the token maybe different . Try to decode access token in https://jwt.io and see “ISS” value has v2 endpoint .If it has V2 endpoint,
in azure Active directory, Go to Manifest and change “accessTokenAcceptedVersion”:2 .Also check that Audience value i.e; “AUD” must match the client Id .The audience invalid occurs if they doesn’t match.
Reference
Details first:
Environment = Cognito Hosted UI
Situation = User signs in using it
Result = He's successfully authenticated and is redirected to whatever URL to which AWS adds the parameter "id_token=" with whatever value
Sample whatever value after decrypting that token with jwt.io =
{
"at_hash": "some_value_here",
"sub": "the_sub_id_in_cognito",
"aud": "the_client_id_of_the_cognito_app",
"email_verified": true,
"token_use": "id",
"auth_time": 1573661803,
"iss": "https://cognito-idp.us-east-1.amazonaws.com/AWSRegion_CognitoPoolName",
"name": "FirstName LastName",
"cognito:username": "the_username_in_cognito",
"exp": 1573665403,
"iat": 1573661803,
"email": "the_email_in_cognito"
}
My question = This token expires within one hour (you can't change this). And in order to keep the user authenticated for more than one hour, you'd have to submit a refresh token using the Cognito InitiateAuth API.
All fine and dandy, except I don't see any refresh token in that JSON :|
Where do I get that refresh token value ? Is it something that gets generated once (and once only) at initial user registration and I should store it in some database ?
Or is that token NOT generated by Cognito Hosted UI because it's not supported and I should stop using it altogether ?
PS: On a different note -> Is Cognito Hosted UI any good or is it bull-crap and I should stop looking into it altogether ?
Thanks and hope you can help me on this ...
Marius
Update.
I've changed my logic to continue to use Cognito Hosted UI and "generate" the HTML pages from Lambda.
I've used the logic from here -> https://github.com/aws/chalice/issues/717 to fetch the authentication code and store them as JWT tokens in cookies using Lambda.
I've also had to modify the App Client Settings in Cognito as following:
Allowed OAuth Flows = Just Authorization code grant
Basically the logic of using JWT tokens now is being generated "manually" at the Lambda layer.
Hope this helps someone out there...
I'm unable to authenticate / sign-in via AzureAD when running testCafe.
const testrole = Role(
'https://login.microsoftonline.com/',
async t => {
await t
.typeText(Selector('input').withAttribute('type', 'email'), *******)
.click(Selector('#idSIButton9'))
.typeText(Selector('input').withAttribute('type', 'password'), ********)
.click(Selector('#idSIButton9'));
},
{ preserveUrl: true }
);
The above steps work fine, however after entering the password I get a message saying:
"Unable to sign in to Outlook account, Error: AADSTS900561: The endpoint only accepts POST requests. Received a GET request."
From my initial search, it seems like something to do with 3rd party cookies on the browser. However, I'm unable to find a solution at this time.
Any idea how I get around this issue?
The Azure AD product team has always reminded me that it is a bad idea to try to automate sign in like that.
They will probably detect that you are a bot and start blocking your requests, even if you succeed.
Instead, to acquire access tokens you need to use either the client credentials flow (for app-only tokens) or the resource owner password credentials flow (for delegated user tokens).
Client credentials flow: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
ROPC flow: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc
You have to take good care to secure the credentials used for testing.
And use a test tenant if possible.
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 have an application that uses google's oauth system to authorize with youtube's api. The code for this is done on our server and we receive tokens without any problem. We'd like to move some of the api calls to the client using their javascript api.
Since we've already authorized the user with the correct scopes required for the youtube api (https://www.googleapis.com/auth/youtube) I assumed when I called authorize on the client it would know that my application was already authorized and allow auto login. Instead I receive a "immediate_failed" response. Does anyone know why? Thanks!
gapi.auth.authorize({
client_id: OAUTH2_CLIENT_ID,
scope: OAUTH2_SCOPES,
immediate: true
}, handleAuthResult);
If you have the token, you can just use setToken instead of going through OAuth2 again.