After deploying your solution to SharePoint anonymous and read-only users may get the following error: Web Part Error: A Web Part or Web Form Control on this Page cannot be displayed or imported. You don’t have Add and Customize Pages permissions required to perform this action. Well, this is the case that is solved by famous this-issue-is-by-design (read: you have to find your own way how to solve the problem).
Why this error occurs?
The error message sais directly what is the problem: the current user has no permissions to customize pages and add or modify web parts on it. If you just deployed your solution to server and your solution is also accessible for anonymous and read-only users then they will get this error when accessing the page.
If you access the page as administrator then all web parts are put on page like expected because you have enough permissions to do it. After you opened page as administrator and you open same page as read-only or anonymous user the error is gone. This is because administrator account has enough permissions for all page initializing operations that must be done when page is accessed first time.
How to solve it?
Make sure your web parts are marked as safe in web.config file. There is special site level permission called “Add and Customize Pages” and by default this permission is not applied to Contributor role. You can do it manually through site settings page. This is not good option because now your contributors have more permissions you may want to give them.
Second option is go through site as administrator and open all pages that have custom web parts. If you don’t have a lot of pages and opening all pages is not very time consuming you can also consider this option.
If you have more pages and they are created during deployment and you know URL-s of pages you can write PowerShell script that requests all those pages as administrator to get pages initialized under account that has enough permissions to do so. You can also consider using wget or some similar command-line tool to make those requests.
Right now I don’t have more information about how to solve this issue. In my case the third option is best one because I have to provide my users a way how they can deploy solution and initialize it so they don’t have to go through a lot of configuration steps. If I find some better solution how to solve this issue I will blog about it here.