Set Permissions on SharePoint Application Pages - visual-studio-2010

I have developed a number of application pages using visual studio 2010 and deployed them on SharePoint 2010.
All the pages have been extended from LayoutsPageBase.
Currently all the application pages are accessible by any authenticated users. However I would like to allow certain groups/permission to access these pages and disallow access for other groups/permissions.
My question:
How can I set the permissions for application pages to be accessible only by certain groups on the SharePoint level and on the code level?

Override a combination of these properties from LayoutsPageBase:
RequireDefaultLayoutsRights
RequireSiteAdministrator
RightsRequired
SupportsReadOnlySite
These properties are used by the CheckRights method to grant or deny access to an application page.
If you need something more specific than these properties offer, set RightsCheckModes to None and then write your own code that throws the following exception if the user should not have access:
SPUtility.HandleAccessDenied((Exception) new UnauthorizedAccessException());
Following the convention of the LayoutsPageBase class, this custom code should be called by your override of either the OnLoadComplete or OnPreInit events.

Related

How to access web.config sections in a Web service called from another application?

I'm working on a Web service with Visual Studio, framework 4.7.1. One of its Web methods needs to call another Web service (provided by another company). It converts the parameters it receives (that are consistent with our main application's business logic) into values the other Web service can handle (according to it's own business logic). To do this, it relies heavily on data stored in the Web.config file.
I tested it directly (start the Web service and call the Web methods with automatically generated pages on a Web browser page) and everything worked fine.
Now, I need to build a test application (also in Visual Studio, framework 4.7.1) to call the same Web methods. On first testing it, I noticed that the Web service was trying to access the test application's config file instead of its own (as described in Can't read Web.config with ConfigurationManager.AppSettings ).
So I created an applicationSettings section in the Web.config and moved all the data from appSettings into it. It worked fine.
Now, however, I notice that the same thing happens with the custom sections. One of them looks like this:
<configSections>
<section name="jobTypeLists" type="AdelSoft_WS_FRA.JobTypesSection" />
</configSections>
<jobTypeLists>
<jobTypes>
<jobType codeCustomerType="A" codeJobType="JobForA" />
<jobType codeCustomerType="B" codeJobType="JobForB" />
</jobTypes>
</jobTypeLists>
I can see how such a structure could fit into its own .settings file, but I have another one that is much more complicated. (Like, the text nodes can have up to four ancestors.) To keep this short-ish, I'm not providing it now, but it can easily be arranged.
ConfigurationManager.GetSection("jobTypeLists") returns null when called from the test application. Same with WebConfigurationManager.GetSection("jobTypeLists").
I've also tried accessing the configuration file with ConfigurationManager.OpenExeConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile), but I can't seem to find my sections in the Configuration object it returns.
I'm not sure it means anything, but the Configuration object's FilePath property contains "C:\Folder\InnerFolder\WebServiceFolder\web.config.config". Why this second ".config"? I tried passing the same string to ConfigurationManager.OpenExeConfiguration(), without the ".config" extension: it returned null. (As it should, I feel.)
The Configuration object has 10 section groups and 22 sections, which I can't make heads or tails from. Likewise, I can list them.
Actually, there are two ways for a Visual Studio project to reference a Web service: as a regular reference (like you would any other project) or as a Web reference.
I was using the former, and therein lay my mistake.
To reference the Web service, I started it, copied the URL from the browser window that it opened, and pasted it into the "URL" text box in the "Add a Web reference" window from my test application. From there on, it worked fine.
(By the way, I have kept the regular reference as well, because I'm using some constants from the Web service to handle return values.)

Click-To-Call feature for Dynamics CRM (like Lync/Skype)

Advance warning: Im an absolute newbie to Dynamics CRM!
Intention
I want to have a feature like Lync/Skype integration but use my own URL. (Click on any telephone number inside CRM and call it).
For eg. assuming I have a web service which can initiate a call per URL: http://telephony.com/call?nr=012345678. Now, whenever a CRM user clicks onto a telephone number field (in forms and views) inside the CRM my web service should be called instead of Skype/Lync.
In fact I'm trying to reproduce sth. like the InGenius Connecter.
Attempts
I already tried to inject a JS web resource to a specific formular (in my case it was the default contact form) and override the Mscrm.ReadFormUtilities.openPhoneClient callback (which seems to handle the Lync/Skype integration).
function load() {
// override integrated CTC (Lync/Skype)
Mscrm.ReadFormUtilities.openPhoneClient = function (telephoneNr) {
// redirect user to my web service
window.location.replace("http://telephony.com/call?nr="+telephoneNr);
return;
}
}
Found this method at: Disable Lync completely
This does work well in forms of Dynamics 2015 (my custom link pops up instead of Skype/Lync). However, this does only work on entity forms since I can't inject web resources into an entity view.
My other ideas how to implement such a feature are:
Inject global JS resource which disables Lync/Skype and encapsulate every telephone number with link to my custom URL.
Extend/Manipulate Lync/Skype integration to use my custom URL instead of Lync/Skype.
Write plugin which encapsulate telephone numbers server side.
Question
Since I have a grasp understanding of Dynamics and no experience in plugin/resource development, I'm left a bit confused with these questions.
Is it possible to achieve any of the three ideas above ?
If not, any idea how InGenius solved this problem ?
Do you have any other idea/resources about this topic ?
Currently I found two options available to achieve a custom CTC feature. (Both has the downside of not being officialy supported by the dynamics crm.)
Global Ribbon
Pretty simple: Add a Click-To-Call button to global ribbon which is only enabled on specific grids when one row is selected.
This button refers to an JS-Action which retrieves the telephone number via ODATA and then launches the dial process.
Global Ribbon CustomRule injection
Add a global button to ribbon which refers to a JS resource per <CustomRule>. The JScript then unbinds all actions from links with .ms-crm-Phone classes and replaces its href-attribute.
This would be useful if one want to override the integrated "Skype / Lync - Click to Dial" feature with his own logic.
I didn't test this method until now, so I can't guarentee it's working !
Note: I will include example scripts as soon I got the time.

Dynamically set URL of web service

Scenario: I'm running code on the client that connects to a server and uses a web service to retrieve data about a SharePoint list. I'm using the Visual Studio 2010 "service reference" to get a web service for my SP Site and get my data from the list. It works. Now how do I go about coding it such that when I want to move from Test to Production, my web service calls will still work? Note that the web service is a SharePoint web service, I did not write it. I am only using it. Is what I am suggesting possible? I do have the ability to ensure that the Site is the exact same (except for URLS) on both environments (e.g. backup the SP site and put it on production). Thanks for any suggestions.
Summary:
Basically I'm looking for the best way to go from test to production without re-compiling my code which consumes the SP web service. Also, as a side note, if anyone knows how similar the test/production sharepoint sites have to be, [in order for the web service to work on both without anything but the URL being changed].. that would be helpful info.
Solution
The project configuration file can be used to specify the web service location. The .svcdatamap and other files in the VS project are for design time use only, and the URL which is actually used to connect to the SharePoint web service is passed as an argument to the System.Data.Services.Client.DataServiceContext object. This is only tangentially related, but to create your own WCF web service see this link. BTW, the web service will work without recompilation anywhere the SharePoint List has the same List name and the column you're querying has the same name.
As far as I know, Visual Studio Tools for Office projects allow you to have an app.config file in your project. I'd expect that Visual Studio created the app.config file and added the necessary configuration settings related to the web service reference. In any case, you need to store the correct web service url somewhere - app.config, registry or even a database.
If you are not able to store the web service endpoint address information in the app.config file, there's a way to configure the proxy manually.
If it's a .asmx reference added as a legacy "Web Reference" in Visual Studio then all you need to do is set the Url property value of the proxy object before you call any web service methods. For example:
MyASMXWebService proxy = new MyASMXWebService();
proxy.Url = "web service url";
proxy.HelloWorld();
If it's a .svc WCF service reference then things get a bit more complicated. You'll need to create your web service endpoint programmatically. For example:
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress endpoint = new EndpointAddress("web service url");
ChannelFactory<IMyWCFWebService> factory = new ChannelFactory<IMyWCFWebService>(binding, endpoint);
IMyWCFWebService proxy = factory.CreateChannel();
proxy.DoWork();
Since SharePoint services (SVC) do not provide a proxy, option 2 will not work. References to both locations must be included in your application and then use a parm to differentiate production from test. I believe 2013 will likely correct this bug.
You have to edit the URL in your project's web.config
Simple SharePoint example:
MyService.ListsSoapClient client = new MyService.ListsSoapClient();
client.Endpoint.Address = "site url"+"/_vti_bin/lists.asmx";

Visual studio 2010 - difference between Settings.settings and Resources.resx

simple question here. What is the difference between putting a string in Settings.settings and putting a string in Resources.resx ?
Regards
In Settings.setting the string will be placed in a config file, bassicaly a xml document which stores all kind of information your application needs to run. It's best practice to store configurable information in here. Also you can set the scope of the config value (application and user).
Application scoped config values will be shared among all users, while the user ones are limited to the current executing user of the application.
The .resx file is the place for storing all kinds of stuff your application needs to run, like images and so on. Files in here should be normally not editable by the user, its as the name states, a resource pool for your application. Also resources are also always global.

How to solve this error: The permissions granted to user 'COMPUTERNAME\\ASPNET' are insufficient for performing this operation. (rsAccessDenied)

I am trying to integrate the SSRS report to my web page.
The code is as follows:
ReportViewer1.ProcessingMode = rocessingMode.Remote;
ReportViewer1.ServerReport.ReportServerUrl = new Uri("http://localhost/reportserver");
ReportViewer1.ServerReport.ReportPath = "/Report Project1/Reconciliation";
List<ReportParameter> paramList = new List<ReportParameter>();
paramList.Add(new ReportParameter("StartDate", startdate.ToString(), false));
paramList.Add(new ReportParameter("EndDate", enddate.ToString(), false));
this.ReportViewer1.ServerReport.SetParameters(paramList);
ReportViewer1.Visible = true;
I get this error when I try to run this report:
The permissions granted to user 'COMPUTERNAME\\ASPNET' are insufficient for performing this operation. (rsAccessDenied)"}
System.Exception {Microsoft.Reporting.WebForms.ReportServerException}
Can anyone tell me what I am doing wrong?
To clarify Erikk's answer a little bit.
The particular set of security permissions you want to set to fix this error (there are at least another two types of security settings in Reports Manager) are available in the "security" menu option of the "Properties" tab of the reports folder you are looking at.
Obiously it goes without saying you should not give full permission to the "Everyone" group for the Home folder as this is inherited to all other items and subfolders and open a huge security hole.
You need to give your web app access to your reports. Go to your report manager (http://servername/reports/). I usually just give the whole web server "Browser" rights to the reports.
The account name of your server is usually Domain\servername$. So if you server name is "webserver01" and your domain is Acme, you would give the account Acme\servername$ Browser rights.
I think you could also fix it by disabling anonymous access (in IIS) on the web application you are running the report from, that way reporting services would authenticate using the users credentials instead of the ASPNET account. But that may not be a viable solution for you.
The problem is that your ASP.NET worker process does not have the permissions to do what you want.
Edit this user on the server (MACHINENAME\ASPNET), and give it more permissions (It may need write permissions etc).
You also will need to add MACHINENAME\ASPNET as a user to the SQL database SSRS is working with.

Resources