【问题标题】:Integrating ASP.NET code to Active Directory or LDAP after deploying on Bluemix在 Bluemix 上部署之后将 ASP.NET 代码集成到 Active Directory 或 LDAP
【发布时间】:2017-02-14 20:58:54
【问题描述】:

我正在做一个 ASP.Net 项目,完成后需要部署在 PaaS 上,需要 BlueMix(这不是我的选择, 这是一个命令)。
另外我需要使用:

Active Directory 或 LDAP 到用户身份验证和授权,与 ASP.Net 项目集成。

这里的问题是:
1. 我发现只使用 Java 或 Node.js 集成到 Active Directory 或 SSO 服务,但在我的我正在使用 ASP.Net
2. 我想要一个解决方案,说明如何在 PaaS 之上完成 Active Directory 和 ASP.Net 应用程序之间的集成。
p>

【问题讨论】:

    标签: asp.net active-directory single-sign-on ibm-cloud paas


    【解决方案1】:

    根据您使用的 ADFS 版本,您应该能够使用 OAuth 或 OIDC 中间件从 ASP.NET Core 应用程序进行连接(假设您使用的是 ASP.NET Core,因为您使用的是 Bluemix )。如果您至少使用 ADFS 3.0 (Windows Server 2012+),则可以使用 ASP.NET Core 的通用 OAuth 中间件进行连接。

    首先,创建一个配置文件来存储您的 ADFS 服务器设置,或者修改现有的配置文件(例如 appsettings.json)。

    示例“adfs-settings.json”文件:

    {
      "ADFS": {
        "ClientId": "Your ClientId as set on ADFS server",
        "ResourceUrl": "url of this application (ex: http://mywebapp.mybluemix.net)",
        "ServerUrl": "url of ADFS (ex: https://dc.your.domain)"
      }
    }
    

    如果您为 ADFS 配置创建了新文件,例如“adfs-settings.json”,请将其添加到 Startup.cs 文件构造函数中的 Configuration 对象。

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("adfs-settings.json");
        Configuration = builder.Build();
    }
    

    在您的 Startup.cs 的 Configure 方法中创建一个 OAuthOptions 对象:

    var options = new OAuthOptions();
    options.AutomaticChallenge = true;
    options.AuthenticationScheme = "ADFS";
    

    指定您在 ADFS 服务器上配置此应用程序时创建的 ClientId,方法是从您的 Configuration 对象中读取它。通用 OAuth 中间件还要求您在此处提供 ClientSecret,即使 ADFS 3.0 实际上并未使用该值。

    options.ClientId = Configuration["ADFS:ClientId"];
    options.ClientSecret = "ADFS 3.0 does not support confidential client, but OAuth middleware requires it";
    

    在您的应用程序中设置 ADFS 服务器将重定向到的回调 url。

    options.CallbackPath = new PathString("/signin-adfs");
    

    现在配置OAuthEventsOnRedirectToAuthorizationEndpoint 定义当应用程序确定用户需要被授权时传递给 ADFS 授权端点的参数。这将至少需要一个resource 参数,该参数指向您的应用程序的url。当 ADFS 服务器完成对客户端的授权并向您的应用程序返回包含声明数据的 JWT 令牌时,将触发 OnCreatingTicket。在此方法中,您需要处理向HttpContext 对象添加角色和声明。

    options.Events = new OAuthEvents {
        OnRedirectToAuthorizationEndpoint = context =>
        {
            var parameter = new Dictionary<string, string>
                {
                    ["resource"] = Configuration["ADFS:ResourceUrl"]
                };
            var query = QueryHelpers.AddQueryString(context.RedirectUri, parameter);
            context.Response.Redirect(query);
            return Task.CompletedTask;
        },
        OnCreatingTicket = context => {
            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
            JwtSecurityToken validatedToken = tokenHandler.ReadJwtToken(context.AccessToken);
            IEnumerable<Claim> a = validatedToken.Claims;
    
            foreach (var claim in a)
            {
                // role claim needs to be mapped to http://schemas.microsoft.com/ws/2008/06/identity/claims/role
                // for IsInRole() to work properly
                if (claim.Type == "role")
                {
                    context.Identity.AddClaim(new Claim(ClaimTypes.Role, claim.Value));
                }
                else if (claim.Type == "unique_name")
                {
                    // map name to Identity.Name
                    context.Identity.AddClaim(new Claim(context.Identity.NameClaimType, claim.Value));
                }
                else
                {
                    // this is optional, if you want any other specific claims from Active Directory
                    // this will also include some information about the jwt token such as the issue
                    // and expire times
                    context.Identity.AddClaim(new Claim(claim.Type, claim.Value));
                }
            }
    
            return Task.CompletedTask;
            }
        };
    

    接下来,将ClaimsIssuer 设置为ADFS url,将SignInScheme 设置为CookieAuthenticationDefaults.AuthenticationScheme,并将AuthorizationEndpointTokenEndpoint 配置为ADFS 服务器上的正确端点。

        options.ClaimsIssuer = Configuration["ADFS:ServerUrl"];
        options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.AuthorizationEndpoint = Configuration["ADFS:ServerUrl"] + "/adfs/oauth2/authorize/";
        options.TokenEndpoint = Configuration["ADFS:ServerUrl"] + "/adfs/oauth2/token/";
    

    最后,使用您刚刚创建的选项添加 OAuth 中间件:

        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseOAuthAuthentication(options);
    

    现在您应该能够将[Authorize] 属性应用于任何需要ADFS 授权的控制器或操作。如需完整的示例应用程序,请参阅this GitHub repo

    【讨论】:

    • 非常感谢,这对通用 ADFSv3 / OAuth 非常有帮助。缺少的一件事是为什么 signInManager.GetExternalLoginInfoAsync 返回 null。
    • 记录在案:在我的情况下,signInManager.GetExternalLoginInfoAsync 因为缺少声明而返回。 ADFSv3 声明类型似乎不遵循标准声明类型(因此我们必须进行转换),但即使这样也会混淆。所以,而不是以下:context.Identity.AddClaim(new Claim(context.Identity.NameClaimType, claim.Value)); 我不得不使用:context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, claim.Value));
    猜你喜欢
    • 1970-01-01
    • 2020-02-24
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    相关资源
    最近更新 更多