日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

.net 8 C# 集成 AWS Cognito SMS/Email 注册与登录

發布時間:2025/3/8 C# 44 如意码农
生活随笔 收集整理的這篇文章主要介紹了 .net 8 C# 集成 AWS Cognito SMS/Email 注册与登录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文主要分為三個部分:

1、描述 cognito 涉及的專業術語 以及 交互流程

2、.net 集成的代碼

3、感想

* 閱讀提示 :鼠標懸停在 章節標題 上可見 文章目錄

1. Cognito 概念

1.1 關鍵詞

進入 Amazon Cognito,會先看到 user pool 的列表

cognito
亞馬遜(Amazon)云 提供的一種用戶管理服務,簡化用戶注冊、登錄和授權、鑒權相關的服務操作。
可以在 cognito 上創建用戶池,管理用戶注冊、登錄和鑒權相關的問題;
可以創建 identity pool 對用戶進行授權相關的約束;
支持多種身份驗證方式,例如 用戶 / 密碼 登錄,社交帳號( Facebook,Google 等)登錄,企業身份供應商
 
* What is Amazon Cognito? - Amazon Cognito
user pool
用戶池,多租戶 / 不同的服務供應商,擁有自己的用戶群體;
用戶池支持用戶注冊、登錄、鑒權、賬號恢復等。
identity pool
資格授權池,可以提供一些 AWS 的資格認證到通過驗證的用戶上
app client
用戶池所關聯的應用服務端,必須要配置到相關的用戶池上才允許訪問該用戶池

選定一個用戶池,可以查看該用戶池的信息,左側欄見其 功能 / 配置

user pool 功能 / 配置 目錄列表

* 為了降低描述的復雜度,此處僅做最小配置展開

* 加粗為需要重點關注;此處不展開 IdentityPool 以及 userPool.Security 和 userPool.Branding

Seconcd

Third

Description

Remark

User Pool

Overview

用戶池的基本信息

集成時需要找到這個用戶池的 ID、ARN 等信息

Applications

app client

配置可訪問該用戶池的應用端信息

在此處可以限制一些讀寫的權限

User Management

Users

用戶池里面的每個用戶

相當于用戶表,可以自定義用戶屬性 custom user attribute

Groups

用戶分組,主要用于指定某個組內的用戶可以享有某些權限

按需求來,可選配置

Authentication

Authentication methods

用戶驗證方式的配置

可以在此處配置密碼驗證 或 通過短信驗證 或 通過郵箱驗證

Sign-in

用戶登錄時的相關配置

例如密碼復雜度,登錄方式

Sign-up

用戶注冊時的相關配置

Social and external providers

通過第三方登錄的配置,像是通過 Facebook, Google, Amazon or Apple..等其他供應商來授權

Extensions

通過一些自定義的驗證行為,觸發 AWS lambda function。此處是觸發器的配置。

此處的觸發條件是 cognito 規定好的。也即僅可以配置:要不要觸發,觸發哪一個function

Security

AWS WAF

Threat protection

Log streaming

Branding

Domain

Managed login

Message templates

Identity Pool

Overview

Authentication Providers

Roles

IAM Policies

Data Synchronization

Cognito 主要是做 用戶管理 的事情,它支持通過 密碼、手機短信、郵箱地址、其他企業供應商(例如 facebook、apple account 等) 等方式授權 token,

本文主要描述 自定義校驗 custom authentication 的方式,此處要求在 user pool 中配置 3 個 AWS lambda function ,cognito 將會觸發它的執行。

Lambda function 也是 Amazon web service 其中之一,此處可以簡單地把其當作一個AWS的 api 方法。

這里涉及到 3 個觸發器:define auth challengecreate auth challengeverify auth challenge

Custom authentication trigger type

Define Auth Challenge

custom authentication 的第一步,這里會返回 custom challenge name 到 cognito;同時也可以基于用戶邏輯,直接在此處發布 token 。

Create Auth Challenge

custom authentication 流程的第二步,實現自定義身份驗證的步驟。通常在這一步中寫入驗證的答案,驗證的問題可以是 captchas 或者其他安全問題 或 驗證碼 等。

Verify Auth Challenge

custom authentication 的第三步,校驗用戶輸入的答案與在 create auth challenge 中預設的答案是否一致

下文將描述我們的代碼會如何與 cognito 交互,又是如何觸發對應的 lambda function。

1.2. 流程圖

登錄步驟 1:輸入賬號

  • 前端第一次調用接口,是提交登錄的請求;
  • 后端調用 AWSSDK.CognitoIdentifyProvider 中 cognitoClient.InitiateAuthAsync 方法,這個方法是 cognito 支持的自定義驗證方式,它會自動觸發到 define auth challengecreate auth challenge
  • 此處發送短信的方式是后端去調用了一個 AWS Lambda Function

登錄步驟 2:輸入驗證碼

  • 前端第二次調用的接口,是提交登錄的驗證碼
  • 后端會把驗證碼發送給 user pool 去做校驗,通過了校驗才能成功授權返回 token

* AWS Lambda Triggers

場景

SDK Function

Trigger the Lambda

sign-in

登錄

InitiateAuthAsync

Define Auth Challenge, Create Auth Challenge

RespondToAuthChallengeAsync

Verify Auth Challenge

sign-up

注冊

SignUpAsync

Custom message trigger

ConfirmSignUpAsync

Define auth challenge

  • 這個 trigger 用于決定下一個驗證步驟,可以在這里配置走向密碼驗證或者自定義的驗證方式。
  • 基于正確的 user session 上,它進一步定義驗證的流程

例如,用戶通過密碼驗證之后,將進入到手機短信驗證

// cognito 將會觸發到配置在 user pool 上的 lambda trigger,event 是它的入參
exports.handler = async (event) => {
if (event.request.session.length === 1 && event.request.session[0].challengeName === 'SRP_A') {
     // 是否直接發布 token
event.response.issueTokens = false;
// 是否驗證失敗
event.response.failAuthentication = false;
// 下一個驗證方式的名字
event.response.challengeName = 'PASSWORD_VERIFIER'; } else if (event.request.session.length === 2 && event.request.session[1].challengeName === 'PASSWORD_VERIFIER' && event.request.session[1].challengeResult === true) {
event.response.issueTokens = false;
event.response.failAuthentication = false;
event.response.challengeName = 'CUSTOM_CHALLENGE'; } else if (event.request.session.length === 3 && event.request.session[2].challengeName === 'CUSTOM_CHALLENGE' && event.request.session[2].challengeResult === true) {
event.response.issueTokens = true;
event.response.failAuthentication = false; } else {
event.response.issueTokens = false;
event.response.failAuthentication = true;
} return event;
};

Create auth challenge

  • 一旦 Define Auth Challenge 觸發器指明使用自定義驗證,那么 Create Auth Challenge 就會被觸發去生成驗證的內容。
  • 在這個步驟中所創建的校驗內容,是用戶必須要答復的。例如 發到 SMS、Email 上的驗證碼,或者 CAPTCHA 之類的驗證問題。

例如在 Create Auth Challenge 上設定一個將發送到 Email 的驗證碼(one-time password,簡稱 OTP),

此時 Amazon Cognito 其實會存儲這個 event 內容,關聯到用戶的 session 和 用于  Verify Auth Challenge 步驟作為校驗的答案(這里是驗證碼)

lambda function 實現示例:

   exports.handler = async (event) => {
if (event.request.challengeName === 'CUSTOM_CHALLENGE') {
const otp = '654321'; // Generate or set your OTP here
event.response.publicChallengeParameters = { otp: 'Enter the OTP sent to your email' };
event.response.privateChallengeParameters = { otp: otp };
event.response.challengeMetadata = 'CUSTOM_CHALLENGE';
}
return event;
};

Verify auth challenge

  • 該觸發器在用戶提交驗證碼之后被觸發
  • 該觸發器接收到用戶輸入的 驗證碼 后會與 Create Auth Challenge 中的驗證碼相互匹配。如果校驗正確,cognito 會處理返回的 event 并生成 token

lambda function 實現示例:

   // TriggerSource is VerifyAuthChallengeResponse_Authentication
exports.handler = async (event) => {
const expectedOtp = event.request.privateChallengeParameters.otp;
const userResponse = event.request.challengeAnswer;
event.response.answerCorrect = userResponse === expectedOtp;
return event;
};

2. 集成到 .net 8 api

.NET 中需要使用 AWS SDK 提供的 API 來與 Cognito 進行交互,

引用包:AWSSDK.CognitoIdentityProvider ,下文代碼使用的版本是 3.7.1.85

<PackageReference Include="AWSSDK.CognitoIdentityProvider" Version="3.7.1.85" />

添加引用

using Amazon.CognitoIdentityProvider;
using Amazon.CognitoIdentityProvider.Model;

cognitoClient 初始化:

var AWSregion = "ap-xxxxx-x";
_cognitoClient = new AmazonCognitoIdentityProviderClient(Amazon.RegionEndpoint.GetBySystemName(AWSregion));

2.1.1 注冊 [signup]

public async Task<SignUpResponse> SignupAsync(SignUpDto user)
{
var userName = string.IsNullOrEmpty(user.Email) ? user.PhoneNumber : user.Email;
var request = new SignUpRequest
{
// 在 cognito user pool 中配置允許訪問該 user pool 的 client 后,可以在cognito 上查看到這個 clientId
ClientId = _clientId, // cognito 會校驗代碼復雜度,需要在 user pool 中配置;但此示例中密碼是沒有作用的
Password = "carcar@2024", // 此處可以填手機號或郵箱地址; cognito user pool 中顯示的 userName 是 user pool 用戶管理意義上的 uuid
Username = userName
}; // 自定義的 user attribute
var nameAttribute = new AttributeType
{
Name = "name",
Value = user.Name
};
request.UserAttributes.Add(nameAttribute); // 自定義的 user attribute
var emailAttribute = new AttributeType
{
Name = "email",
Value = user.Email
};
request.UserAttributes.Add(emailAttribute); return await _cognitoClient.SignUpAsync(request);
}

可配置密碼復雜度配置

可以配置對 user attribute 的必填要求

查看 user attribute

2.1.2 注冊驗證 [signup-confirm]

 var confirmSignUpRequest = new ConfirmSignUpRequest
{
ClientId = "client id",
Username = "user phone / email",
ConfirmationCode = "verification code from sms or email"
}; var confirmSignUpResponse = await cognitoClient.ConfirmSignUpAsync(confirmSignUpRequest);
Console.WriteLine($"User {confirmSignUpResponse.UserConfirmed} confirmed successfully.")

2.1.3 重新發送驗證碼 [resend-confirmation]

// userName 可以是 cognito UserName,又或者是注冊時寫入的 userName 即郵箱或手機號
public async Task ResendConfirmationAsync(string userName)
{
var request = new ResendConfirmationCodeRequest
{
ClientId = _clientId,
Username = userName
}; var response = await _cognitoClient.ResendConfirmationCodeAsync(request);
}

2.2.1 登錄 [signin]

var authRequest = new InitiateAuthRequest
{
ClientId = "the client id which configures in the user pool",
AuthFlow = AuthFlowType.CUSTOM_AUTH,
AuthParameters = new Dictionary<string, string>
{
{ "USERNAME", "your_username_or_phone_or_email" }
}
}; var authResponse = await cognitoClient.InitiateAuthAsync(authRequest);

2.2.2 登錄驗證 [signin-confirm]

校驗驗證碼時,調用 RespondToAuthChallengeAsync

 var respondToAuthChallengeRequest = new RespondToAuthChallengeRequest
{
ChallengeName = authResponse.ChallengeName,
ClientId = "your_client_id",
ChallengeResponses = new Dictionary<string, string>
{
{ "USERNAME", "your_username_or_phone_or_email" },
{ "SMS_MFA_CODE", "user_received_code" }
},
Session = authResponse.Session
}; var challengeResponse = await cognitoClient.RespondToAuthChallengeAsync(respondToAuthChallengeRequest); var idToken = challengeResponse.AuthenticationResult.IdToken;

2.3 token 驗證

在 Program 或 StartUp 的配置文件中,需要配置 Authentication 中間件

* token 參數說明 - 點此跳轉查看

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = $"https://cognito-idp.{AWSregion}.amazonaws.com/{userPoolId}",
// ValidAudience = {userPoolId},
IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
{
// Get JsonWebKeySet from AWS
var json = new WebClient().DownloadString($"https://cognito-idp.{AWSregion}.amazonaws.com/{userPoolId}/.well-known/jwks.json");
// Deserialize the result
var keys = JsonConvert.DeserializeObject<JsonWebKeySet>(json).Keys;
// Cast the result to be the type expected by IssuerSigningKeyResolver
return (IEnumerable<SecurityKey>)keys;
}
};
});

3. 為什么寫這一篇文章

很多開發可能和我一樣,沒有成為一名云上工程師,或者說項目里并沒有使用 Amazon Web Service,那么對于如何集成 AWS 可能是不感興趣的。

那我為什么寫這篇文章?

1、國內對 AWS 的應用較少,AWS 相關的資料大多是英文的,其實解讀下來真的挺花時間。

2、現在新穎的技術層出不窮,我的希望是在探索 cognito 的過程中,建立一個快速理解的方法論。

這背后考驗的是專業知識以及邏輯梳理能力。我們一定是:知其所以然,才能應對多變的表象。

當然,這里我指的是對云服務如何集成傳統應用,或者說“我的應用要怎么上云”。

3、借此機會看一下云服務的設計,現在都怎么玩的。

理解云服務的應用不單止為我們多提供一種解決方案,在排查集成云集成中產生的問題,也會有所啟發。

是否能夠以小見大,找到表象的本質?

在既定的解決方案架構里面找到可以拓展的共性,能不能經驗遷移?

無論如何,希望這篇文章對你有所收益。

References

[1] Amazon Cognito Identity Provider examples using AWS SDK for .NET

[2] Authentication flow examples with .NET for Amazon Cognito

[3] Authenticating users in ASP.NET Core MVC using Amazon Cognito

[4] Securing ASP.NET Core API with JWT Token using AWS Cognito

總結

以上是生活随笔為你收集整理的.net 8 C# 集成 AWS Cognito SMS/Email 注册与登录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

歡迎分享!

轉載請說明來源于"生活随笔",并保留原作者的名字。

本文地址:.net 8 C# 集成 AWS Cognito SMS/E