1

我最近问了一个类似的问题,但它与AAD B2C有关。现在我想知道如何在我的应用中正确添加策略到Azure Active Directory身份验证。目前,我的启动类看起来是这样的:在Auth 2.0迁移后将Azure AD的策略添加到启动

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(); 
     } 


    } 
} 

我设法获得所有需要的代币(为天青图)成功地以后,但现在的应用程序使用某种默认的Microsoft政策,我被迫使用微软认证,而我也想认证本地租户用户。我在我的租户中有一个名为B2C_1_SignInPolicy的注册策略,但我无法弄清楚如何将它传递给我的应用程序的身份验证。 App正在使用类似MVC的模型和.Net Core 2.0。

我最好的猜测是添加类似于opts.AddPolicyUrl(” https://...policyName)线;但我无法找到一个方法来做到这一点

+0

你能澄清你想达到什么具体的,?当你说当地的租客用户是否意味着要从特定的Azure AD租户或本地帐户存储中登录用户? –

+0

来自Azure AD租户的本地帐户 - 通过[从此处]创建用户(本地帐户)方案创建的帐户(https://msdn.microsoft.com/zh-cn/library/azure/ad/graph/api/users -operations) –

回答

0

而是直接添加AddOpenIdConnect的,你可以参考下面的代码对于Asp.net 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; 
      } 
     } 
    } 
} 

,而整体的代码示例,您可以参阅core2.0 branch of active-directory-b2c-dotnetcore-webapp

+0

这不适用于Auth 2.0。而且,我通过使用这个令牌无法让我连接到Azure Graph。 –

+1

此代码示例演示了通过OpenId连接协议通过Asp.net核心2.0交互Azure AD B2C。正如我们在预览线程中所讨论的,要为Azure AD B2C调用Azure AD图,您需要与客户端凭证流进行交互。目前,Azure AD B2C应用不支持获取访问令牌来委派用户(请参阅[Azure AD B2C:使用图形API](https://docs.microsoft.com/en-us/azure/)有源目录-B2C /有源目录-B2C-devquickstarts-图表-的dotnet))。 –

相关问题