冠军

导航

06 IdentityServer4 中支持外部标识提供器

06. IdentityServer4 External Providers .NET Core 3.1

January 24, 2020| deblokt| in category Tutorials .Net Core 3.17 comments

You can find the project [here](https://github.com/Deblokt/IdentityServer4Demos.NETCore31/tree/master/06. IdentityServer4 External Providers).

标准协议

All Identity Providers are supported using standard protocols like OpenID Connect, OAuth2, SAML2 and WS-Federation. This could be Okta, it could be Auth0, could be proprietary IdP of a client, could be another IdentityServer4. Take a look at the list of out-of-the-box extensions for “AuthenticationBuilder” for big providers like Azure AD, Microsoft Account, Google, Facebook, Twitter, etc here https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.authenticationbuilder?view=aspnetcore-2.2

所有的标识提供者都支持使用标准协议,例如 OpenID Connect,OAuth2,SAML2 以及 WS-Federation。它们可以是 Okta,也可以是 Auth0,还可以是专属于某个客户端的 IdP,甚至可以是另外一个 IdentityServer4。检查一下该开箱即用的 AuthenticationBuilder 列表,对于大型的提供者,例如 Azure AD,Microsoft Account,Goolge,Facebook,Twitter 等等。列表地址:https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.authenticationbuilder?view=aspnetcore-2.2

Setting up the usual OpenID Connect OIDC middleware is enough for most of the providers to get you going. Almost all providers nowadays provide OIDC, some as a second option alongside SAML2 and/or WS-Fed.

对于使用而言,设置通用的 OpenID Connect OIDC 中间件就足够了,几乎所有的提供者当前支持 OIDC,有些还同时支持 SAML2 和/或者 WS-Fed。

As IdentityServer4 is OIDC Identity Provider you can actually set up one IdentityServer4 instance to be an external provider for another IdentityServer4 instance using OIDC middleware. As long as there is a single root node, all Identity Servers connected this way can achieve SSO.

由于 IdentityServer4 就是一个 OIDC 的标识提供者,所以,你确实可以使用 OIDC 中间件,将一个 IdentityServerr4 设置为一个另一个 IdentityServer4 的外部提供者。通过将它作为单一的根节点,所有通过该方式连接到它的 Identity 服务器都可以实现 SSO。

Azure AD Example

I will continue from my last tutorial. Open the “Quickstart” solution in Visual Studio.

Open the “Startup.cs” in project root and navigate right above the “AddIdentityServer” service registration. Add the authentication middleware for AzureAD like so:

我们可以继续上一教程,在 Visual Studio 中打开 Quickstart 解决方法。

打开项目中的 Startup.cs 文件,找到 AddIdentityServer 服务注册的上边,针对 AzureAD 添加验证中间件的注册,如下所示:

services.AddAuthentication()	
  .AddOpenIdConnect(
  	"azuread", 
  	"Azure AD", 
  	options => Configuration.Bind("AzureAd", options));

services.Configure<OpenIdConnectOptions>(
  "azuread", 
  options => {
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Events = new OpenIdConnectEvents() {
      OnRedirectToIdentityProviderForSignOut = context => {
        context.HandleResponse();
        context.Response.Redirect("/Account/Logout");
        return Task.FromResult(0);
      }
    };
  });

Now open the “appsettings.json” in project root and modify it to add the Azure AD configuration we are using and binding in “Startup” like so:

然后,打开项目中的 appsettings.json文件,修改并添加我们在 Startup 中使用的 Azure AD 配置,如下所示:

{ 
  "ConnectionStrings": {  
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=IdentityServerQuickstart.NetCore3.1;Trusted_Connection=True;MultipleActiveResultSets=true" }, 
  "AzureAd": {  
    // Authority/MetadataAddress format (https://{instance}/{tenantId}/...  
    "Authority": "https://login.microsoftonline.com/0366c849-xxxx-xxxx-xxxx-adcc0ccf2170/oauth2/v2.0/",  
    "MetadataAddress": "https://login.microsoftonline.com/0366c849-xxxx-xxxx-xxxx-adcc0ccf2170/.well-known/openid-configuration",  
    "ClientId": "7adeb3b0-xxxx-xxxx-xxxx-a6bc5aa756da",  
    "CallbackPath": "/signin-oidc" 
  }
}

注意 您必须通过 Azure portal 获取你的 TenantIdClientId (也被称为 ApplicationId)。这里是如何在 Azure AD 中创建应用的官方文档: https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app

提示 对于应用注册,你将需要 ReturnUrl。对于本演示,该 return URL 是 http://localhost:5000/signin-oidc

Okta Example

Open the “Startup.cs” in project root and navigate right below the “AddAzureAD” and add:

打开项目根目录中的 Startup.cs ,导航到 AddAuzreAD 的下边,并添加:

.AddOpenIdConnect("okta", "Okta", options => Configuration.Bind("Okta", options));

Also add the OpenIdConnectOptions service configuration like so:

还需要添加 `OpenIdConnectOptions 服务的配置,如下所示:

services.Configure<OpenIdConnectOptions>(
  "okta", options => {
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Events = new OpenIdConnectEvents() {
      OnRedirectToIdentityProviderForSignOut 
        = context => {
        context.HandleResponse();                                                                      
        context.Response.Redirect("/Account/Logout");
        return Task.FromResult(0);
      }
    };
  });

So full code including Azure Ad and Okta looks like so:

所以,完整地包含对 Azure Ad 和 Okta 支持的代码如下所示:

services.AddAuthentication()
  .AddOpenIdConnect(
  "azuread", 
  "Azure AD",
  options => Configuration.Bind("AzureAd", options)
)
.AddOpenIdConnect(
  "okta", 
  "Okta", 
  options => Configuration.Bind("Okta", options)
);

services.Configure<OpenIdConnectOptions>(
  "azuread", 
  options => {
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Events = new OpenIdConnectEvents() {
      OnRedirectToIdentityProviderForSignOut = 
        context => {
        	context.HandleResponse();
          context.Response.Redirect("/Account/Logout");
          return Task.FromResult(0);
      }
    };
  });

services.Configure<OpenIdConnectOptions>(
  "okta", 
  options => {
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Events = new OpenIdConnectEvents() {
      OnRedirectToIdentityProviderForSignOut = context => {
        context.HandleResponse();
        context.Response.Redirect("/Account/Logout");
        return Task.FromResult(0);
      }
    };
  });

Now open the “appsettings.json” in project root and modify it to add the Okta configuration we are using and binding in “Startup” like so:

现在,打开项目根目录中的 appsettings.json 文件,修改并添加我们在 Startup 中使用的 Okta 的配置信息。

"Okta": {	
  "Authority": "https://dev-xxxxxx-admin.oktapreview.com",	
  "ClientId": "0oakhxxxxxxxxxxaX0h7",	
  "CallbackPath": "/signin-oidc-okta"
}

注意 您必须从 Okta 获取你的 AuthorityClientId 。这是如何创建 Okta 应用的官方文档: https://developer.okta.com/docs/guides/add-an-external-idp/microsoft/register-app-in-okta/

提示 你需要为应用注册提供 ReturnUrl,对于本演示,该 return URL 是: http://localhost:5000/signin-oidc-okta

Modify the user auto-provisioning process

调整用户的自动配置处理

Because we added the “IsEnable” custom property in the previous tutorial the auto-provisioned user will by default have value “false” (disabled user) and the external provider login will fail. We need to slightly modify the automatic user creation process for external providers to set the “IsEnabled” flag to “true”. Navigate to “Quickstart/Account/ExternalController.cs” and open it.

Find the “AutoProvisionUserAsync” method and modify the line that instantiates new user. We need to modify it to set the “IsEnabled” user property to “true” like so:

由于我们在上一教程中,为自动配置用户添加了一个自定义的 IsEnable 属性,默认值为 false (禁用用户),所以外部提供者的登录会失败。我们需要略微调整对于外部提供者的自动用户创建处理,将该 IsEnabled 标志设置为 true。找到 “Quickstart/Account/ExternalController.cs” 然后打开它。

var user = new ApplicationUser{	
  UserName = Guid.NewGuid().ToString(),	
  Email = email,	
  IsEnabled = true
};

Now run the IdentityServer4 and try to sign in with Azure AD or Okta. If the local user exists with the same username or email as the external user (from Azure AD or Okta in our example) the matching process will link the external user with local user and the new local user will not be created. For other scenarios (no match) the auto-provisioning process will create a new local user and link it with the external user. I logged in using Okta and the new local user was auto-provisioned. Notice that my name was automatically populated from the claims provided by Okta. These are the claims of the external user now set to the local user.

现在,运行 IdentityServer4 ,然后尝试通过 Azure AD 或者 okta 登录。如果对于外部用户 (来自 Azure Ad 或者 Okta) 存在有相同的用户名或者电子邮件的本地用户,匹配过程将链接外部用户到本地用户,且不会创建新的本地用户。对于其它场景 (不匹配的用户),自动匹配过程将创建一个新的本地用户并链接到外部用户。我使用 Okta 用户登录,自动匹配过程将会自动处理。注意,我的名字将会自动从来自 Okta 提供的声明中填充。来自外部用户的声明现在设置到本地用户。

Capture

很简单

Now that was super easy, wasn’t it? Adding any standard Identity Provider shouldn’t pose any challenge as the method is pretty much the same. In my next tutorial I will start tackling one of the important features which are Multi-Factor Authentication MFA aka 2FA if there are two factors. Stay fresh!

You can find the project [here](https://github.com/Deblokt/IdentityServer4Demos.NETCore31/tree/master/06. IdentityServer4 External Providers).

超级简单,是不是?添加任何标准的标识提供者的难度不会超过这些方法。在下一教程中,我将开始另一个重要的特性:多因子验证 MFA,如果只有两个因子,也被称为 2FA。

Support

For direct assistance schedule a technical meeting with Ivan to talk about your requirements. For a general overview of our services and a live demo schedule a meeting with Maja.

https://deblokt.com/2020/01/24/06-identityserver4-external-providers-net-core-3-1/

posted on 2022-03-14 16:30  冠军  阅读(130)  评论(0编辑  收藏  举报