Obtaing access token in a Web Part

%3CLINGO-SUB%20id%3D%22lingo-sub-1168871%22%20slang%3D%22es-ES%22%3EObtaing%20access%20token%20in%20a%20Web%20Part%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1168871%22%20slang%3D%22es-ES%22%3E%3CP%3EHi%3C%2FP%3E%3CP%3E%3CSPAN%3E%3CBR%20%2F%3EWe%20have%20a%20website%20with%20a%20game%20that%20uses%20Azure%20AD%20to%20authenticate%20the%20users.%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%3CSPAN%3EOne%20of%20our%20clients%20has%20decided%20to%20put%20the%20website%20inside%20their%20Sharepoint%20and%20now%20they%20want%20avoid%20the%20%22relogin%22%20against%20their%20Azure%20AD.%20If%20they%20are%20logged%20in%20their%20Sharepoint%2C%20they%20want%20to%20be%20logged%20in%20my%20website%20at%20the%20same%20time.%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EOur%20doubt%20is%20simple.%20We%20have%20developed%20to%20Sharepoint%20Web%20Part.%20Inside%20this%20Web%20Part%20we%20have%20an%20iframe%20to%20render%20our%20website%20that%20login%20against%20Azure%20AD.%20Our%20client%20don't%20want%20to%20relogin%20in%20our%20website%20and%20prefer%20that%20the%20login%20will%20be%20automatic%20according%20to%20the%20access%20token%20of%20the%20session%20Sharepoint.%3CSPAN%3E%26nbsp%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3EWe%20need%20to%20know%20the%20way%20to%20obtain%20the%20Sharepoint%20token%20to%20pass%20it%20to%20our%20website%3C%2FP%3E%3CP%3E-----------------------------------------------------------------------------------------------------------------%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%3CP%3Eimport%20-%20Version%20from%20'%40microsoft%2Fsp-core-library'%3B%20%3CBR%20%2F%3Eimport%3CBR%20%2F%3E%20-%20IPropertyPaneConfiguration%2C%3CBR%20%2F%3E%20PropertyPaneTextField%3CBR%20%2F%3E-%20from%20'%40microsoft%2Fsp-property-pane'%3B%20%3CBR%20%2F%3Eimport%20-%20BaseClientSideWebPart%20from%20'%40microsoft%2Fsp-webpart-base'%3B%20%3CBR%20%2F%3Eimport%20-escape%20from%20'%40microsoft%2Fsp-lodash-subset'%3B%20%3CBR%20%2F%3E%3CBR%20%2F%3Eimport%20styles%20from%20'.%2FTestwebpartWebPart.module.scss'%3B%20%3CBR%20%2F%3Eimport%20*%20as%20strings%20from%20'TestwebpartWebPartStrings'%3B%20%3CBR%20%2F%3E%3CBR%20%2F%3Eexport%20interface%20ITestwebpartWebPartProps%20%3F%3CBR%20%2F%3E%20%3CBR%20%2F%3Edescription%3A%20string%3B%20%3CBR%20%2F%3E%3CBR%20%2F%3Eexport%20default%20class%20TestwebpartWebPart%20extends%20BaseClientSideWebPart%20%3CITESTWEBPARTWEBPARTPROPS%3E%3CBR%20%2F%3E%3CBR%20%2F%3E%20%3F%3CBR%20%2F%3E%20public%20render()%3A%20void%20%3F%3CFONT%20color%3D%22%23e62412%22%3E%20var%20access_token%20%3F%20%3F%3F%3F%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3Bthis.domElement.innerHTML''%3B%3CIFRAME%20src%3D%22'%26lt%3BA%22%20href%3D%22https%3A%2F%2Fourapp.es%2F%3Ftoken%3D%24%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fourapp%3Ftoken%3D%24%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Blt%3B%2FA%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bgt%3B%7Baccess_token%7D%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3B%2339%3B%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bgt%3B%3C%2FIFRAME%3E%3CBR%20%2F%3E%20%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%20%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%3C%2FFONT%3E%3CBR%20%2F%3E%26nbsp%3B%20%E2%80%A2%3CBR%20%2F%3E%3CBR%20%2F%3E%20protected%20get%20dataVersion()%3A%20Version%20.%20.%20.%3CBR%20%2F%3E%20return%3CBR%20%2F%3EVersion.parse('1.0')%3B%20%3CBR%20%2F%3E%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20protected%20getPropertyPaneConfiguration()%3A%20IPropertyPaneConfiguration%3CBR%20%2F%3E%20%3F%20return%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20%3F%20pages%3A%20%5B%20%3F%20header%3A%20%3F%3CBR%20%2F%3E%20description%3A%20strings.%20PropertyPaneDescription%3CBR%20%2F%3E%20%2C%3CBR%20%2F%3E%20groups%3A%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20%5B%20%3F%20groupName%3A%20strings.%20BasicGroupName%2C%3CBR%20%2F%3E%20groupFields%3A%3CBR%20%2F%3E%20%5B%20PropertyPaneTextField('description'%2C%20s%3CBR%20%2F%3E%20label%3A%20strings.%20DescriptionFieldLabel%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20%5D%5D%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20%5D%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20%5D%3CBR%20%2F%3E%20%5D%20%5D%20%3B%20%3CBR%20%2F%3E%7D%3CBR%20%2F%3E%7D%26nbsp%3B%26nbsp%3B%3C%2FITESTWEBPARTWEBPARTPROPS%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1168871%22%20slang%3D%22es-ES%22%3E%3CLINGO-LABEL%3EToken%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3Eweb%20part%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1170184%22%20slang%3D%22en-US%22%3ERe%3A%20Obtaing%20access%20token%20in%20a%20Web%20Part%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1170184%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F535940%22%20target%3D%22_blank%22%3E%40vcima%3C%2FA%3E%26nbsp%3BHow%20is%20authentication%20handled%20in%20your%20application%3F%3CBR%20%2F%3E%3CBR%20%2F%3EI%20would%20avoid%20passing%20an%20authentication%20token%20in%20the%20way%20you%20are%20describing.%20If%20you've%20implemented%20authentication%20correctly%20in%20the%20other%20application%20(for%20example%2C%20OWIN%20for%20authentication)%2C%20you%20would%20have%20no%20problem%20authenticating%20without%20re-logging%20in%20to%20the%20iframe.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1232051%22%20slang%3D%22es-ES%22%3ERe%3A%20Obtaing%20access%20token%20in%20a%20Web%20Part%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1232051%22%20slang%3D%22es-ES%22%3E%3CP%3EHi%20%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F39836%22%20target%3D%22_blank%22%3E%40Beau%20Cameron%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EAnd%2C%20If%20I%20have%20something%20like%20this%2C%20How%20is%20the%20best%20way%20to%20obtain%20the%20user%20token%3F%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3Epublic%20render()%3A%3CBR%20%2F%3Evoid%20%3F%20...%20%3CBR%20%2F%3Elet%20request%20%3F%20this.getRequest(param1)%3B%20%3CBR%20%2F%3E...%20%3CBR%20%2F%3E%7D%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%3CP%3Eprotected%20getRequest(param1%3A%20string)%3A%20Promise%3CANY%3E%20%3F%3C%2FANY%3E%3C%2FP%3E%3CP%3Elet%20loginURL%20%3F%20this.properties.url%2B%22%2Fadmin%2Fapi%2Fv2%2Flist%22%3B%3C%2FP%3E%3CP%3Elet%20body%20s''param%22%3A%22'%2Bparam1%2B'%22'%3B%3C%2FP%3E%3CP%3Elet%20requestHeaders%3A%20Headers%20%3F%20new%20Headers()%3B%20requestHeaders.append(%22Accept-Tos%22%2C%20%22true%22)%3B%20requestHeaders.append(%22Content-Type%22%2C%20%22application%2Fjson%22)%3B%20requestHeaders.append(%22respondWithObject%22%2C%20%22true%22)%3B%20%3CBR%20%2F%3E%20%3CSTRONG%3E**requestHeaders.append('Authorization'%2C%20%3CTOKEN%3E'Bearer')%3B%20%3F%3F%3F%3F%20**%3C%2FTOKEN%3E%3C%2FSTRONG%3E%3C%2FP%3E%3CP%3Elet%20httpClientOptions%3A%20IHttpClientOptions%20%3F%20body%3A%20body%2C%20headers%3A%20requestHeaders%3CBR%20%2F%3E%3F%3C%2FP%3E%3CP%3Ereturn%3CBR%20%2F%3Ethis.context.httpClient.post(%20loginURL%2C%20HttpClient.configurations.v1%2C%3CBR%20%2F%3EhttpClientOptions)%20.then((response%3A%20HttpClientResponse)%3A%20any%20.%26gt%3B%20%3F%3CBR%20%2F%3Ereturn%20response.json()%3B%3CBR%20%2F%3E%3F%20%3CBR%20%2F%3E%7D%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1232626%22%20slang%3D%22en-US%22%3ERe%3A%20Obtaing%20access%20token%20in%20a%20Web%20Part%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1232626%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F535940%22%20target%3D%22_blank%22%3E%40vcima%3C%2FA%3E%26nbsp%3BThe%20Url%20this.properties%20%2B%26nbsp%3B%3CSPAN%3E%2Fadmin%2Fapi%2Fv2%2Flist%22%20is%20to%20your%20custom%20API%3F%26nbsp%3B%3CBR%20%2F%3E%3CBR%20%2F%3EYou%20need%20to%20register%20this%20API%20in%20Azure%20AD%20as%20a%20Registered%20Application.%20From%20there%2C%20you%20would%20use%20the%20AADHttpClient%20instead%20of%20the%20HttpClient%20you%20are%20using%2C%20to%20send%20requests%20to%20that%20API.%20This%20is%20outlined%20in%20the%20SPFx%20documentation.%3CBR%20%2F%3E%3CBR%20%2F%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fsharepoint%2Fdev%2Fspfx%2Fuse-aadhttpclient%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fsharepoint%2Fdev%2Fspfx%2Fuse-aadhttpclient%3C%2FA%3E%3CBR%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E
Highlighted
Contributor

Hi ,


We have a website with a game that uses Azure AD to authenticate the users.

 

One of our clients has decided to put the website inside their Sharepoint and now they want avoid the "relogin" against their Azure AD. If they are logged in their Sharepoint, they want be logged in my website at the same time.

 

Our doubt is simple. We have developed a Sharepoint Web Part. Inside this Web Part we have an iframe to render our website that login against Azure AD. Our client don' t want to relogin in our website and prefers that the login will be automatic according to the access token of the session Sharepoint. 

We need to know the way to obtain the Sharepoint access token to pass it to our website

-----------------------------------------------------------------------------------------------------------------

import { Version } from '@microsoft/sp-core-library';
import {
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import { escape } from '@microsoft/sp-lodash-subset';

import styles from './TestwebpartWebPart.module.scss';
import * as strings from 'TestwebpartWebPartStrings';

export interface ITestwebpartWebPartProps {
  description: string;
}

export default class TestwebpartWebPart extends BaseClientSideWebPart <ITestwebpartWebPartProps> {

  public render(): void {
    var access_token = ¿¿??     
    this.domElement.innerHTML = `
      <iframe src='https://ourapp?token=${access_token}'/>`;

  }

  protected get dataVersion(): Version {
  return Version.parse('1.0');
}

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
  return {
    pages: [
      {
        header: {
          description: strings.PropertyPaneDescription
        },
        groups: [
          {
            groupName: strings.BasicGroupName,
            groupFields: [
              PropertyPaneTextField('description', {
                label: strings.DescriptionFieldLabel
              })
            ]
          }
        ]
      }
    ]
  };
}
}

3 Replies
Highlighted

@vcima How is authentication handled in your application?

I would avoid passing an authentication token in the way you are describing. If you've implemented authentication correctly in the other application (for example, OWIN for authentication), you would have no problem authenticating without re-logging in to the iframe.

Highlighted

Hi @Beau Cameron 

 

And, If I have something like this, How is the best way to obtain the user token?

 

public render(): void {
...
let request = this.getRequest(param1);
...
}

protected getRequest(param1: string): Promise<any> {

let loginURL = this.properties.url+"/admin/api/v2/list";

let body = '{"param":"'+param1+'"}';

let requestHeaders: Headers = new Headers(); requestHeaders.append("Accept-Tos", "true"); requestHeaders.append("Content-Type", "application/json"); requestHeaders.append("respondWithObject", "true");
**requestHeaders.append('Authorization', 'Bearer <TOKEN>'); ????**

let httpClientOptions: IHttpClientOptions = { body: body, headers: requestHeaders
};

return this.context.httpClient.post( loginURL,
HttpClient.configurations.v1, httpClientOptions)
.then((response: HttpClientResponse): any => {
return response.json();
});
}

Highlighted

@vcima The Url this.properties + /admin/api/v2/list" is to your custom API? 

You need to register this API in Azure AD as a Registered Application. From there, you would use the AADHttpClient instead of the HttpClient you are using, to send requests to that API. This is outlined in the SPFx documentation.

https://docs.microsoft.com/en-us/sharepoint/dev/spfx/use-aadhttpclient