Azure active directory 添加Azure AD';要在Auth 2.0迁移后启动的策略

Azure active directory 添加Azure AD';要在Auth 2.0迁移后启动的策略,azure-active-directory,asp.net-core-2.0,azure-ad-graph-api,Azure Active Directory,Asp.net Core 2.0,Azure Ad Graph Api,我最近问了一个类似的问题,但这是关于AAD B2C的。现在我想知道如何在我的应用程序中正确地向Azure Active Directory身份验证添加策略。目前,我的Startup类如下所示: namespace Auth { public class Startup { public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuil

我最近问了一个类似的问题,但这是关于AAD B2C的。现在我想知道如何在我的应用程序中正确地向Azure Active Directory身份验证添加策略。目前,我的Startup类如下所示:

namespace Auth
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();

            Configuration = builder.Build();
        }

        private IConfigurationRoot Configuration { get; }


        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(opts =>
            {
                opts.Filters.Add(typeof(AdalTokenAcquisitionExceptionFilter));
            });

            services.AddAuthorization(o =>
            {

            });

            services.AddAuthentication(auth =>
            {
                auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                auth.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                auth.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })           

            .AddCookie()
            .AddOpenIdConnect(opts =>
            {
                Configuration.GetSection("Authentication").Bind(opts);

                opts.Events = new OpenIdConnectEvents
                {
                    OnAuthorizationCodeReceived = async ctx =>
                    {
                        HttpRequest request = ctx.HttpContext.Request;
                        string currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
                        var credential = new ClientCredential(ctx.Options.ClientId, ctx.Options.ClientSecret);

                        IDistributedCache distributedCache = ctx.HttpContext.RequestServices.GetRequiredService<IDistributedCache>();

                        string userId = ctx.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;

                        var cache = new AdalDistributedTokenCache(distributedCache, userId);

                        var authContext = new AuthenticationContext(ctx.Options.Authority, cache);

                        AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                        ctx.ProtocolMessage.Code, new Uri(currentUri), credential, ctx.Options.Resource);

                        ctx.HandleCodeRedemption(result.AccessToken, result.IdToken);
                    }
                };
            });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseStaticFiles();

            app.UseAuthentication();

            app.UseMvcWithDefaultRoute();
        }


    }
}
命名空间身份验证
{
公营创业
{
公共启动(IHostingEnvironment环境)
{
var builder=new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile(“appsettings.json”,可选:false,reloadOnChange:true)
.AddenEnvironmentVariables();
Configuration=builder.Build();
}
专用IConfigurationRoot配置{get;}
public void配置服务(IServiceCollection服务)
{
services.AddMvc(选项=>
{
添加(typeof(AdalTokenAcquisitionExceptionFilter));
});
services.AddAuthorization(o=>
{
});
services.AddAuthentication(auth=>
{
auth.DefaultAuthenticateScheme=CookieAuthenticationDefaults.AuthenticationScheme;
auth.DefaultChallengeScheme=OpenIdConnectDefaults.AuthenticationScheme;
auth.DefaultSignenscheme=CookieAuthenticationDefaults.AuthenticationScheme;
})           
.AddCookie()
.AddOpenIdConnect(选项=>
{
Configuration.GetSection(“身份验证”).Bind(opts);
opts.Events=新的OpenIdConnectEvents
{
OnAuthorizationCodeReceived=异步ctx=>
{
HttpRequest request=ctx.HttpContext.request;
字符串currentUri=UriHelper.BuildAbsolute(request.Scheme、request.Host、request.PathBase、request.Path);
var-credential=new-ClientCredential(ctx.Options.ClientId,ctx.Options.ClientSecret);
IDistributedCache distributedCache=ctx.HttpContext.RequestServices.GetRequiredService();
字符串userId=ctx.Principal.FindFirst(“http://schemas.microsoft.com/identity/claims/objectidentifier1.价值;
var cache=new AdalDistributedTokenCache(distributedCache,userId);
var authContext=新的AuthenticationContext(ctx.Options.Authority,缓存);
AuthenticationResult=等待authContext.AcquireTokenByAuthorizationCodeAsync(
ctx.ProtocolMessage.Code,新Uri(currentUri),凭证,ctx.Options.Resource);
ctx.HandleCodeRedemption(result.AccessToken、result.IdToken);
}
};
});
}
公共无效配置(IApplicationBuilder应用程序,IHostingEnvironment环境)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
}
}
后来我成功地获得了所有需要的令牌(针对Azure Graph),但现在应用程序使用某种默认的microsoft策略,我被迫使用microsoft身份验证,同时我还想验证本地租户用户。我的租户中有一个名为B2C_1_SigningPolicy的注册策略,但我不知道如何将其传递到我的应用程序的身份验证。该应用程序使用类似MVC的模型和.NETCore2.0


我最好的猜测是添加了一行类似于opts.AddPolicyUrl(“);但我找不到这样做的方法。

不要直接添加
AddOpenIdConnect
,你可以参考下面的代码,让Asp.net Core 2.0与Azure AD B2C交互:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

    services.AddAuthentication(sharedOptions =>
    {
        sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddAzureAdB2C(options => Configuration.Bind("Authentication:AzureAdB2C", options))
    .AddCookie();

    // Add framework services.
    services.AddMvc();

    // Adds a default in-memory implementation of IDistributedCache.
    services.AddDistributedMemoryCache();
    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromHours(1);
        options.CookieHttpOnly = true;
    });


}

public static class AzureAdB2CAuthenticationBuilderExtensions
{
    public static AuthenticationBuilder AddAzureAdB2C(this AuthenticationBuilder builder)
        => builder.AddAzureAdB2C(_ =>
        {
        });

    public static AuthenticationBuilder AddAzureAdB2C(this AuthenticationBuilder builder, Action<AzureAdB2COptions> configureOptions)
    {
        builder.Services.Configure(configureOptions);
        builder.Services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, OpenIdConnectOptionsSetup>();
        builder.AddOpenIdConnect();
        return builder;
    }

    public class OpenIdConnectOptionsSetup : IConfigureNamedOptions<OpenIdConnectOptions>
    {

        public OpenIdConnectOptionsSetup(IOptions<AzureAdB2COptions> b2cOptions)
        {
            AzureAdB2COptions = b2cOptions.Value;
        }

        public AzureAdB2COptions AzureAdB2COptions { get; set; }

        public void Configure(string name, OpenIdConnectOptions options)
        {
            options.ClientId = AzureAdB2COptions.ClientId;
            options.Authority = AzureAdB2COptions.Authority;
            options.UseTokenLifetime = true;
            options.TokenValidationParameters = new TokenValidationParameters() { NameClaimType = "name" };

            options.Events = new OpenIdConnectEvents()
            {
                OnRedirectToIdentityProvider = OnRedirectToIdentityProvider,
                OnRemoteFailure = OnRemoteFailure,
                OnAuthorizationCodeReceived = OnAuthorizationCodeReceived
            };
        }

        public void Configure(OpenIdConnectOptions options)
        {
            Configure(Options.DefaultName, options);
        }

        public Task OnRedirectToIdentityProvider(RedirectContext context)
        {
            var defaultPolicy = AzureAdB2COptions.DefaultPolicy;
            if (context.Properties.Items.TryGetValue(AzureAdB2COptions.PolicyAuthenticationProperty, out var policy) &&
                !policy.Equals(defaultPolicy))
            {
                context.ProtocolMessage.Scope = OpenIdConnectScope.OpenIdProfile;
                context.ProtocolMessage.ResponseType = OpenIdConnectResponseType.IdToken;
                context.ProtocolMessage.IssuerAddress = context.ProtocolMessage.IssuerAddress.ToLower().Replace(defaultPolicy.ToLower(), policy.ToLower());
                context.Properties.Items.Remove(AzureAdB2COptions.PolicyAuthenticationProperty);
            }
            else if (!string.IsNullOrEmpty(AzureAdB2COptions.ApiUrl))
            {
                context.ProtocolMessage.Scope += $" offline_access {AzureAdB2COptions.ApiScopes}";
                context.ProtocolMessage.ResponseType = OpenIdConnectResponseType.CodeIdToken;
            }
            return Task.FromResult(0);
        }

        public Task OnRemoteFailure(RemoteFailureContext context)
        {
            context.HandleResponse();
            // Handle the error code that Azure AD B2C throws when trying to reset a password from the login page 
            // because password reset is not supported by a "sign-up or sign-in policy"
            if (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("AADB2C90118"))
            {
                // If the user clicked the reset password link, redirect to the reset password route
                context.Response.Redirect("/Session/ResetPassword");
            }
            else if (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("access_denied"))
            {
                context.Response.Redirect("/");
            }
            else
            {
                context.Response.Redirect("/Home/Error?message=" + context.Failure.Message);
            }
            return Task.FromResult(0);
        }

        public async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
        {
            // Use MSAL to swap the code for an access token
            // Extract the code from the response notification
            var code = context.ProtocolMessage.Code;

            string signedInUserID = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value;
            TokenCache userTokenCache = new MSALSessionCache(signedInUserID, context.HttpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);
            try
            {
                AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, AzureAdB2COptions.ApiScopes.Split(' '));


                context.HandleCodeRedemption(result.AccessToken, result.IdToken);
            }
            catch (Exception ex)
            {
                //TODO: Handle
                throw;
            }
        }
    }
}
public void配置服务(IServiceCollection服务)
{
services.AddSingleton();
services.AddAuthentication(sharedOptions=>
{
sharedOptions.DefaultScheme=CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme=OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAdB2C(选项=>Configuration.Bind(“身份验证:AzureAdB2C”,选项))
.AddCookie();
//添加框架服务。
services.AddMvc();
//添加IDistributedCache的默认内存内实现。
AddDistributedMemoryCache();
services.AddSession(选项=>
{
options.IdleTimeout=TimeSpan.FromHours(1);
options.CookieHttpOnly=true;
});
}
公共静态类AzureAdB2CAuthenticationBuilderExtensions
{
公共静态身份验证生成器AddAzureAdB2C(此身份验证生成器)
=>builder.AddAzureAdB2C(=>
{
});

public static AuthenticationBuilder AddAzureAdB2C(此AuthenticationBuilder,Action.

不是直接添加
AddOpenIdConnect
,您可以参考下面的代码,让Asp.net Core 2.0与Azure AD B2C交互:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

    services.AddAuthentication(sharedOptions =>
    {
        sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddAzureAdB2C(options => Configuration.Bind("Authentication:AzureAdB2C", options))
    .AddCookie();

    // Add framework services.
    services.AddMvc();

    // Adds a default in-memory implementation of IDistributedCache.
    services.AddDistributedMemoryCache();
    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromHours(1);
        options.CookieHttpOnly = true;
    });


}

public static class AzureAdB2CAuthenticationBuilderExtensions
{
    public static AuthenticationBuilder AddAzureAdB2C(this AuthenticationBuilder builder)
        => builder.AddAzureAdB2C(_ =>
        {
        });

    public static AuthenticationBuilder AddAzureAdB2C(this AuthenticationBuilder builder, Action<AzureAdB2COptions> configureOptions)
    {
        builder.Services.Configure(configureOptions);
        builder.Services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, OpenIdConnectOptionsSetup>();
        builder.AddOpenIdConnect();
        return builder;
    }

    public class OpenIdConnectOptionsSetup : IConfigureNamedOptions<OpenIdConnectOptions>
    {

        public OpenIdConnectOptionsSetup(IOptions<AzureAdB2COptions> b2cOptions)
        {
            AzureAdB2COptions = b2cOptions.Value;
        }

        public AzureAdB2COptions AzureAdB2COptions { get; set; }

        public void Configure(string name, OpenIdConnectOptions options)
        {
            options.ClientId = AzureAdB2COptions.ClientId;
            options.Authority = AzureAdB2COptions.Authority;
            options.UseTokenLifetime = true;
            options.TokenValidationParameters = new TokenValidationParameters() { NameClaimType = "name" };

            options.Events = new OpenIdConnectEvents()
            {
                OnRedirectToIdentityProvider = OnRedirectToIdentityProvider,
                OnRemoteFailure = OnRemoteFailure,
                OnAuthorizationCodeReceived = OnAuthorizationCodeReceived
            };
        }

        public void Configure(OpenIdConnectOptions options)
        {
            Configure(Options.DefaultName, options);
        }

        public Task OnRedirectToIdentityProvider(RedirectContext context)
        {
            var defaultPolicy = AzureAdB2COptions.DefaultPolicy;
            if (context.Properties.Items.TryGetValue(AzureAdB2COptions.PolicyAuthenticationProperty, out var policy) &&
                !policy.Equals(defaultPolicy))
            {
                context.ProtocolMessage.Scope = OpenIdConnectScope.OpenIdProfile;
                context.ProtocolMessage.ResponseType = OpenIdConnectResponseType.IdToken;
                context.ProtocolMessage.IssuerAddress = context.ProtocolMessage.IssuerAddress.ToLower().Replace(defaultPolicy.ToLower(), policy.ToLower());
                context.Properties.Items.Remove(AzureAdB2COptions.PolicyAuthenticationProperty);
            }
            else if (!string.IsNullOrEmpty(AzureAdB2COptions.ApiUrl))
            {
                context.ProtocolMessage.Scope += $" offline_access {AzureAdB2COptions.ApiScopes}";
                context.ProtocolMessage.ResponseType = OpenIdConnectResponseType.CodeIdToken;
            }
            return Task.FromResult(0);
        }

        public Task OnRemoteFailure(RemoteFailureContext context)
        {
            context.HandleResponse();
            // Handle the error code that Azure AD B2C throws when trying to reset a password from the login page 
            // because password reset is not supported by a "sign-up or sign-in policy"
            if (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("AADB2C90118"))
            {
                // If the user clicked the reset password link, redirect to the reset password route
                context.Response.Redirect("/Session/ResetPassword");
            }
            else if (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("access_denied"))
            {
                context.Response.Redirect("/");
            }
            else
            {
                context.Response.Redirect("/Home/Error?message=" + context.Failure.Message);
            }
            return Task.FromResult(0);
        }

        public async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
        {
            // Use MSAL to swap the code for an access token
            // Extract the code from the response notification
            var code = context.ProtocolMessage.Code;

            string signedInUserID = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value;
            TokenCache userTokenCache = new MSALSessionCache(signedInUserID, context.HttpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);
            try
            {
                AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, AzureAdB2COptions.ApiScopes.Split(' '));


                context.HandleCodeRedemption(result.AccessToken, result.IdToken);
            }
            catch (Exception ex)
            {
                //TODO: Handle
                throw;
            }
        }
    }
}
public void配置服务(IServiceCollection服务)
{
services.AddSingleton();
services.AddAuthentication(sharedOptions=>
{
sharedOptions.DefaultScheme=CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme=OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAdB2C(选项=>Configuration.Bind(“身份验证:AzureAdB2C”,选项))
.AddCookie();
//添加框架服务。
services.AddMvc();
//添加IDistributedCache的默认内存内实现。
AddDistributedMemoryCache();
services.AddSession(选项=>
{
options.IdleTimeout=TimeSpan.FromHours(1);
options.CookieHttpOnly=true;
});
}
公共静态类AzureAdB2CAuthenticationBuilderExtensions
{
公共静态身份验证生成器AddAzureAdB2C(此身份验证生成器