使用针对Azure AD B2C的OWIN / OIDC对自定义Umbraco控制器进行身份验证

时间:2017-12-21 15:52:24

标签: c# authentication owin umbraco azure-ad-b2c

我被困住了。

我有一个继承自RenderMvcController的自定义Umbraco控制器,当命中Index()操作方法时,返回一个文件。这是有效的,但我想做的是通过使用AuthorizeAttribute修改操作然后要求用户进行身份验证来保护它。

namespace MyNamespace.Controllers
{
    public class MyModelController : RenderMvcController
    {
        [Authorize]
        public ActionResult Index(RenderModel model)
        {
            // ...
        }
    }
}

使用针对Azure AD B2C应用程序的OWIN和OpenId Connect进行身份验证。这也有效并且经过测试,但是在非Umbraco环境中。

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

但我需要Umbraco胶水,并且在理解我应该如何配置cookie时遇到问题。我已经检查过调用了启动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文档与网址'/login.aspx?ReturnUrl=MYORIGINALROUTEHTTPENCODED'匹配。   此页面可以替换为自定义404.请查看“自定义404”文档。

我的猜测是,这是因为<authentication mode="Forms">中的Web.config设置,但如果我将其删除或将属性mode设置为"None",这是否会影响后台登录?

非常感谢有人能帮我指出正确的方向!

1 个答案:

答案 0 :(得分:2)

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

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

如果您需要实现自定义用户名/密码,请使用Umbraco扩展名。查看更多:https://our.umbraco.org/documentation/Reference/Security/#replacing-the-basic-username-password-check

您也可以使用Umbraco扩展名来访问Active Directory。查看更多:https://our.umbraco.org/documentation/Reference/Security/#authenticating-with-active-directory-credentials

关于AuthorizeAttribute。你发现找不到错误导致授权对OWIN和Umbraco一无所知。它重定向到默认路径,即login.aspx页面,它在项目中不存在。您可以将<authentication mode="Forms">设置为None。它不会影响Umbraco后台,因为它使用ASP.NET身份。如果您想保护某些资源,可以使用UmbracoAuthorizeAttribute。

查看更多:https://our.umbraco.org/documentation/Implementation/Controllers/#mvc

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

<强>更新

尝试使用您自己的AuthorizeAttribute版本。有一个例子:http://www.c-sharpcorner.com/UploadFile/56fb14/custom-authorization-in-mvc/

您需要覆盖AuthorizeCore方法并从HandleUnauthorizedRequest返回所需的结果。因此,您可以将RedirectResult返回到您的登录页面或任何您需要的地方。

您可以将其应用为

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

更新2

如果自定义AuthorizeAttribute没有帮助或它不起作用,您可以创建ActionFilter并将授权逻辑放在那里。当然,这不是最佳实践,但你至少可以尝试这样做。见这里:https://msdn.microsoft.com/en-us/library/gg416513(vs.98).aspx#Anchor_2