{"record":{"id":"1ac29975c328ea13","repo":"SignalR/SignalR","slug":"outgoing-authorization-can-only-be-required-for-an","errorCode":null,"errorMessage":"Outgoing authorization can only be required for an entire Hub, not a specific method.","messagePattern":"Outgoing authorization can only be required for an entire Hub, not a specific method\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.AspNet.SignalR.Core/AuthorizeAttribute.cs","lineNumber":110,"sourceCode":"        /// </summary>\n        /// <param name=\"hubIncomingInvokerContext\">An <see cref=\"IHubIncomingInvokerContext\"/> providing details regarding the <see cref=\"IHub\"/> method invocation.</param>\n        /// <param name=\"appliesToMethod\">Indicates whether the interface instance is an attribute applied directly to a method.</param>\n        /// <returns>true if the caller is authorized to invoke the <see cref=\"IHub\"/> method; otherwise, false.</returns>\n        public virtual bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)\n        {\n            if (hubIncomingInvokerContext == null)\n            {\n                throw new ArgumentNullException(\"hubIncomingInvokerContext\");\n            }\n\n            // It is impossible to require outgoing auth at the method level with SignalR's current design.\n            // Even though this isn't the stage at which outgoing auth would be applied, we want to throw a runtime error\n            // to indicate when the attribute is being used with obviously incorrect expectations.\n\n            // We must explicitly check if _requireOutgoing is true since it is a Nullable type.\n            if (appliesToMethod && (_requireOutgoing == true))\n            {\n                throw new ArgumentException(Resources.Error_MethodLevelOutgoingAuthorization);\n            }\n\n            return UserAuthorized(hubIncomingInvokerContext.Hub.Context.User);\n        }\n\n        /// <summary>\n        /// When overridden, provides an entry point for custom authorization checks.\n        /// Called by <see cref=\"AuthorizeAttribute.AuthorizeHubConnection\"/> and <see cref=\"AuthorizeAttribute.AuthorizeHubMethodInvocation\"/>.\n        /// </summary>\n        /// <param name=\"user\">The <see cref=\"System.Security.Principal.IPrincipal\"/> for the client being authorize</param>\n        /// <returns>true if the user is authorized, otherwise, false</returns>\n        protected virtual bool UserAuthorized(IPrincipal user)\n        {\n            if (user == null)\n            {\n                return false;\n            }\n","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/SignalR/SignalR/blob/693053b89a9e1f5ce819e3233ed159a6409de22b/src/Microsoft.AspNet.SignalR.Core/AuthorizeAttribute.cs#L92-L128","documentation":"Thrown by AuthorizeAttribute.AuthorizeHubMethodInvocation when the attribute has RequireOutgoing set to true and is applied to a method (appliesToMethod == true). SignalR's design cannot enforce outgoing authorization at the method level, so this is a runtime error flagging obviously incorrect attribute usage rather than silently allowing it.","triggerScenarios":"Placing [Authorize(Roles=..., RequireOutgoing=true)] (or an [Authorize] that defaults outgoing on) on an individual hub method instead of the hub class.","commonSituations":"Developer copies a class-level [Authorize] attribute onto a method expecting per-method outgoing auth; misunderstanding that RequireOutgoing is a hub-wide concern.","solutions":["Move the [Authorize] attribute (with RequireOutgoing) to the Hub class, not individual methods.","If per-method auth is needed, use [Authorize] without RequireOutgoing on the method.","Review the XML doc on RequireOutgoing: it is a class-level-only parameter."],"exampleFix":"// before (incorrect)\npublic class ChatHub : Hub\n{\n    [Authorize(RequireOutgoing = true)]\n    public void Send(string msg) { }\n}\n\n// after (correct)\n[Authorize(RequireOutgoing = true)]\npublic class ChatHub : Hub\n{\n    public void Send(string msg) { }\n}","handlingStrategy":"validation","validationCode":"// Apply [Authorize] with RequireOutgoing only at the class level\n[AttributeUsage(AttributeTargets.Class)] // if you wrap AuthorizeAttribute\npublic class OutgoingAuthAttribute : AuthorizeAttribute { }","typeGuard":"// In a startup validation pass, scan hub methods for Authorite attributes with outgoing required\nforeach (var m in hubType.GetMethods())\n{\n    var attr = m.GetCustomAttribute<AuthorizeAttribute>();\n    if (attr != null) { /* warn: ensure RequireOutgoing not set on method */ }\n}","tryCatchPattern":"try { base.AuthorizeHubMethodInvocation(ctx, appliesToMethod: true); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Outgoing authorization\"))\n{\n    // misplaced attribute; log and fix placement\n}","preventionTips":["Apply RequireOutgoing=true only at the Hub class level.","Add a code-review checklist item for attribute placement on hubs.","Write a startup test that scans hub methods for misconfigured [Authorize]."],"tags":["argument","authorize","misconfiguration","hub","server"],"backgroundTag":null,"analyzedSha":"693053b89a9e1f5ce819e3233ed159a6409de22b","analyzedAt":"2026-08-13T22:23:59.793Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}