Question

I have this Cloudshare environment consisting on 3 machines:

  • One for Sharepoint 2013 (this is where I develop with VS2012 installed)
  • Another for SQL Server 2012
  • And another for Active Directory

I'm trying to create a basic high trust app for Sharepoint 2013 using server-to-server protocol.

I've followed several guides:

When I run the project (default template code) from VS and trust the app I get an exception in the following line:

Uri hostWeb = new Uri(Request.QueryString["SPHostUrl"]);

using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(hostWeb, Request.LogonUserIdentity))
{
    clientContext.Load(clientContext.Web, web => web.Title);
    clientContext.ExecuteQuery(); // throws exception
    Response.Write(clientContext.Web.Title);
}

in Default.aspx.cs

The exception could be any of the following:

The remote server returned an error: (403) Forbidden.

The remote server returned an error: (401) Unauthorized.

I have tried several troubleshooting tips with no luck. I'm not a SP2013 expert so any help will be appreciated.

Thanks

UPDATE

Here are the ULS log entries related to the request: http://pastie.org/pastes/8395956/text

Was it helpful?

Solution

for simplicity I will state the obvious!

user is not authenticated and resource requires authentication

this tells me there is somthing wrong going on with the hand shaking (your certificate is not sent or is wrong), as its a microsoft product the best place is to look at msdn.

to make it clear please read this:

The following step is optional. However, we recommend that you develop and test with HTTPS turned on. Turning off HTTPS might cause you as a developer to miss certain issues when building an app that would occur during a production deployment where HTTPS is required.

now you read the note, read the issue that your having!

OAuth now requires SharePoint to run HTTPS, not only for your service but also for SharePoint 2013. You’ll get a 403 (forbidden) message when attempting to make a call to SharePoint by using a test certificate.

On the computer where you have SharePoint 2013 installed, you can turn off the HTTPS requirement during development by using the following Windows PowerShell cmdlets.

so that is your problem right there! to get around it whilst developing do:

this in powershell for testing/development:

$serviceConfig = Get-SPSecurityTokenServiceConfig
$serviceConfig.AllowOAuthOverHttp = $true
$serviceConfig.Update()

once finished return it back to how it was!

$serviceConfig = Get-SPSecurityTokenServiceConfig
$serviceConfig.AllowOAuthOverHttp = $false
$serviceConfig.Update()

now i would also like to note:

In a high-trust app, there is no context token, even if you use the appredirect.aspx file. The context token is specific to configurations that use Windows Azure Access Control Service (ACS). However, an access token is still required. If you’re using a high-trust configuration, your web application has to authenticate the user in the same way that SharePoint 2013 does (that is, the app is responsible for creating the user portion of the access token).

are you using the tokenhelper class to get the clientcontext?

        using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(hostWeb, Request.LogonUserIdentity))
        {
            clientContext.Load(clientContext.Web, web => web.Title);
            clientContext.ExecuteQuery();
            Response.Write(clientContext.Web.Title);
        }

also what exactly are you trying to do as you might need more permissions depending on what your doing!

To access other properties, you may need to request permissions on the host web.

http://msdn.microsoft.com/en-us/library/fp179901.aspx

hope the above answers your question! you need to make sure that the above is correctly done for it to work!


if that is still an issue than its somthing wrong with the guid that is issued by vs2012, that is auto sent when you press F5, this is set in web.config at this line:

<add key="IssuerId" 

change the guid from upper case to lower case:

from:

<add key="IssuerId" value="F2AE6B96-1FC0-43C6-B5D0-900117C491A4"/>

to

<add key="IssuerId" value="f2ae6b96-1fc0-43c6-b5d0-900117c491a4"/>

obviously your guid is going to be different from above ;)

also like to note you need a unique certificate for each individual app! also make sure the guid is the same as the powershell guid using Get-SPTrustedSecurityTokenIssuer should be the same as the web.config!

http://www.jamestsai.net/Blog/post/SharePoint-Provider-Hosted-App-401-Unauthorized-error-on-clientContextExecuteQuery().aspx

UPDATE

Just looked at your log file!

to break it down its failing straight away with the authentication! what method are you using? ntlm? kerbos? ect...

This is fundamental to know how you have setup your farm and authentication!

now there could be several issues going on here by the looks of the errors! I recommend that you read through the links below! I would highly recommend once you have read the links that if all is correct in your setup to run New-SPTrustedSecurityTokenIssuer this example can be found in my last link at the bottom of the page! this might solve you issue with the token part and the correct handshaking between two servers(validating each other).

1) the token is not being sent due to the security settings that are not compatible!

If you are using Windows claims mode for user authentication and the web application is configured to use only Kerberos authentication without falling back to NTLM as the authentication protocol, then app authentication does not work.

http://technet.microsoft.com/en-us/library/ee806870.aspx

or/and

2) your using server to server auth, this is where it could be going wrong! have your profile been synchronized??

for 2013 server to server make sure that group memberships are synchronized with the User Profile service application.

If a user profile exists for a user and the relevant group memberships are not synchronized, access may be denied when the user is supposed to be granted access for a given resource. Therefore, make sure that group memberships are synchronized with the User Profile service application.

http://technet.microsoft.com/en-us/library/jj219806.aspx

now this is needed for server to server setup to work!

Server-to-server authentication allows for servers that are capable of server-to-server authentication to access and request resources from one another on behalf of users. Therefore, the server that runs SharePoint Server 2013 and that services the incoming resource request must be able to complete two tasks:

To rehydrate a user’s identity, a server that can perform server-to-server authentication requests access to SharePoint resources. SharePoint Server 2013 takes the claims from the incoming security token and resolves it to a specific SharePoint user. By default, SharePoint Server 2013 uses the built-in User Profile service application to resolve the identity.

and the result of the above is:

If a user profile and the relevant group memberships for the user are not synchronized, SharePoint Server 2013 may incorrectly deny access to a given resource. Therefore, make sure that group memberships are synchronized with the User Profile service application. For Windows claims, the User Profile service application imports the four key user attributes previously described and group memberships.

http://technet.microsoft.com/en-us/library/jj729797.aspx

point being is the token and authentication is not working correctly because either your setup is wrong with security type or configuration! knowing what you have done will determin where its going wrong! clearly it looks like server to server auth is getting rejected as the token is not sent properly.

If you belive that the authentication protocol is correct than, you can follow this guide once you have read the above links:

http://technet.microsoft.com/en-us/library/jj655400.aspx

link above explains and demonstrates server to server steps for specific senarios

to create a trust between two servers (Creates a trust between a server to server principal.)

follow this guide! using New-SPTrustedSecurityTokenIssuer

http://technet.microsoft.com/en-us/library/jj219695.aspx

sorry for the long text and many links! as its server to server and the log is generic/setup I can give you a definitive answer! but what i do know is the handshaking between two servers is going wrong meaning you have missed somthing out with the initial setup! the links above should hopefully solve your issue between handshaking to pass the correct credentials to work properly!

OTHER TIPS

I had similar problems. Instead of using ClientContext or TokenHelper, I switched to the new SharePointContext which you can read about here: http://blogs.msdn.com/b/kaevans/archive/2013/09/24/introducing-sharepointcontext-for-provider-hosted-sharepoint-apps.aspx

Once I made this switch, my 401 and 403 problems disappeared. The new SharePointContext uses the underlying TokenHelper, so make sure you have the latest version of the TokenHelper file also.

I think I know what your problem was, the server log points to client/server machine is not having time in sync.

"SPApplicationAuthenticationModule: No valid access token exists in the Authorization header, you should see a 401 challenge as a response to this request."

"SPSecurityTokenExtensions: Not Valid Before:10/11/2013 21:15:38, Valid To:09/06/2015 07:55:38."

I had faced similar error few days back, and the resolution was to have the server and client machine time to be in sync.

Foundation  Application Authentication ajezq High SPApplicationAuthenticationModule: 
Error authenticating request, Error details: 
Header: 3000002;reason="The access token has expired.
It's valid from '4/29/2015 2:50:44 PM' and to '4/30/2015 2:50:44 AM'.";
category="invalid_client", Body: {"error_description":"Invalid JWT token. The token is not yet valid. 
Current time is 4\/29\/2015 10:44:25 AM and the token is Valid from 4\/29\/2015 2:50:44 PM."}  

How to set the machine time in sync with the internet

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top