I'm trying to access our company SharePoint 2013 instance, which is hosted at ourinstance.sharepoint.com, with small Java web application.
I registered application through _layouts/15/AppRegNew.aspx this way:
- I let SP generate Client ID, Client Secret,
- to App Domain I set: ourdomain:8443
- to Redirect URL I set:
https://ourdomain:8443/our-redirect-processing
I edited application permissions with _layouts/15/appinv.aspx, where I looked it up by client ID and edited its Permission Request XML to contain:
<AppPermissionRequests AllowAppOnlyPolicy="true">
<AppPermissionRequest Scope="http://insideidc.sharepoint.com/oursite/web" Right="FullControl"/>
</AppPermissionRequests>
Handler behind https://ourdomain:8443/our-redirect-processing
is doing this:
JsonWebSignature jws = JsonWebSignature.parse(new JacksonFactory(), request.getParameter("SPAppToken"));
JsonParser jsonParser = new JacksonFactory().createJsonParser(jws.getPayload().get("appctx").toString());
AppCtx appCtx = jsonParser.parse(AppCtx.class, new CustomizeJsonParser());
String appctxsender=jws.getPayload().get("appctxsender").toString();
String[] splitApptxSender = appctxsender.split("@");
String sharepointServerHostName = new URL(request.getParameter("SPSiteUrl")).getHost();
String resource = splitApptxSender[0] + "/" + sharepointServerHostName + "@" + splitApptxSender[1];
AuthorizationCodeTokenRequest tokenRequest = new AuthorizationCodeTokenRequest(new NetHttpTransport(), new JacksonFactory(),
new GenericUrl(appCtx.getSecurityTokenServiceUri()), jws.getPayload().get("refreshtoken").toString());
tokenRequest.setRedirectUri(request.getRequestURL().toString());
String aud = (String) jws.getPayload().getAudience();
tokenRequest.setClientAuthentication(new ClientParametersAuthentication(aud, secrets.get(aud)));
tokenRequest.setGrantType("refresh_token");
tokenRequest.set("resource", resource);
tokenRequest.set("refresh_token", jws.getPayload().get("refreshtoken").toString());
TokenResponse response = tokenRequest.execute();
token = response.getAccessToken();
It uses com.google.api.client. auth, http and json classes.
The token I get I use in REST call to this URL:
https://ourinstance.sharepoint.com/oursite/_api/web/getFolderByServerRelativeUrl('/thefolderIwant')/Files
with these Headers:
Accept: application/json;odata=verbose
Authorization: Bearer theToken
The response asks me for logging in, while response header has WWW-Authenticate: NTLM set.
First question: should such complex process of obtaining OAuth token end up with another credentials request?
Second and main question: how can I construct domain\username for NTLM Authenticator, which I can build, when SharePoint is hosted for us?
I had a similar experience when trying to access Microsoft's Project Online. I found some helpful information from AllThatJS which pointed me in the right direction. He suggested sniffing the packets using Fiddler. Once I did that, I saw what was actually going on. Here is some Java code I used to solve this problem, using Apache's HttpClient, Apache's common-io, and log4j to solve this :