2016-08-25 40 views
2

これに関連する質問を探しましたが、何も見つかりませんでした。Azure AD B2C with ASP.NET Core - プロファイルを編集できません

私は認証にAzure AD B2Cを使用するASP.NET Core 1.0アプリケーションを持っています。署名と登録だけでなく、署名作業もうまくいきます。問題は、ユーザーのプロフィールを編集しようとするときに発生します。

は はここ

namespace AspNetCoreBtoC 
{ 
    public class Startup 
    { 
     private IConfigurationRoot Configuration { get; } 

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

     // This method gets called by the runtime. Use this method to add services to the container. 
     // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940 
     public void ConfigureServices(IServiceCollection services) 
     { 
      services.AddSingleton<IConfiguration>(Configuration); 
      services.AddMvc(); 
      services.AddAuthentication(
       opts => opts.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme); 
     } 

     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
     { 
      loggerFactory.AddConsole(); 

      if (env.IsDevelopment()) 
      { 
       loggerFactory.AddDebug(LogLevel.Debug); 
       app.UseDeveloperExceptionPage(); 
      } 

      app.UseStaticFiles(); 

      app.UseCookieAuthentication(new CookieAuthenticationOptions 
      { 
       AutomaticChallenge = false 
      }); 

      string signUpPolicyId = Configuration["AzureAd:SignUpPolicyId"]; 
      string signUpCallbackPath = Configuration["AzureAd:SignUpCallbackPath"]; 
      app.UseOpenIdConnectAuthentication(CreateOidConnectOptionsForPolicy(signUpPolicyId, false, signUpCallbackPath)); 

      string userProfilePolicyId = Configuration["AzureAd:UserProfilePolicyId"]; 
      string profileCallbackPath = Configuration["AzureAd:ProfileCallbackPath"]; 
      app.UseOpenIdConnectAuthentication(CreateOidConnectOptionsForPolicy(userProfilePolicyId, false, profileCallbackPath)); 

      string signInPolicyId = Configuration["AzureAd:SignInPolicyId"]; 
      string signInCallbackPath = Configuration["AzureAd:SignInCallbackPath"]; 
      app.UseOpenIdConnectAuthentication(CreateOidConnectOptionsForPolicy(signInPolicyId, true, signInCallbackPath)); 

      app.UseMvc(routes => 
      { 
       routes.MapRoute(
        name: "Default", 
        template: "{controller=Home}/{action=Index}/{id?}"); 
      }); 
     } 

     private OpenIdConnectOptions CreateOidConnectOptionsForPolicy(string policyId, bool autoChallenge, string callbackPath) 
     { 
      string aadInstance = Configuration["AzureAd:AadInstance"]; 
      string tenant = Configuration["AzureAd:Tenant"]; 
      string clientId = Configuration["AzureAd:ClientId"]; 
      string redirectUri = Configuration["AzureAd:RedirectUri"]; 

      var opts = new OpenIdConnectOptions 
      { 
       AuthenticationScheme = policyId, 
       MetadataAddress = string.Format(aadInstance, tenant, policyId), 
       ClientId = clientId, 
       PostLogoutRedirectUri = redirectUri, 
       ResponseType = "id_token", 
       TokenValidationParameters = new TokenValidationParameters 
       { 
        NameClaimType = "name" 
       }, 
       CallbackPath = callbackPath, 
       AutomaticChallenge = autoChallenge 
      }; 

      opts.Scope.Add("openid"); 

      return opts; 
     } 
    } 
} 
私AccountControllerは、私はミドルウェアへの挑戦を発行するところから、次のとおりです:ここに私のStartup.csのように見えるものである

namespace AspNetCoreBtoC.Controllers 
{ 
    public class AccountController : Controller 
    { 
     private readonly IConfiguration config; 

     public AccountController(IConfiguration config) 
     { 
      this.config = config; 
     } 

     public IActionResult SignIn() 
     { 
      return Challenge(new AuthenticationProperties 
      { 
       RedirectUri = "/" 
      }, 
      config["AzureAd:SignInPolicyId"]); 
     } 

     public IActionResult SignUp() 
     { 
      return Challenge(new AuthenticationProperties 
      { 
       RedirectUri = "/" 
      }, 
      config["AzureAd:SignUpPolicyId"]); 
     } 

     public IActionResult EditProfile() 
     { 
      return Challenge(new AuthenticationProperties 
      { 
       RedirectUri = "/" 
      }, 
      config["AzureAd:UserProfilePolicyId"]); 
     } 

     public IActionResult SignOut() 
     { 
      string returnUrl = Url.Action(
       action: nameof(SignedOut), 
       controller: "Account", 
       values: null, 
       protocol: Request.Scheme); 
      return SignOut(new AuthenticationProperties 
      { 
       RedirectUri = returnUrl 
      }, 
      config["AzureAd:UserProfilePolicyId"], 
      config["AzureAd:SignUpPolicyId"], 
      config["AzureAd:SignInPolicyId"], 
      CookieAuthenticationDefaults.AuthenticationScheme); 
     } 

     public IActionResult SignedOut() 
     { 
      return View(); 
     } 
    } 
} 

私はOWINの例から、それに適応しようとしました。私が持っている問題は、プロファイルを編集するために、その責任を負うOpenIdConnectミドルウェアに挑戦しなければならないということです。問題は、ユーザーが認証されていることを認識しているミドルウェア(Cookie)の既定のサインを呼び出すため、アクションは何か不正なものであったに違いありませんし、/ Account/AccessDeniedにリダイレクトしようとしますAzure ADに行くのではなく、プロファイルを編集する必要はありません)。

誰もがASP.NET Coreでユーザープロファイルの編集を正常に実装しましたか?

答えて

1

さて、私はついにそれを解決しました。私は解決策を含むセットアップに関するブログ記事を書いた:https://joonasw.net/view/azure-ad-b2c-with-aspnet-core。問題はChallengeBehaviorで、デフォルト値のAutomaticではなくUnauthorizedに設定する必要があります。現時点では、フレームワークのChallengeResultでそれを定義することはできませんでしたので、私は自分自身を作った:

名のため申し訳ありません
public class MyChallengeResult : IActionResult 
{ 
    private readonly AuthenticationProperties authenticationProperties; 
    private readonly string[] authenticationSchemes; 
    private readonly ChallengeBehavior challengeBehavior; 

    public MyChallengeResult(
     AuthenticationProperties authenticationProperties, 
     ChallengeBehavior challengeBehavior, 
     string[] authenticationSchemes) 
    { 
     this.authenticationProperties = authenticationProperties; 
     this.challengeBehavior = challengeBehavior; 
     this.authenticationSchemes = authenticationSchemes; 
    } 

    public async Task ExecuteResultAsync(ActionContext context) 
    { 
     AuthenticationManager authenticationManager = 
      context.HttpContext.Authentication; 

     foreach (string scheme in authenticationSchemes) 
     { 
      await authenticationManager.ChallengeAsync(
       scheme, 
       authenticationProperties, 
       challengeBehavior); 
     } 
    } 
} 

...しかし、これはコントローラのアクションから、と指定することによって返すことができますChallengeBehavior.Unauthorized、私はそれが必要なようにすべての作業を得た。

関連する問題