1. Thorsten Kummer
  2. PowerBuilder
  3. Friday, 18 February 2022 08:30 AM UTC

Dear all,

does anybody have a code snippet for getting a token to use with further calls to the MS 365 REST api?

I've got app ID, Client secret, user and password but need a tenant, which I don't have right now. 

I am not familiar with MS 365 and need to execute some REST calls but I cannot get the oauth token to work.

best regards

Thorsten

Thorsten Kummer Accepted Answer Pending Moderation
  1. Wednesday, 15 June 2022 11:32 AM UTC
  2. PowerBuilder
  3. # 1

Dear all,

I meanwhile solved it. let me know if I can help you if you face the same problem.
Thank you for your support!

Regards

Thorsten

Comment
There are no comments made yet.
Thorsten Kummer Accepted Answer Pending Moderation
  1. Friday, 18 February 2022 20:14 PM UTC
  2. PowerBuilder
  3. # 2

Thanks a lot, Kevin.

I tried  earlier today with the token endpoint instead of authorize.

I adapted your code but I am getting:

status code = 401
ls_type = invalid client

ls_description = AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app <... myappid>

 

ls_uri = https://login.microsoftonline.com/error?code=7000215

My Admin has given me:

AppId, clientid and client secret 

 

I am lost .... will contact my admin

 

Many regards

Thorsten

Comment
  1. Kevin Ridley
  2. Friday, 18 February 2022 21:09 PM UTC
Make sure it's setup as a SERVICE ACCOUNT in Azure. The client is and secret need to be for the service account.
  1. Helpful
  1. Thorsten Kummer
  2. Tuesday, 22 February 2022 10:03 AM UTC
Hello Kevin,



what exactly do you mean by:

setting it up as a service account?

Are you referring to the ltr_request.username ?

Thanks in advance

Thorsten
  1. Helpful
There are no comments made yet.
Kevin Ridley Accepted Answer Pending Moderation
  1. Friday, 18 February 2022 18:25 PM UTC
  2. PowerBuilder
  3. # 3

Try this.  Here's the code from my Dynamics 365 presentation.  You don't want to use a redirect.  You will notice a few differences.  I'd get rid of your current appendparam statements and figure out what resource you need to access, and also customize your tokenlocation similar to what I have but with your info obviously.  Don't worry about my info being on display here it's no longer valid.  Keys are the token location, resource and removing your response mode, type, redirect.  As I mentioned, you don't want to rely on a rediriect, you won't be able to do anything with it.  You could maybe try the new Chromium browser in an invisible window maybe to work with a redirect, but it's not necessary if you do it like below.  Hope this works for you, I had to dig up the code from my old laptop from Elevate 2018.  I haven't worked with Dynamics since then, so it's not real fresh in my brain.  Let us know if it works.

Integer				li_rc
OAuthClient			lo_client
OauthRequest		loa_request
ResourceResponse	lrr_response
TokenRequest		ltr_request
TokenResponse 	ltr_response
String					ls_state, ls_uri, ls_description, ls_type

CONSTANT	String		FUNCTION_NAME = "of_oauth_retrieve"
CONSTANT	Integer	SUCCESS = 1
CONSTANT	Integer	FAILURE = -1

try
//	ltr_request.granttype = 'client_credentials'
	ltr_request.granttype = 'password'
	ltr_request.username = "pb_elevate2@elevateme.onmicrosoft.com"
	ltr_request.password = "Elevate2018!"
	ltr_request.method = 'POST'
	ltr_request.clientid = APP_ID
	ltr_request.clientsecret = CLIENT_SECRET
	ltr_request.AppendParam ( "resource", "https://elevateme.crm.dynamics.com/")
	ltr_request.timeout= 30
	ltr_request.tokenlocation = "https://login.microsoftonline.com/elevateme.onmicrosoft.com/oauth2/token"
	ltr_request.SetHeader ( "User-Agent", "Elevate OAuth Demo" )

	lo_client = CREATE OAuthClient
	li_rc = lo_client.AccessToken ( ltr_request, ltr_response )

	If li_rc = 1 and ltr_response.GetStatusCode () = 200 Then
		If li_rc = 1 Then
			as_token = ltr_response.GetAccessToken()
		End If
		li_rc = ltr_response.GetBody(as_Body)
		return SUCCESS
	Else
		li_rc = ltr_Response.GetTokenError(ls_type, ls_description, ls_uri, ls_state)
		as_error = FUNCTION_NAME + " - Request AccessToken Falied: " + ls_description
		return FAILURE
	End If

catch(runtimeerror re)
	as_error = FUNCTION_NAME + " - RuntimeError: " + re.getmessage()
	return -1
finally
	IF IsValid(lo_client) THEN
		DESTROY lo_client
	END IF
end try
Comment
There are no comments made yet.
Thorsten Kummer Accepted Answer Pending Moderation
  1. Friday, 18 February 2022 14:23 PM UTC
  2. PowerBuilder
  3. # 4

Dear Kevin,

 

here's my code (please see below)

note itr_request is a tokenrequest object

note itr_response is a tokenresponse object

ioac_Client is a OAuth client

Microsoft says:

Authorization response

If the user consents to the permissions your app requested, the response will contain the authorization code in the code parameter. Here is an example of a successful response to the previous request. Because the response_mode parameter in the request was set to query, the response is returned in the query string of the redirect URL.

 
GET https://localhost/myapp/?
code=M0ab92efe-b6fd-df08-87dc-2c6500a7f84d
&state=12345

 

I don't know how to grab that code for the token call

 

 

**********************************************************************************

ls_redirect = "https://localhost"


itr_Request.tokenlocation = "https://login.microsoftonline.com/<MY-Tenant>/oauth2/v2.0/authorize"

itr_Request.Method = "POST"
itr_Request.secureprotocol = 0
itr_Request.clientid = "<myclientid>"
itr_Request.clientsecret = "<MySecret>"
itr_Request.UserName = "myaccount@testme.eu"
itr_Request.Password = "testtttt"
itr_Request.scope = "Mail.Send"
itr_Request.granttype = "password"

itr_Request.AppendParam( "response_mode", "query" )
itr_Request.AppendParam( "response_type", "code" )
itr_Request.AppendParam( "redirect_uri", ls_Redirect )


ll_Return = ioac_Client.AccessToken( itr_Request, itr_Response )
If ll_Return = 1 and itr_Response.GetStatusCode () = 200 Then
ls_test = itr_Response.getstatustext()
ll_Return = itr_Response.GetBody(ls_Body)
If ll_Return = 1 Then
is_AccessToken = itr_Response.GetAccessToken()

End If
Else
ll_Return = itr_Response.GetTokenError(ls_type, ls_description, ls_uri, ls_state)
MessageBox( "AccessToken Failed", "Return :" + String ( ll_return ) + "~r~n" + ls_description )
End If

Comment
  1. Bruce Armstrong
  2. Friday, 18 February 2022 22:21 PM UTC
If you're asking for code and sending a redirect you need to have the PowerBuilder app listing on a port for the response. You can use Roland Smith's winsock library for that. Then pass the host name and the port your app is listening on for the redirect_uril. You'll have the code to get the token in the event that gets the winsock response .



itr_Request.AppendParam( "response_type", "code" )

itr_Request.AppendParam( "redirect_uri", ls_Redirect )
  1. Helpful 1
  1. Thorsten Kummer
  2. Saturday, 19 February 2022 12:46 PM UTC
Dear Bruce, thanks a lot.

I thought I need to call /authorize and grab the code but meanwhile I know that I can directly use the /token endpoint. So I don't need the redirect URL at all, which I loke...

Currently i followed Kevin's example but facing a problem with the client secret. Kevin proposed:

"Make sure it's setup as a SERVICE ACCOUNT in Azure. The client is and secret need to be for the service account."

I will contact my Admin to check the setup. I don't have any access to the setup at all.



I hope I am not too far away from a working solution.

Thanks and hope to see you again soon in germany

Thorsten







  1. Helpful
There are no comments made yet.
Thorsten Kummer Accepted Answer Pending Moderation
  1. Friday, 18 February 2022 13:49 PM UTC
  2. PowerBuilder
  3. # 5

Hello Kevin,

thanks a lot. meanwhile I am a few steps further.

I can successfully call the authorize endpoint, but I am not able to grab the code that I need for the next call to the token endpoint.

I can't find out how to get the code parameter that is returned by the response.

regards

Thorsten

Comment
  1. Kevin Ridley
  2. Friday, 18 February 2022 14:07 PM UTC
Are you using the password grant type? That's what you need to use. I had to use a service account with the password grant.
  1. Helpful
There are no comments made yet.
Kevin Ridley Accepted Answer Pending Moderation
  1. Friday, 18 February 2022 13:36 PM UTC
  2. PowerBuilder
  3. # 6

I did an Elevate presentation in I believe 2019 on accessing MS Dynamics 365 REST API that I think you would find useful.  Wondering if @Armeen knows where the video for the session is.  I checked on Youtube and didn't see it.  If it's not available, I'll have to see if I can dig up the code on my old laptop.

 

Kevin

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.