学习009-07-02 Configure the OAuth2 Azure Authentication for the Web API(为 Web API 配置 OAuth2 Azure 身份验证

Configure the OAuth2 Azure Authentication for the Web API(为 Web API 配置 OAuth2 Azure 身份验证 )

The Web API supports the OAuth2 Azure Authentication. To use it, set up an Azure Active Directory (Azure AD) tenant. After you obtain a tenant, register the Web API with the Microsoft identity platform. When you configure platform settings for the Web API, select Single-page application as the Web application type and set the following Redirect URI: https://localhost:44318/swagger/oauth2-redirect.html.
Web API支持OAuth2 Azure身份验证。要使用它,请设置Azure Active Directory(Azure AD)租户。获得租户后,向Microsoft标识平台注册Web API。为Web API配置平台设置时,选择单页应用程序作为Web应用程序类型,并设置以下重定向URI:https://localhost:44318/swagger/oauth2-redirect.html。

Enable Authentication in a New Project(在新项目中启用身份验证)

Use the Solution Wizard to create a Web API project. Enable the OAuth2 Azure Authentication on the Choose Security page:
使用解决方案向导创建Web API项目。在选择安全页面上启用OAuth2 Azure身份验证:
在这里插入图片描述

The wizard generates Azure AD authentication scaffolding code.
该向导生成Azure AD身份验证脚手架代码。

Update the generated code as follows:
更新生成的代码如下:

1.Specify your Azure AD settings in the “Authentication” section of the appsettings.json file:
在appsetings. json文件的“身份验证”部分指定您的Azure AD设置:

File: MySolution.WebApi\appsettings.json (MySolution.Blazor.Server\appsettings.json)

JSON

// ...
"Authentication": {
    // ...
    "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "Domain": "abcdabcd-abcd-abcd-abcd-abcdabcdabcd", // This value is an example - replace it with your tenant domain.
        "TenantId": "organizations", // Use 'common', 'organizations', or the tenant Id obtained from the Azure portal.
        "ClientId": "11111111-1111-1111-1111-111111111111", // This value is an example - replace it with your client Id (application ID obtained from the Azure portal).
        "CallbackPath": "/ms_auth"
    }
},    
// ...

2.Configure scopes according to your Azure settings. See the following topic for details: Quickstart: Configure an application to expose a web API.
根据您的Azure设置配置范围。有关详细信息,请参阅以下主题:快速入门:配置应用程序以公开Web API。

File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)

C#

AuthorizationCode = new OpenApiOAuthFlow() {
        // ...
        Scopes = new Dictionary<string, string> {
            { "api://11111111-1111-1111-1111-111111111111/WebApi", "Read WebApi"}
        }
    }

3.In the options.Events.OnAuthenticated delegate, implement the authentication logic. The auto-generated code maps an OAuth provider user to an application user. If this code suits your requirements, comment out return.
在options.Events中,实现身份验证逻辑。自动生成的代码将OAuth提供程序用户映射到应用程序用户。如果此代码符合您的要求,请注释掉返回。

See the following topic for more information: How to: Use Active Directory and OAuth2 Authentication Providers in ASP.NET Core Blazor Applications.
有关详细信息,请参阅以下主题:如何:在ASP.NET核心Blazor应用程序中使用Active Directory和OAuth2身份验证提供程序。

File: MySolution.Blazor.Server\Startup.cs (MySolution.Blazor.Server\Startup.json)

C#

options.Events.OnAuthenticated = (externalAuthenticationContext) => {
    // When a user successfully logs in with an OAuth provider, you can get their unique user key.
    //return;
    if (externalAuthenticationContext.AuthenticatedUser == null &&
    externalAuthenticationContext.Principal.Identity.AuthenticationType != SecurityDefaults.PasswordAuthentication &&
    externalAuthenticationContext.Principal.Identity.AuthenticationType != SecurityDefaults.WindowsAuthentication && !(externalAuthenticationContext.Principal is WindowsPrincipal)) {
        const bool autoCreateUser = true;
    // ...
    }

See the following section for information on how to test the OAuth2 Azure authentication: Use the Swagger UI to Test the OAuth2 Azure Authentication.
有关如何测试OAuth2 Azure身份验证的信息,请参阅以下部分:使用Swagger UI测试OAuth2 Azure身份验证。

Enable Authentication in an Existing Project(在现有项目中启用身份验证)

Follow the steps below to add the OAuth2 Azure authentication to an existing Web API or Blazor Server project.
按照以下步骤将OAuth2 Azure身份验证添加到现有Web API或Blazor Server项目。

Step 1. Install the Required NuGet Packages(安装所需的NuGet包)

Install the following NuGet Packages:
安装以下NuGet包:

  • DevExpress.ExpressApp.Security.Xpo - to the MySolution.WebApi and MySolution.Module projects;
  • Microsoft.Identity.Web.UI - to MySolution.WebApi.

See the following topic for details: Choose Between Offline and Online DevExpress NuGet Feeds.
有关详细信息,请参阅以下主题:在离线和在线DevExpress NuGet Feeds之间进行选择。

Step 2. Modify appsettings.json(修改appset. json)

Add the AzureAd option to the Authentication section in the appsettings.json file and specify your Azure AD credentials.
将AzureAd选项添加到appset. json文件中的身份验证部分并指定您的Azure AD凭据。

File: MySolution.WebApi\appsettings.json (MySolution.Blazor.Server\appsettings.json)

JSON

// ...
"Authentication": {
    "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "Domain": "abcdabcd-abcd-abcd-abcd-abcdabcdabcd", // This value is an example, replace it with your tenant domain.
        "TenantId": "organizations", // Use 'common', 'organizations', or the tenant Id obtained from the Azure portal.
        "ClientId": "11111111-1111-1111-1111-111111111111", // This value is an example, replace it with your client Id (application ID obtained from the Azure portal).
        "CallbackPath": "/ms_auth"
    }
},    
// ...

Step 3. Modify Startup.cs(修改Startup. cs)

Add the following code to the ConfigureServices method to enable authentication:
将以下代码添加到配置服务方法以启用身份验证:

File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)

C#

// ...
using DevExpress.ExpressApp.Security;
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
using DevExpress.ExpressApp;
using System.Security.Claims;
using Microsoft.Identity.Web;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.DependencyInjection;
using System.Security.Principal;
// ...
public void AddXafAspNetCoreSecurity(Configuration,IServiceCollection services) {
    // ...
    services.AddXafAspNetCoreSecurity(Configuration, options => {
        options.RoleType = typeof(PermissionPolicyRole);
        options.UserType = typeof(MySolution.Module.BusinessObjects.ApplicationUser);
        options.UserLoginInfoType = typeof(MySolution.Module.BusinessObjects.ApplicationUserLoginInfo);
        options.Events.OnSecurityStrategyCreated = securityStrategy => ((SecurityStrategy)securityStrategy).RegisterXPOAdapterProviders();
        options.SupportNavigationPermissionsForTypes = false;
    })
    .AddAuthenticationStandard(Configuration, options => {
        options.IsSupportChangePassword = true;
    })
    .AddExternalAuthentication(options => {
        options.Events.OnAuthenticated = (externalAuthenticationContext) => {
            // When a user successfully logs in with an OAuth provider, you can get their unique user key.
            //return;
            if(externalAuthenticationContext.AuthenticatedUser == null &&
            externalAuthenticationContext.Principal.Identity.AuthenticationType != SecurityDefaults.PasswordAuthentication &&
            externalAuthenticationContext.Principal.Identity.AuthenticationType != SecurityDefaults.WindowsAuthentication && !(externalAuthenticationContext.Principal is WindowsPrincipal)) {
                const bool autoCreateUser = true;


                IObjectSpace objectSpace = externalAuthenticationContext.LogonObjectSpace;
                ClaimsPrincipal externalUser = (ClaimsPrincipal)externalAuthenticationContext.Principal;


                var userIdClaim = externalUser.FindFirst("sub") ?? externalUser.FindFirst(ClaimTypes.NameIdentifier) ?? throw new InvalidOperationException("Unknown user id");
                string providerUserId = userIdClaim.Value;


                var userLoginInfo = FindUserLoginInfo(externalUser.Identity.AuthenticationType, providerUserId);
                if(userLoginInfo != null || autoCreateUser) {
                    externalAuthenticationContext.AuthenticatedUser = userLoginInfo?.User ?? CreateApplicationUser(externalUser.Identity.Name, providerUserId);
                }


                object CreateApplicationUser(string userName, string providerUserId) {
                    if(objectSpace.FirstOrDefault<MySolution.Module.BusinessObjects.ApplicationUser>(user => user.UserName == userName) != null) {
                        throw new ArgumentException($"The username ('{userName}') was already registered within the system");
                    }
                    var user = objectSpace.CreateObject<MySolution.Module.BusinessObjects.ApplicationUser>();
                    user.UserName = userName;
                    user.SetPassword(Guid.NewGuid().ToString());
                    user.Roles.Add(objectSpace.FirstOrDefault<PermissionPolicyRole>(role => role.Name == "Default"));
                    ((ISecurityUserWithLoginInfo)user).CreateUserLoginInfo(externalUser.Identity.AuthenticationType, providerUserId);
                    objectSpace.CommitChanges();
                    return user;
                }
                ISecurityUserLoginInfo FindUserLoginInfo(string loginProviderName, string providerUserId) {
                    return objectSpace.FirstOrDefault<MySolution.Module.BusinessObjects.ApplicationUserLoginInfo>(userLoginInfo =>
                                        userLoginInfo.LoginProviderName == loginProviderName &&
                                        userLoginInfo.ProviderUserKey == providerUserId);
                }
            }
        };
    });
    const string customBearerSchemeName = "CustomBearer";
    var authentication = services.AddAuthentication(customBearerSchemeName);
    authentication
    .AddJwtBearer(customBearerSchemeName, options => {
    options.TokenValidationParameters = new TokenValidationParameters() {
    ValidIssuer = Configuration["Authentication:Jwt:Issuer"],
    ValidAudience = Configuration["Authentication:Jwt:Audience"],
    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:Jwt:IssuerSigningKey"]))
    };
    });
    authentication.AddMicrosoftIdentityWebApi(Configuration, configSectionName: "Authentication:AzureAd");


    services.AddAuthorization(options => {
        options.DefaultPolicy = new AuthorizationPolicyBuilder(
            JwtBearerDefaults.AuthenticationScheme)
                .RequireAuthenticatedUser()
                .RequireXafAuthentication()
                .Build();
    });
// ...
}

Use the AddSecurityDefinition and AddSecurityRequirement methods to add the OAuth2 Azure authentication to the Swagger UI.
使用AddSecurityDefinition和AddSecurityRequirement方法将OAuth2 Azure身份验证添加到Swagger UI。

File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)

C#

services.AddSwaggerGen(c => {
    //...
    var azureAdAuthorityUrl = $"{Configuration["Authentication:AzureAd:Instance"]}{Configuration["Authentication:AzureAd:TenantId"]}";
    c.AddSecurityDefinition("OAuth2", new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.OAuth2,
        Flows = new OpenApiOAuthFlows()
        {
            AuthorizationCode = new OpenApiOAuthFlow()
            {
                AuthorizationUrl = new Uri($"{azureAdAuthorityUrl}/oauth2/v2.0/authorize"),
                TokenUrl = new Uri($"{azureAdAuthorityUrl}/oauth2/v2.0/token"),
                Scopes = new Dictionary<string, string> {
                    // Configure scopes according to https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-expose-web-apis
                    {"api://11111111-1111-1111-1111-111111111111/WebApi", "Read WebApi"}
                }
            }
        }
    });
    c.AddSecurityRequirement(new OpenApiSecurityRequirement() {
        {
            new OpenApiSecurityScheme {
                Name = "OAuth2",
                Scheme = "OAuth2",
                Reference = new OpenApiReference {
                    Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme,
                    Id = "OAuth2"
                },
                In = ParameterLocation.Header
            },
            new string[0]
        }
    });
});

Also, modify the UseSwaggerUI method as follows:
另外,修改UseSwaggerUI方法如下:

File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)

C#

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
    // ...
    app.UseSwaggerUI(c => {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "MySolution WebApi v1");
        c.OAuthClientId(Configuration["Authentication:AzureAd:ClientId"]);
        c.OAuthUsePkce();
    });
    // ...
}    

Step 4. Add the ApplicationUser and ApplicationUserLoginInfo Business Objects(添加Application和ApplicationUserLoginInfo业务对象)

XAF requires the ApplicationUser and ApplicationUserLoginInfo business objects to store user information. Add these business objects to the MySolution.Module project as described in the following topic: Use the Security System.
XAF需要Application ationUser和ApplicationUserLoginInfo业务对象来存储用户信息。将这些业务对象添加到MySolutions. Module项目中,如以下主题中所述:使用安全系统。

Use the Swagger UI to Test the OAuth2 Azure Authentication(使用Swagger UI测试OAuth2 Azure身份验证)

1.If your solution includes a Web API project, right-click the project in the Solution Explorer and choose Debug | Start new instance to run the Web API project. A browser displays the page with the available endpoints.
如果您的解决方案包含Web API项目,请在解决方案资源管理器中右键单击该项目并选择调试|启动新实例以运行Web API项目。浏览器会显示包含可用端点的页面。

If your solution includes a startup Blazor Server project with the Web API, run the application. Add /swagger to the application address (for example, https://localhost:44318/swagger ) and press Enter to display a page with available endpoints.
如果您的解决方案包含带有Web API的启动Blazor Server项目,请运行应用程序。将 /swagger添加到应用程序地址(例如,https://localhost:44318/swagger),然后按Enter显示包含可用端点的页面。

Refer to the following link for more information on the page’s UI: Swagger UI.
有关页面UI的更多信息,请参阅以下链接:Swagger UI。
在这里插入图片描述

2.Click the Authorize button: Authorize button. In the Available authorizations window, select a scope and click the Authorize button:
单击授权按钮:授权按钮。在可用授权窗口中,选择一个范围并单击授权按钮:
在这里插入图片描述

Refer to the following topic for information on how to create Web API endpoints: Create Endpoints and Test the Web API.
有关如何创建Web API端点的信息,请参阅以下主题:创建端点和测试Web API。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汤姆•猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值