We will set up a simple Angular frontend web app with
ASP.NET Core Web API backend (.NET 5.0) using
AWS Cognito as authentication provider. Users will be able to sign up, confirm sign up/verify and sign in. The backend WebAPI will be the point of contact and interaction with AWS Cognito. The frontend Angular web app will simply pass user information and then keep the Cognito Access Token passed by the backend WebAPI.
This writing will be divided into three parts:
- Set up AWS Cognito and backend Web API user functions - this post
- Configure CORS in Web API backend - next post
- Authentication between frontend and Web API backend - next post
On this first series, we will set up
AWS Cognito and
ASP.NET Core Web API backend (.NET 5.0) with some user sign up an sign in functions.
1. First, create a new user pool in
AWS Cognito then create a new
App Client.
Make sure 'Enable username password auth for admin APIs for authentication (ALLOW_ADMIN_USER_PASSWORD_AUTH)' is selected:
2. Create an ASP.NET Core Web API project. On
Startup.cs file inside
ConfigureServices method set
options.Audience and
options.Authority
public void ConfigureServices(IServiceCollection services)
{
// AWS Cognito
services.AddAuthentication("Bearer")
.AddJwtBearer(options =>
{
options.Audience = "[APP_CLIENT_ID]";
options.Authority = "https://cognito-idp.[REGION_NAME].amazonaws.com/[USER_POOL_ID]";
});
. . .
}
App Client Id is shown on:
Then for the
Authority field, we can get Region and User Pool Id from
3. In
Configure(IApplicationBuilder app, IWebHostEnvironment env) method, add
app.UseAuthentication();
after
app.UseRouting() is called.
4. Make sure your project has this
AWSSDK.CognitoIdentityProvider package installed
5. Then we can add sign up feature in a controller
[HttpPost]
[Route("api/signup")]
public async Task<ActionResult<string>> SignUp(User user)
{
var cognito = new AmazonCognitoIdentityProviderClient(_region);
var request = new SignUpRequest
{
ClientId = _clientId,
Password = user.Password,
Username = user.Username
};
// Cognito email attribute
var emailAttribute = new AttributeType
{
Name = "email",
Value = user.Email
};
request.UserAttributes.Add(emailAttribute);
var response = await cognito.SignUpAsync(request);
return Ok(response);
}
6. When a user sign up with the method above, its Account Status is "
Unconfirmed" and Email Verified is "
false". A confirmation email will be sent with a code. We need to add another function to handle this.
[HttpPost]
[Route("api/confirmSignUp")]
public async Task<ActionResult<string>> ConfirmSignUp(string username, string confirmationCode)
{
var cognito = new AmazonCognitoIdentityProviderClient(_region);
var request = new ConfirmSignUpRequest
{
ClientId = _clientId,
Username = username,
ConfirmationCode = confirmationCode
};
var response = await cognito.ConfirmSignUpAsync(request); // after calling this method, user's Account Status will become 'Confirmed' and Email Verified become 'true'
return Ok(response);
}
7. Then the sign in function. This will return an Access Token if successful.
[HttpPost]
[Route("api/signin")]
public async Task<ActionResult<string>> SignIn([FromBody] User user)
{
var cognito = new AmazonCognitoIdentityProviderClient(_region);
var request = new AdminInitiateAuthRequest
{
UserPoolId = _userPoolId, // User Pool Id
ClientId = _clientId, // App Client Id
AuthFlow = AuthFlowType.ADMIN_USER_PASSWORD_AUTH
};
request.AuthParameters.Add("USERNAME", user.Username);
request.AuthParameters.Add("PASSWORD", user.Password);
var response = await cognito.AdminInitiateAuthAsync(request);
return Json(response.AuthenticationResult.AccessToken);
}
Additional resend confirmation code and find user functions:
[HttpPost]
[Route("api/resendConfirmationCode")]
public async Task<ActionResult<string>> ResendConfirmationCode(string username)
{
var cognito = new AmazonCognitoIdentityProviderClient(_region);
var request = new ResendConfirmationCodeRequest
{
ClientId = _clientId,
Username = username
};
var response = await cognito.ResendConfirmationCodeAsync(request);
return Ok(response);
}
[HttpPost]
[Route("api/findUser")]
public async Task<ActionResult<string>> FindUser(string username)
{
var cognito = new AmazonCognitoIdentityProviderClient(_region);
var request = new AdminGetUserRequest
{
UserPoolId = _userPoolId,
Username = username
};
var response = await cognito.AdminGetUserAsync(request);
return Ok(response);
}
On the next post, we will set up CORS (Cross-Origin Resource Sharing) in the project.