【问题标题】:DnnModuleAuthorize Attribute Always Returns Unauthorized in Web APIDnnModuleAuthorize 属性在 Web API 中始终返回未经授权
【发布时间】:2014-04-09 06:09:00
【问题描述】:

我正在尝试在自定义模块的 Web API 方法中使用此属性:

[DnnModuleAuthorize(AccessLevel = DotNetNuke.Security.SecurityAccessLevel.Edit)]

但无论我设置什么 SecurityAccessLevel,我总是收到 401 未经授权的响应。

我能够通过添加使代码工作:

[AllowAnonymous]

关于方法,并添加:

if (!ModulePermissionController.CanEditModuleContent(this.ActiveModule))
                return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "You do not have permission to access this content.");

到我的方法的开头,但这似乎是一种我真的不需要的解决方法,因为它正是该属性的用途。我正在运行 DNN 7.2.1。

有人知道我的属性哪里出错了吗?

【问题讨论】:

    标签: dotnetnuke dotnetnuke-module dotnetnuke-7


    【解决方案1】:

    您是否将SupportedModules 属性应用于您的控制器(或操作方法)?如果是这样,我猜您传入的名称与 DNN 中的真实名称不匹配(您应该传入桌面模块名称)。尝试删除该属性,看看是否有帮助。

    设置ActiveModule 和当前用户(从而使您在操作方法中进行检查)的同一进程应该负责实现DnnModuleAuthorize 属性的检查。所以,这绝对是令人困惑的。也许情况发生了变化,如果您只在标头中传递 ModuleId 而不是 TabId,那么它会设置 ActiveModule,但不会进行身份验证?

    您是否查看过 Fiddler 中的流量并确保正确发送了 ModuleIdTabId 标头?以超级用户(即主机级用户)身份登录是否会影响任何身份验证检查(如果是,可能是 URL 构造不正确,并且 DNN 识别了错误的门户)?

    【讨论】:

    • 嘿布莱恩。 SupportedModules 已应用于控制器(但不是 DnnSupportedModules,假设这只是一个错字?),还尝试将其移至方法,但没有帮助;标头正在被传入并正确解析,并且与这些 ID 相关的所有其他功能都按预期工作;并且以超级用户身份登录没有任何影响。
    • @ChrisSearles 是的,这是一个错字。尝试删除 SupportedModules 属性并查看它是否有帮助(我用详细信息/建议更新了我的答案)。
    • 试过了,没有运气。也只是在 Fiddler 中进行了双重检查,并且标题肯定被正确发送(选项卡和模块 ID)。
    • 我也在为此苦苦挣扎。以“主机”身份登录,效果很好。以“注册用户”或“订阅者”身份登录我得到 401 Unauthorized。
    • 发现我缺少 [SupportedModules] 属性的解决方案。添加 [SupportedModules("myModuleNameAsInManifest")] 给出了不同的错误,结果证明这是一个未定义的敲除变量,因为在数据库中只有 varchar(6) 分配的“值”“未定义”,因此返回一个截断错误,如此处所述:stackoverflow.com/questions/5591473/…
    【解决方案2】:

    原来它实际上与防伪令牌有关。我正在使用 Angular,所以我在 Angular 服务中手动设置标题,而不是使用内置的 ServicesFramework setModuleHeaders 方法,并且只设置 TabId 和 ModuleId。我不认为 [AllowAnonymous] 属性会覆盖防伪功能,但看起来确实如此(很高兴知道)。

    为那些做同样事情的人提供完整的解决方案:

    var baseUrl = sf.getServiceRoot('[yourmodulename]') + '[controller]';
        var config = {
            headers: {
                'ModuleId': sf.getModuleId(),
                'TabId': sf.getTabId(),
                'RequestVerificationToken': sf.getAntiForgeryValue()
            }
        };
    

    【讨论】:

    • 是的,AllowAnonymous 属性...不太好。它完全忽略了身份验证管道的其余部分。
    • 嘿,克里斯,您是如何获得 AntiForgeryValue 的。我不认为你可以从 JS 中得到它。你是用 http get 来获取的吗?
    • @JKing 您必须在客户端上初始化服务框架。看看这里有一个很好的详细示例:dnnsoftware.com/community-blog/cid/145174/…
    • 感谢您跟进克里斯。正是我正在寻找的东西,它是我需要让我的服务安全工作的最后一块。
    【解决方案3】:

    当您初始化 ServicesFramework 时,请确保在 document.ready 函数中进行。

        var self = {};
        jQuery(document).ready(function ($) {
            self.sf = $.ServicesFramework(<%=ModuleID %>);
        });
    

    更多信息:www.dnnsoftware.com/forums/threadid/507753/scope/posts/services-framework-problems

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-09
      • 2016-12-24
      • 1970-01-01
      • 1970-01-01
      • 2013-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多