AWS Cognito finding right Parameters for CognitoSyncDemo - authentication

I'm going to setup this Example for Amazon Cognito Sync demo, using Eclipse + ADK + AWS libs V2.9.
I created an identity pool in the Cognito Console, so I got the Identity Pool ID which is used in CognitoSyncClientManager.java at:
private static final String IDENTITY_POOL_ID = "us-east-1:1a23b013-1abc-123-b123-123abc1fe5";
private static final Regions REGION = Regions.US_EAST_1;**
(perhaps not all regions seem to run in test mode)
I registered my (developing-)app in the Seller Central with Eclipse Help>Android>Bild>MD5 fingerprint and the package-name from AndroidManifest.xml, so got my api_key.txt Value.
From the AWS doku I got my Provider URL (code as sample), which is used in DeveloperAuthenticationProvider.java at:
private static final String developerProvider = "cognito-sync.us-east-1.amazonaws.com";
private static final String cognitoSampleDeveloperAuthenticationAppEndpoint = "arn:aws:iam::123456789123:role/Cognito_TestMyAppAuth_DefaultRole"
private static final String cognitoSampleDeveloperAuthenticationAppName = "Cognito sync demo";
After creating some Users which are attached to groups with permissions to IAM full access and (auto)generated roles for unautherized and autherized Roles, my app is running in this way:
Login with Amazon - is running, but where will their datasets be created and is it possible I see them in the AWS Console?
Simple Browse your data (without login) - is running, unauthenticated users and their datasets appear/are counted in the Identity console
Developer Authentication fails with Username or password do not match - combined with an "Unable to reach resource..." in the LogCat.
Now I think, the last missing thing in this game is the parameter cognitoSampleDeveloperAuthenticationAppEndpoint=...
Where can I find it and what else could I have missed to setup for a full running Example?

Thanks for using Cognito demo. Answers to your questions
Yes, you can see the datasets in the AWS console. Navigate to Cognito inside the AWS Console and go to your identity pool. On the left hand side menu go to identity browser and you will see the list of identities or you can search for an identity. Click on the identity and you can see the datasets owned by that identity.
Developer Authentication is a feature which helps to integrate your authentication system with Cognito. For this you should have a backend server serving user's authentication requests, and once you authenticate users you can request OpenId Connect tokens for them from Cognito using the GetOpenIdTokenForDeveloperIdentity API call. The developer provider name is the one which you setup for your identity pool in the AWS Cognito console. For using the sample you can setup a sample server application by following this blog and the readme file of the the server side application.
P.S.: Please avoid sharing your identity pool id.
Thanks,
Rachit

Related

How to add Pinpoint or Kinesis Streams to Amplify project initialized with an imported Cognito UserPool configured as UserPoolOnly

I set up my Cognito UserPool as UserPoolOnly at creation a few months back, before my team considered that we would possibly need an Identity Pool later on for gathering user data. This was set up from an existing user base, so it was configured as an imported User Pool.
We now have hundreds of active users and I am trying to add Amazon Pinpoint to gather user session data to improve our UX, but am getting the following error because I don't have an identity pool in our Amplify project
Error: Current auth configuration is: userPoolOnly, but identityPoolOnly was required.
Auth configuration is required to allow unauthenticated users, but it is not configured properly.
I tried creating a new identity pool, basing it off the Cognito UserPool and adding the same app id and federated identity app ids to "attach" it, but this does not change the error after running amplify pull - I think because it is still not associated with Amplify.
When running amplify update auth I get the error Updating imported Auth resource is not supported.
How can I fix the issue of not having an identity pool associated with my Amplify project but needing it for Pinpoint?
Note:
Trying to use Kinesis Streams instead of Pinpoint gives the same Error about identityPoolOnly being required

Kusto.Explorer requires secondary account to access azure Log Analytics workspace

I am having a challenge accessing azure LA/AI workspace with desktop Kusto.Exploer. I cannot use RUNAS to invoke my secondary account with credentials, accessing workspace in azure. Note that I am able to do that using dataexplorer.azure.com ( since i am already logged into azure portal). Any help will be appreciated.
Kusto Explorer allows sign in form within the Client itself – using the Connections toolbar : https://learn.microsoft.com/en-us/azure/data-explorer/kusto/tools/kusto-explorer#connections-tab
You can –
Click on ‘Sign-Out from AAD’
Add your cluster again, and now you'll be prompted to Sign In where you can use the creds from your other User Account.
If the issue is that you are logging to the Log Analytics namespace from a different tenant, you can specify it in the cluster connection "advanced connection string" settings and add at the end the applicable tenant guid using the following ";authority id = tenant Guid" syntax, for example:

Azure SQL authenticate as user via API with MS Identity Platform

I have an ASP.NET Core 3.1 Web App calling an ASP.NET Core 3.1 Web API, which in turn accesses an Azure SQL database. Authentication is provided via MSAL (Microsoft Identity Platform) - i.e. using the relatively new Microsoft.Identity.Web and Microsoft.Identity.Web.UI libraries.
The goal is to ensure that the user pulls data from SQL via the API under the context of his/her own login, thus enabling row-level security, access auditing and other good things.
I have succeeded in getting the sign-in process to work for the Web App - and through that it obtains a valid access token to access the API using a scope I created when registering the latter with AD.
When I run both the API and the App locally from Visual Studio everything works as expected - the correct access tokens are provided to the App to access the API, and the API to access SQL - in both cases under the user's (i.e. my) identity.
When I publish the API to App Services on Azure, however, and access it there either from a local version of the Web App or an App-Services hosted version of it, the access token that the API gets to access SQL contains the API's Application Identity (system-assigned managed identity), and not the user's identity. Although I can access SQL as the application, it's not what we need.
The Web App obtains its access token using the GetAccessTokenForUserAsync method of ITokenAcquisition - taking as a parameter the single scope I defined for the API.
The API gets its token (to access SQL) like so:
var token = await new AzureServiceTokenProvider().GetAccessTokenAsync("https://database.windows.net", _tenantId)
...where _tenantId is the tenant ID of the subscription.
I have added the SQL Azure Database "user_impersonation" API permission to the AD registration for the API - but that has not helped. As an aside, for some reason Azure gives the full name of this permission as https://sql.azuresynapse.usgovcloudapi.net/user_impersonation - which is slightly alarming as this is just a UK-based regular Azure account.
I have found a few similar posts to this, but mostly for older versions of the solution set. I'm hoping to avoid having to write my own code to post the token requests - this is supposed to be handled by the MSAL libraries.
Should I somehow be separately requesting a SQL access scope from the Web App after sign-in, or should the API be doing something different to get hold of a SQL access token that identifies the user? Why does it work perfectly when running locally?
It seems like this should be a very common use case (the most common?) but it is barely documented - most documentation I've found refers only to the application identity being used or doesn't tell you what to do for this particular tech stack.
Finally - success! In the end this was the critical piece of documentation: Microsoft identity platform and OAuth 2.0 On-Behalf-Of flow - the key points being:
The App only asks for a token to access the API.
The API then requests a token, on behalf of the user identified via the 1st token, to access SQL.
The key is that - since the API cannot trigger a consent window for the second step - I had to use the Enterprise Applications tab in the Azure portal to pre-grant the permissions for SQL.
So the good news is it does work: maybe it's obvious to some but IMO it took me far too long to find the answer to this. I will write up a fuller explanation of how to do this in due course as it can't only be me struggling with this one.
The bad news is that - in the course of my investigations - I found that Azure B2C (which is the next thing I need to add in) doesn't support this "On Behalf Of" flow - click here for details. That's a great shame as I think it's the most obvious use case for it! Oh well, back to the drawing board.
I'm currently working on a similar problem, using a Net5.0 Web app. The reason it appears to be working locally is you are signed into Visual Studio with a user who can access Azure SQL and those are the rights you get in the Db. The IDE is using those credentials in place of the Managed Service Identity, the latter gets used when you upload the app to Azure.
As you noted, in the App registration you need to grant permission to the App for Azure SQL Database user_impersonation.
In your code, you need to request a token from https://database.windows.net//.default (note the // as it's needed for v1 endpoints). By referencing /.default you are asking for all permissions you've selected for the app in the app registration portal.
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#the-default-scope
In Startup.cs you need to EnableTokenAcquisitionToCallDownstreamApi with the scope you require.
services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi(new[]
{"https://database.windows.net//.default"})
// Adds the User and App InMemory Token Cache
.AddInMemoryTokenCaches();
services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the
// default policy
options.FallbackPolicy = options.DefaultPolicy;
});
services.AddDbContext<MyDatabaseContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("MyAzureConnection")));
// The database interface
services.AddScoped<ITodos, TodoData>();
services.AddRazorPages()
.AddRazorRuntimeCompilation()
.AddMvcOptions(o =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
o.Filters.Add(new AuthorizeFilter(policy));
})
.AddMicrosoftIdentityUI();
You also need to decorate your controllers with [AuthorizeForScopes(Scopes = new string[]{"https://database.windows.net//.default"}] and include the required scopes for that Controller. For Razor, it's at the top of the page model and requires a reference to `using Microsoft.Identity.Web;'
namespace ToDoApp.Pages.Todos
{
[AuthorizeForScopes(ScopeKeySection = "AzureSQL:BaseUrl")]
public class CreateModel : PageModel
I'm using a section in my appsettings.json for the scope and retrieving it using ScopeKeySection:
"AzureSQL": {
"BaseUrl": "https://database.windows.net//.default",
"Scopes": "user_impersonation"
}
This shows you where to include it for MVC, Razor and Blazor:
https://github.com/AzureAD/microsoft-identity-web/wiki/Managing-incremental-consent-and-conditional-access#in-mvc-controllers
Finally, your DbContext needs a token which you could pass to it from the client app (perhaps...).
This is how I am doing it at the moment
public class MyDatabaseContext : DbContext
{
private readonly ITokenAcquisition _tokenAcquisition;
public MyDatabaseContext (ITokenAcquisition tokenAcquisition,
DbContextOptions<MyDatabaseContext> options)
: base(options)
{
_tokenAcquisition = tokenAcquisition;
string[] scopes = new[]{"https://database.windows.net//.default"};
var result = _tokenAcquisition.GetAuthenticationResultForUserAsync(scopes)
.GetAwaiter()
.GetResult();
token = result.AccessToken;
var connection = (SqlConnection)Database.GetDbConnection();
connection.AccessToken = result.token;
}
This is a flawed solution. If I restart the app and try to access it again I get an error Microsoft.Identity.Web.MicrosoftIdentityWebChallengeUserException: IDW10502: An MsalUiRequiredException was thrown due to a challenge for the user
It seems to be related to the TokenCache. If I sign out and in again or clear my browser cache the error is resolved. I've a workaround that signs the app in on failure, but it's deficient since I'm using the app's credentials.
However, it successfully connects to the Azure SQL Db as the user instead of the App with the user's rights instead. When I do solve the error (or find one) I will update this answer.

Using Cognito User Pools, without Cognito Federated Identities(identity pools)

I would like to use only Cognito User Pool, and therefore I want to use identity federation with Cognito User Pools, without Cognito Federated Identities (identity pools).
I have followed the documentation, but I couldn't succeed.
http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-social.html
Her is my User Pool configuration.
How can I combine Google and Cognito in User Pool without using identity pool (Federated Identities). Or is that possible?
Based on your comment to Summer Guo, here's what it seems like you're having an issue with...
A lot of details missing here, but if you're using a Cognito Authorizer in your API Gateway, then it doesn't know about any 3rd party IdP -- it just knows about your Cognito User Pool. So sending the CUP JWT will work, while sending anything else won't. If you want to use a Google auth token, then you need to implement a Custom Authorizer that verifies this token with Google.
I presented on this topic during reInvent. Here's the video that goes into the details:
https://www.youtube.com/watch?v=VZqG7HjT2AQ
it is possible to have a user pool with google configured as an identity provider without using Cognito Federated Identities. Cognito has SDKs available for Android, iOS, and Javascript, you can find them on github(https://github.com/aws/). Can you be more specific about the problem you are running into when trying to do this?
Looks like they only allow User Pool Federation with their own UI/SDK. What I ended up doing for react-native was
get facebook token
sign up the user into the user pool with a custom attribute to track facebook Id and generic password
use the temporary credentials (need to setup IAM for cognito user pool - adminMovetoGroup to move the user into the auto created user pool federated group.
create lambda function to auto-confirm the end user.
This way the user can log in and get credentials using federated identities, but then they also have an account in the event they stop using facebook. They would also need to reset their password.
If you are using your own Custom UI, you will need to create a button/anchor to redirect to the user.
This is what I use to create a url (JS Code):
`https://${domain}/oauth2/authorize`,
`?redirect_uri=${redirectSignIn}`,
`&response_type=${responseType}`,
`&client_id=${userPoolWebClientId}`,
`&identity_provider=${providerName.toString()}`
providerName is either Facebook/Google
responseType is either token/code
domain your domain in cognito userpool config
redirectSignIn your redirect sign in in Cognito User Pool Config
You will need to call window.location.assign({the url generated above}). When user clicks the button, it will redirect to either Facebook/Google page asking for Account/Permission.
As for as I know, Facebook/Google dialog for custom UI is not yet supported.
Example code from AWS Amplify
import { Auth } from 'aws-amplify';
const config = Auth.configure();
const {
domain,
redirectSignIn,
redirectSignOut,
responseType } = config.oauth;
const clientId = config.userPoolWebClientId;
// The url of the Cognito Hosted UI
const url = 'https://' + domain + '/login?redirect_uri=' + redirectSignIn + '&response_type=' + responseType + '&client_id=' + clientId;
// Launch hosted UI
window.location.assign(url);
Link: https://aws-amplify.github.io/docs/js/authentication
Another thing, you can link federated identity to a user pool account.
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#adminLinkProviderForUser-property

Subscription-scope authorization for Azure Resource Manager API user

Trying to put together an Azure ARM integration, where my code uses the Azure API to retrieve the full list of VMs in the entire subscription.
Went successfully through all the (many!) steps here to get an API user ready with all relevant IDs needed for authentication.
Using the same set of instructions, we were also able to grant this user the Reader role, for listing VMs in specific groups (we did this through the Azure UI). However, we have been unsuccessful in implementing the instructions here for setting up Reader role for this user to the entire subscription (through the CLI).
Running this:
azure role assignment create --objectId app-oid --roleName Reader --scope /subscriptions/subscription-id
Or this:
azure role assignment create --objectId app-oid --roleName Reader --subscription subscription-id --scope /subscriptions/subscription-id
Yields this:
Principals of type Application cannot validly be used in role assignments.
So currently we have no way of programmatically browsing the full set of VMs without adding a specific authorization for each Resource Group.
Does anybody know of a way that actually works to assign this permission at the subscription level?
Found the answer in the comment area of the link in the question body:
In the new portal, edit the subscription and add the role, just like you would do with a resource group. Still curious as to why the CLI doesn't support this.
The steps to use the Azure CLI to create and authorize a service principal are documents here: https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal-cli/
Instead of using --objectId app-oid try using -ServicePrincipalName <appId>
https://github.com/Azure/azure-powershell/issues/4776
Had the same error for role assignment with terraform
Principals of type Application cannot validly be used in role assignments.
But as described here, using the Object Id that is displayed on the overview page of the app registration in the Azure portal resulting the above error.
The solution is to get the Object Id from azure cli:
az ad sp show --id [Application (client) Id] -o json | grep objectId
# and then using this objectId assign your role
az role assignment create --role contributor —-assignee-object-id [object id] —-resource-group [MyResourceGroup]