I have an Restful API which requires OAuth2 in order to get the token.
$username = 'A'
$password = 'B'
$ClientID = "C"
$client_secret = "D"
$RestEndpoint = 'https://oauth2/token'
I am trying to create a Logic Apps. But I am not sure if Logic Apps can handle OAuth2 or if there is a way.
If you are using Azure AD then you should be able to follow the these instructions:
https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-custom-api-authentication#part-3-populate-the-authorization-section-in-your-logic-app
Part 3 has the specific configuration within your Logic App:
Part 3: Populate the Authorization section in the Logic app
In the Authorization section of the HTTP action: {"tenant":"<<tenantId>>", "audience":"<<clientID from Part 2>>", "clientId":"<<clientID from Part 1>>","secret": "<<Password or Key from Part 1>>","type":"ActiveDirectoryOAuth" }
Related
There's so many different flows in the Microsoft docs that I have no clue what one is needed for me. I am using React and Python. (I understand node, so if someone explains using node/express its fine)
What user should see:
A page with a button to login, nav is there but wont work till logged in. The login creates a popup to sign in with Microsoft account. Once signed in, the user will be able to use nav to see dynamics information.
What I am trying to do:
This app needs to sign in a user and obtain the users email through 'https://graph.microsoft.com/v1.0/me'.(no client secrets needed) Then I need to send that email in this request;
(The tenant == {company}.crm.dynamics.com.)
allInfo = requests.get(
f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq \'{email}\'', headers=headers).json()
This backend request needs to have a client secret to obtain the information. So I believe my backend also needs to be logged on to a service account. I believe I need to get a token for my backend to make requests on behalf of the service account.
What I have:
I have a React frontend that is signing a user in and calling 'https://graph.microsoft.com/v1.0/me' correctly and getting that email. Once I get the email, I am sending it to my backend.
Now I have no clue how to proceed and have tried many things.
What I have tried for backend:
Attempt 1: I get a token but error: {'error': {'code': '0x80072560', 'message': 'The user is not a member of the organization.'}}. Problem is, this id is the Azure AD ID. It should def work
#app.route('/dynToken', methods=['POST'])
def get_dyn_token():
req = request.get_json()
partnerEmail = req['partnerEmail']
token = req['accessToken']
body = {
"client_id": microsoft_client_id,
"client_secret": client_secret,
"grant_type": "client_credentials",
"scope": SCOPE_DYN,
}
TENANTID = '{hash here}'
res = requests.post(
f'https://login.microsoftonline.com/{TENANTID}/oauth2/v2.0/token', data=body).json()
dyn_token = res['access_token']
headers = {
"Prefer": "odata.include-annotations=\"*\"",
"content-type": "application/json; odata.metadata=full",
"Authorization": f"Bearer {dyn_token}"
}
try:
allInfo = requests.get(
f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq \'{email}\'', headers=headers).json()
print(allInfo)
Attempt 2:
Same code but instead of f'https://login.microsoftonline.com/{TENANTID}/oauth2/v2.0/token' its
f'https://login.microsoftonline.com/common/oauth2/v2.0/token'. Error: An exception occurred: [Errno Expecting value] : 0. Because it returns an empty string.
Now I don't know if I am even on the right path or where to go. I know the routes work themselves if the token is correct. I used only SSR with no react and these routes work. But I need the React to be there too. I just don't know what flow to use here to get what I need. The docs make it easy for /me route to work. But the {company}crm.dynamics.com docs don't really provide what I am trying to do.
Additional info after comment:
What 'f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq '{email}'', headers=headers" is trying to get are API keys. Full code :
try:
allInfo = requests.get(
f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq \'{email}\'', headers=headers).json()
partner_value = allInfo['value'][0]['_company_partner_value']
response = requests.get(
f'https://{TENANT}api/data/v9.0/company_partnerses({partner_value})', headers=headers).json()
return {'key': response['company_apikey'], 'secret': response['company_apisecret']}
Then once it has the keys:
def api_authentication(apikey, apisecret):
headers = get_headers() #<-- same headers as above with using dyn_token
response = requests.get(
f'https://{TENANT}api/data/v9.0/company_partnerses?$filter=company_apikey eq \'{apikey}\' and company_apisecret eq \'{apisecret}\'&$select=company_apikey,company_apisecret,_company_account_value,_company_primarycontact_value,blahblah_unassignedhours,company_reporturl', headers=headers).json()
return response
Afterwards I am able to get all the information I am looking for to send back to my frontend for the client to see. (By making multiple request to crm with these keys)
The client_credentials grant that you are using should work, provided the CRM trusts the token issued to the client (your python backend). Please use MSAL library instead of hand crafting the token request. It will save you time and eliminate errors.
I have an application that serves to add slides from my PC into a google slides file, and it relies on the following code to check authorization:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
and where the variable SCOPES is set as:
SCOPES = 'https://www.googleapis.com/auth/drive'
or - it does not change the outcome
SCOPES = ['https://www.googleapis.com/auth/drive']
and the credentials are :
{"installed":{"client_id":"162352680285-0i0fmpq50gqgsm1d796mmdim3c3oe874.apps.googleusercontent.com","project_id":"quickstart-1613196175693","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"REDACTED","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
The program runs into an exception
raise exceptions.RefreshError(error_details, response_body)
google.auth.exceptions.RefreshError: ('invalid_scope: Some requested scopes were invalid.
This is surprising because the program ran error free till recently
Issue:
SCOPES should be a list of scopes, not a string:
scopes (Sequence[str]): The list of scopes to request during the flow.
Solution:
SCOPES = ['https://www.googleapis.com/auth/drive']
Reference:
Flow.from_client_secrets_file
Trying to create a web client that uses oauth to connect to multiple sso endopints, google mainly. This is on top of a spring boot project, I just keep getting the same error that no code is provided, but I'm not sure how i'm supposed to get a code without the access token first. Here is a simple version of what im trying to run I want localhost/8080 to redir to google to login and comeback to the same page or a different one doesn't matter
#RequestMapping("/google")
fun google(#RequestParam(value = "code") code: String?, model: Model): String {
val clientId = "asdf.apps.googleusercontent.com"
val secret = "1234"
var goog = GoogleAuth.create(Vertx.factory.vertx(), clientId, secret)
goog.authenticate(JsonObject().put("code", code), {
System.out.println(it)
})
return "test"
}
the error is always
"error": "invalid_request",
"error_description": "Missing required parameter: code"
}}
e```
but how can I provide a code first I need some sort of response from the server. I'm pretty familiar with restful oauth and must be missing something
You can't use the GoogleAuth like that. GoogleAuth provides the basic primitives to handle the OAuth2 protocol. As you're not using the vertx-web part you will need to setup a callback endpoint in your application (I guess it's the /google endpoint you listed) but now you miss the whole Oauth2 handshake. Your client (browser) should call Google, which calls your server to validate the code.
So what you're asking here is to re-implement the vert.x web Oauth2Handler using Spring Boot APIs.
I'm struggling to retrieve access token using django.
I want to get access token from users using oAuth.
This is what I have setup so far.
class GoogleExhangeViewSet(viewsets.ViewSet):
queryset = User.objects.all()
#list_route(
methods=["GET"])
def auth(self,request,pk=None):
client_id = ''
client_secret = ''
flow = OAuth2WebServerFlow(client_id=client_id,
client_secret=client_secret,
scope='https://www.googleapis.com/auth/calendar',
redirect_uri='http://localhost:8001/api/googleAuth/complete')
auth_uri = flow.step1_get_authorize_url()
return HttpResponseRedirect(auth_uri)
def complete(self, request, pk=None):
client_id = ''
client_secret = ''
host = Site.objects.get_current().name
flow = OAuth2WebServerFlow(client_id=client_id,
client_secret=client_secret,
scope='https://www.googleapis.com/auth/calendar',
redirect_uri='http://localhost')
credentials = flow.step2_exchange(request.GET.get('code'))
return Response(status=200,data=credentials.access_token)
under urls.py I have
api_router.register(r'api/googleAuth', GoogleExhangeViewSet)
This is the error I get with the following code
As seen in your error, you are encountering a redirect_uri_mismatchBad Request if you are using a wrong redirect uri. From this link, the redirect_uri_mismatch will be thrown if it was not matched between auth and token requests.
Additional references:
Google oAuth2 redirect_uri_mismatch in token access
Google OAuth 2.0 redirect_uri_mismatch error
Here's a tutorial if you want to use an Access Token to authenticate users against Django’s authentication system.
You need a fully-functional OAuth2 provider which is able to release access tokens: just follow the steps in the part 1 of the tutorial. To enable OAuth2 token authentication you need a middleware that checks for tokens inside requests and a custom authentication backend which takes care of token verification.
I want to do application(Play 2) to application(Spring) Private API call that is secured by OAuth 1.X. How can I do that in Play 2 framework? Following this example I was able to invoke the service in 3 legged way. What changes I should make to switch to 2 legged way?
I had a similar problem and found Steven Phung's gist on github:
def doRequest(key: String, secret: String) {
val ck = ConsumerKey(key, secret)
val calc = OAuthCalculator(ck, RequestToken("", ""))
calc.setSendEmptyTokens(true)
WS.url(endpoint).sign(calc).get.map(response => {
println(response.json)
})
}
This code snippet assumes that you have empty request token key and secret. If you have a specific token key and secret that you need to provide to calculate the OAuth signature, then you need to provide them as arguments to the constructor of RequestToken.
The classes you need to import can be found in play.api.libs.oauth._.