C# 根据Azure AD B2C使用OWIN/OIDC验证自定义Umbraco控制器

C# 根据Azure AD B2C使用OWIN/OIDC验证自定义Umbraco控制器,c#,authentication,owin,umbraco,azure-ad-b2c,C#,Authentication,Owin,Umbraco,Azure Ad B2c,我被卡住了 我有一个自定义的Umbraco控制器,它继承自RenderMvcController,当点击Index()操作方法时,将返回一个文件。这是可行的,但我想做的是通过使用authorized属性装饰操作,然后要求用户进行身份验证来保护它 namespace MyNamespace.Controllers { public class MyModelController : RenderMvcController { [Authorize]

我被卡住了

我有一个自定义的Umbraco控制器,它继承自
RenderMvcController
,当点击
Index()
操作方法时,将返回一个文件。这是可行的,但我想做的是通过使用
authorized属性
装饰操作,然后要求用户进行身份验证来保护它

namespace MyNamespace.Controllers
{
    public class MyModelController : RenderMvcController
    {
        [Authorize]
        public ActionResult Index(RenderModel model)
        {
            // ...
        }
    }
}
通过使用OWIN和OpenId Connect对Azure AD B2C应用程序进行身份验证。这也可以工作并经过测试,但在非Umbraco环境中

我已经阅读了许多与该主题相关的线程和代码,但我正在努力将其集成到Umbraco中。我有一个自定义启动类,它继承自
UmbracoDefaultOwinStartup
。我向我的
AuthController
注册自定义路由,并通过
IAppBuilder.UseOpenIdConnectAuthentication()
配置OIDC

但是我需要Umbraco胶水,在理解如何配置cookies时遇到了问题。我已检查是否调用了startup
Configuration()
方法

namespace MyNamespace
{
    public class CustomOwinStartup : UmbracoDefaultOwinStartup
    {
        public override void Configuration(IAppBuilder app)
        {
            base.Configuration(app);
            ConfigureAuth(app);

            RouteTable.Routes.MapRoute(
                "CustomAuth",
                "CustomAuth/{action}",
                new { controller = "Auth" }
            );
        }

        private void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/CustomAuth/SignUpSignIn") // TODO: What should I put here?
            });
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
            app.UseOpenIdConnectAuthentication(
                // Passing options that are tested and working
            );
        }
    }
}
然后我有了我的auth控制器,目前它非常简单。我不需要与Umbraco用户同步身份验证信息

namespace MyNamespace.Controllers
{
    public partial class CustomAuthController : Controller
    {
        public CustomAuthController() : base()
        {
        }

        public void SignUpSignIn()
        {
            if (!Request.IsAuthenticated)
            {
                HttpContext.GetOwinContext().Authentication.Challenge();
                return;
            }

            Response.Redirect("/"); // TODO: Maybe this should redirect me back to original route MyModel/Index in some way
        }
    }
}
如果我运行此命令并尝试通过我的自定义Umbraco控制器执行此操作,则会出现以下错误:

找不到页面

没有任何umbraco文档与url
”/login.aspx?ReturnUrl=MYORIGINALROUTEHTTPENCODED“
匹配。 此页面可以替换为自定义404。检查文档中的“自定义404”

我猜这是因为
Web.config
中的
设置造成的,但是如果我删除此设置或将属性
mode
设置为
“None”
,这会不会影响后台登录


非常感谢任何人能帮我指出正确的方向

不幸的是,我没有足够的时间设置相同的环境并检查所有内容,但我会给出一些想法并发布几个链接

要覆盖后台登录逻辑,您不需要创建自定义身份验证控制器或覆盖登录页面。由于Umbraco使用ASP.NET标识进行授权,您需要在OWIN启动时正确配置它,它将根据您的需要工作。然后,您将使用Umbraco授权工具检查用户是否可以点击MyModelController的索引操作

如果需要实施自定义用户名/密码检查,请使用Umbraco扩展名。请参阅更多:

您还可以将Umbraco扩展名用于Active Directory。请参阅更多:

关于属性。“找不到”错误,因为Authorize对OWIN和Umbraco一无所知。它将重定向到默认路径login.aspx页面,并且该路径在项目中不存在。您可以设置

无论如何,请阅读更多Umbraco教程和文档。我希望你能找到答案。请随意多问

已更新

尝试使用您自己版本的AuthorizeAttribute。有一个例子:

您需要重写AuthorizeCore方法并从HandleUnauthorizedRequest返回所需的结果。因此,您可以返回重定向结果到您的登录页面或任何您需要的

然后,您可以根据需要应用它

    [CustomAuthorize]
    public ActionResult Index(RenderModel model)
    {
        // ...
    }
更新2


如果自定义AuthorizeAttribute不起作用或不起作用,您可以创建ActionFilter并将授权逻辑放在那里。当然这不是最好的做法,但你至少可以试着去做。请参见此处:

您是否查看了使用owin w/b2c的应用程序?是的,我查看了,这是我传递给OIDC配置程序的选项对象的基础。为了详细说明,我使用示例应用程序使其正常工作,但现在,我想将相同的身份验证层添加到现有的Umbraco应用程序中,该应用程序已经具有身份验证,我希望保持原样。我不需要我的自定义身份验证连接到Umbraco中的前端用户存储,因为我只想进行身份验证,然后忘记。或者可能是auth,然后可能是log。该站点的其余部分是可供公众访问的。只是想澄清几个问题:当用户未登录并试图打开MyModelController的索引页时,会发生什么?他应该被引导到您的自定义登录页面还是umbraco one?您是否希望使用两种不同的授权系统,即您的custom和umbraco?因此,它们中的每一个都将用于不同的页面?laroslav:用户应该被重定向到Azure AD B2C登录页面。如果一个用于前端(自定义)而另一个用于后台(Umbraco),我可以使用授权系统。我不需要覆盖后台登录。简单地说:我想在用户试图访问特定文档类型时对其进行身份验证。我只想知道该用户已向我的身份提供商注册。我尝试使用
MemberAuthorizationAttribute
保护文档类型控制器,但这会导致错误“未提供此类型的页面”。但是,我可以通过
HttpContext.GetOwinContext().Authentication.Challenge()
调用OAuth提供程序。当请求未通过身份验证时,我是否可以以某种方式覆盖
MemberAuthorizationAttribute
所做的操作?不幸的是,您不能使用MemberAuthorizationAttribute检查用户是否获得授权。如果需要,您可以在此处阅读更多:。我了解您的需求,并将尝试更多地了解您的问题。您是否只尝试编写自己的自定义属性?我想这应该行得通。我在以前的一个项目中看到了这种方法。我们在WebAPI中使用了它,但在MVC中应该是一样的。这里:您可以通过OWIN上下文检查您的用户,如果需要重定向到登录页面或任何您想要的内容。如果有帮助或需要更多说明,请写信给我。我已更新了关于custom AuthorizeAttribute的说明。我选择按照您的建议编写
AuthorizeAttribute
的自定义实现。我以前就考虑过,但是