{"record":{"id":"b461a0b2ef7116b6","repo":"alibaba/nacos","slug":"authorization-failed","errorCode":null,"errorMessage":"authorization failed!","messagePattern":"authorization failed!","errorType":"exception","errorClass":"AccessException","httpStatus":null,"severity":"error","filePath":"plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java","lineNumber":109,"sourceCode":"        }\n        \n        return user;\n    }\n    \n    @Override\n    public void authorize(Permission permission, NacosUser nacosUser) throws AccessException {\n        if (Loggers.AUTH.isDebugEnabled()) {\n            Loggers.AUTH.debug(\"auth permission: {}, nacosUser: {}\", permission, nacosUser);\n        }\n        if (nacosUser.isGlobalAdmin()) {\n            return;\n        }\n        if (hasGlobalAdminRole(nacosUser)) {\n            return;\n        }\n        \n        if (!roleService.hasPermission(nacosUser, permission)) {\n            throw new AccessException(\"authorization failed!\");\n        }\n    }\n    \n    private String resolveToken(HttpServletRequest request) {\n        String bearerToken = request.getHeader(AuthConstants.AUTHORIZATION_HEADER);\n        if (StringUtils.isNotBlank(bearerToken)\n            && bearerToken.startsWith(AuthConstants.TOKEN_PREFIX)) {\n            return bearerToken.substring(AuthConstants.TOKEN_PREFIX.length());\n        }\n        bearerToken = request.getParameter(Constants.ACCESS_TOKEN);\n        \n        return bearerToken;\n    }\n    \n    @Override\n    public boolean hasGlobalAdminRole(String username) {\n        return roleService.hasGlobalAdminRole(username);\n    }","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java#L91-L127","documentation":"Thrown by AbstractAuthenticationManager.authorize when a non-admin user without the global admin role attempts an operation for which roleService.hasPermission returns false. It is an AccessException meaning the caller is authenticated but lacks the required permission on the requested resource/action.","triggerScenarios":"An authenticated non-admin user invokes a secured API (config read/write, naming write, admin op) without a matching role/permission grant. Reached after authentication succeeds and the authorize(permission, nacosUser) check fails.","commonSituations":"A read-only user attempting a write; missing RAM permission entry for a namespace or resource; role grants not propagated after a role change; client using a service account scoped too narrowly.","solutions":["Grant the required role/permission to the user (RAM permission API: /v3/auth/permission) scoped to the resource and action.","Use an account with the global admin role for administrative operations.","Confirm the resource string and action in the request match the permission entry (READ vs WRITE, exact resource pattern)."],"exampleFix":"// before: read-only user issues a write\npermission = new Permission(\"*:*\", ActionTypes.WRITE);\nmanager.authorize(permission, readOnlyUser); // -> authorization failed!\n\n// after: grant write permission or use admin\n// POST /v3/auth/permission { role, resource:\"*:*\", action:\"w\" }\nmanager.authorize(permission, authorizedUser);","handlingStrategy":"validation","validationCode":"// pre-check role grants before issuing a secured op\nboolean canWrite = nacosUser.isGlobalAdmin()\n    || roleService.hasPermission(nacosUser, new Permission(resource, ActionTypes.WRITE));\nif (!canWrite) throw new AccessException(\"insufficient permission\");","typeGuard":"static boolean canPerform(NacosRoleService rs, NacosUser u, Permission p) {\n    return u != null && (u.isGlobalAdmin() || rs.hasPermission(u, p));\n}","tryCatchPattern":"try {\n    manager.authorize(permission, nacosUser);\n} catch (AccessException e) {\n    if (\"authorization failed!\".equals(e.getMessage())) {\n        // return 403 Forbidden to the client\n    } else throw e;\n}","preventionTips":["Scope service accounts with the minimal role/permission set.","Match resource pattern and action (READ/WRITE) exactly in RAM permission entries.","Use admin accounts only for admin operations."],"tags":["auth","authorization","permission","access-exception","rbac"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}