Attempting to GET Google Apps Single Sign-On Signing Key via API - google-provisioning-api

I'm receiving an interesting error from the Google Apps admin settings API when attempting to retrieve the Single Sign-On key for updating (creating) it the first time. We're looking to do this via the API only, but it appears as though the API is making the assumption the signing key has already been created client-side. The following GET request is failing with the error below:
GET https://apps-apis.google.com/a/feeds/domain/2.0/ruby-alphaz.co/sso/signingkey
The response error is as follows:
SimpleXMLElement Object
(
[error] => SimpleXMLElement Object
(
[#attributes] => Array
(
[errorCode] => 1408
[invalidInput] =>
[reason] => InvalidSsoSigningKey
)
)
)
I'm able to update Single Sign-On settings without a problem, but the signing key endpoint is causing problems. To be clear, no signing key currently exists for the domain, but the domain instructions are to attempt to retrieve the XML via the endpoint to ensure it has the proper id parameter set so I can follow up with a subsequent PUT response to create/update the signing key.
The documentation that I'm following as here:
https://developers.google.com/google-apps/admin-settings/#retrieving_the_single_sign-on_signing_key
I know for a fact that my Auth token headers are set properly as they work for other endpoints.
Any ideas?
Update (and Solution)
After conversing with Jay in the comments section of the below answer, it turns out the solution to the problem is as follows:
If you perform a GET request to https://apps-apis.google.com/a/feeds/domain/2.0/{domainName}/sso/signingkey and receive an XML response with the InvalidSsoSigningKey error, first ensure that you have enabled SSO via the https://apps-apis.google.com/a/feeds/domain/2.0/{domainName}/sso/general endpoint.
If you're sure that you've enabled SSO and still receive the InvalidSsoSigningKey error, it is likely because you do not yet have an uploaded signing key. While it isn't readily documented, you may perform a PUT request to https://apps-apis.google.com/a/feeds/domain/2.0/{domainName}/sso/signingkey with the following format to create your signing key:
<?xml version="1.0" encoding="UTF-8"?>
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:apps="http://schemas.google.com/apps/2006">
<apps:property name="signingKey" value="[YOUR_BASE64_ENCODED_CERTIFICATE_VALUE]" />
</atom:entry>
From now on, you should be able to successfully issue GET requests to https://apps-apis.google.com/a/feeds/domain/2.0/{domainName}/sso/signingkey and receive a valid response. Future updates will need to utilize this GET response as it contains the proper id parameter.

I filed an issue about this back in 2009, feel free to star it:
http://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=1527
You need to enable SSO in order to retrieve the key.
And yes, that means you can't check the key matches properly before enabling SSO.
You don't need to do the GET before doing the PUT. Just create the XML manually. See how GAM does it:
http://code.google.com/p/google-apps-manager/source/browse/trunk/gdata/apps/adminsettings/service.py#363

Related

Priority REST API - Generating key for API Access

I am new to Priority and can't seem to find in the docs where I can generate an API key for accessing the REST API. It was my understanding that a user has to have the API license key enabled (which my user does).. But where can I generate the link? Is there any good resource to find this out? I've scoured the docs and while they mention using it I didn't see any mention of how to generate the endpoint to send requests to.
Thanks!
There is a Procedure named "Send Program Activation Link"
(internal name MGLINK) you can run to receive the link.
It usually looks like this:
https://priority.web.url/odata/Priority/tabula.inifile/envCode
The API Username (on USERSB form) and the Priority user's password are
needed for the Authorization header.

oAuth with Azure Active Directory fails due to [AADSTS50012: Invalid client secret is provided]

I'm implementing a webapp that connects to Dynamics365 via webapi. Therefore I'm using Azure Active Directory for oAuth. I'm getting the following error and I'm not sure where is something going wrong. Therefore I'm describing my whole procedure:
"error":"invalid_client",
"error_description":"AADSTS70002: Error validating credentials. AADSTS50012: Invalid client secret is provided.
Trace ID: 2cc92fcd-798b-4636-892d-0c3c397c0401
Correlation ID: f3bd2f4c-05c5-4de8-ace2-acf4b99e6fb9
Timestamp: 2018-09-19 09:43:38Z",
"error_codes":[70002,50012],
"timestamp":"2018-09-19 09:43:38Z",
"trace_id":"2cc92fcd-798b-4636-892d-0c3c397c0401",
"correlation_id":"f3bd2f4c-05c5-4de8-ace2-acf4b99e6fb9"
I'm using these urls including the tenant. I got got them from the Azure Portal / Azure Active Directory / App Registration:
https://login.microsoftonline.com/{tenant}/oauth2/authorize
https://login.microsoftonline.com/{tenant}/oauth2/token
I registered a new app in the App Registration. I used the app ID and created a key that I used as client_secret. Calling the authorize-url is working fine! Then it is redirected to my callback.
Then I'm getting a code that I try to use to get a token. But it returns the error mentioned above. Input for POST-request to /oauth2/token is the following:
grant_type=authorization_code&
client_id={same as for authorize}&
code={returned code from authorize}&
redirect_uri={the callback of my webapp}&
resource={also callback-url}&
client_secret={the key from the keys-section in App Registration}
I'm looking forward to any ideas!
A few things you can try:
As Sunny suggested in the comments, a simple step would be to create a new key in the app registration and try that one.
Make sure that you have the Client Secret in your config or app settings matches exactly what you have in the portal. Also make sure that you don't somehow have duplicate app settings that could be overwriting each other.
From this similar discussion on MSDN:
Go to https://identity.microsoft.com login, and then select your app.
Click on "Generate New Password"
Use that value as the client_secret parameter.

Can BigCommerce Private Apps use OAuth

I am very confused by the BC documentation on their API, because they let you create "Draft Apps" (private apps) and now I see that in their documentation they say "We do not currently provide a means of keeping OAuth apps private.".
My concern here is that they made some changes recently that might have affected a few of my Private Apps that I had running just fine a month ago. If anyone can provide some insight, I would appreciate it greatly!
https://developer.bigcommerce.com/api/guides/oauth-transition
There is nothing wrong with creating oAuth credentials with a "Draft App" for the sole purpose of accessing the API of your store. You do not ever have to publish your app and your app will never be made "public" in that case. You also don't have to bother with the 'Load Callback URL' and filling out the details on your draft app, unless you want to provide yourself an interface in the store.
The "Draft App" function was specifically meant to allow Developers building apps for the BC App Marketplace to test their apps in a store before submission. However, you can use it to make a private application that is only intended for your store - I'm including the process here for others!
Making a Private App with oAuth (or How to Generate oAuth Credentials for a Store)
What you will need
Access to the account listed as the "store owner" of the store where you want to install your app or the ability to get a person with access to complete a couple steps
Ability to setup a local or public URL to receive the 'Auth Callback Request'
Getting started
The first thing you should do is sort out making available a local or public URL that can receive an "Auth Callback" request. This resource must be able to work over an HTTPS connection but the SSL can be self-signed. The 'Auth Callback' request from Bigcommerce is a GET request that will have 3 query parameters on the URL: code, scope, and context.
It is described in greater detail here:
https://developer.bigcommerce.com/api/callback#get-req
Additional info
When building a public app it is important that the service receiving the Auth Callback request be configured to catch the 3 query values and combine them with information you already have. You would then send all of this information in a POST to the BC oAuth Token service to generate your API token for the store. In addition to that you would want to respond to the Auth Callback request with a 200 status and an interface, or instructions, for the user.
In the context of building a private application you don't need to worry about any of that. All you need to do is capture the query values. If you have this already then go ahead and jump down to the section on generating an API token below.
Before Moving On
You should have a URL path that can receive a GET request and captures query parameters. Test it out and make sure it works. Here are a couple example URLs:
https://example.com/auth-callback
https://localhost:8000/auth-service
Registering an App
The key point here is that the registration of the app must be completed by the store owner account of the store where you want to install the app. If you have access to the store owner account credentials then follow the steps at the bottom of this page:
https://developer.bigcommerce.com/api/registration
If you are working with the store owner then you can direct them to complete the steps above. You will need to provide them the Auth Callback URL you created for completing Step 9. The Load Callback URL does have to be filled in but the default example provided can be left in place.
SCOPES
When registering an app you are able to choose the scopes for the app. It is simple to just leave them all open but it is best practice to only enable the scopes you need. Here is a list of the scopes:
https://developer.bigcommerce.com/api/scopes
If you are not sure whether or not you will need a certain scope then leave it enabled because you will have to re-generate your API Token (perform a re-install of the app) if you have to change the scopes on your app.
Before Moving On
You need to have the client_id and client_secret. If someone else registered the app then you will need to ask them for this. There is a View Client ID button that will provide it after registering an app.
Generate the Auth Callback Request
You will need the person with store owner access again for this step. They will need to login to their store and go to the Apps section on the left side column. After that click on Marketplace -> then My Apps (in the top-right) -> then My Draft Apps
You should now see a list containing any "apps" that the store owner has registered. Choose the one relating to the client_id you plan to use. Click to install the app.
The Auth Callback request has now been sent and you are done here. You should expect to see just a blank or grey page as a result unless you are responding to the Auth Callback request with content. Your app is now awaiting authentication.
If using a self-signed certificate
When your Auth Callback URL has a self-signed certificate then you will see a "untrusted cert" error in your browser when you attempt installation of the app. You should choose to trust the certificate and continue.
Before Moving On
You should now have received the code, scope, and context at your Auth Callback URL. If you did not it was likely due to not having SSL/TLS at your server. You can replay the Auth Callback request as many times as needed by Cancelling Installation of the app in the same place where you started it. You can even open up a Dev tool and watch the request happen to see what errors show up in the console. If this is continuing to fail then you should reach out to Bigcommerce support or ask a new question on here!
Generating an API Token to Complete Installation
Follow the steps here:
https://developer.bigcommerce.com/api/callback#post-req
You should have all of the details needed to send a POST request to the BC Auth Token Service at https://login.bigcommerce.com/oauth2/token
Make sure to URL encode your content and you should be good! Here is a site that can URL encode and decode for you: http://meyerweb.com/eric/tools/dencoder/
Just be careful of it encoding & and = signs when those are actually being used as separators between fields or between field/value (respectively).
Before Moving On
You should have received a successful response from the Auth service which will include your API Token. Once you have this you are all set to access the API of the store. You no longer need to have your Auth Callback URL up and available and can take that down.
Also take note of the context to use to create your API path.
Accessing the API
Now that you have your API Token and context you are all set to access the API of a store. Start off with a simple request to the /time endpoint.
Make a GET request and include the following headers (minus the curly braces):
X-Auth-Client: {CLIENT_ID}
X-Auth-Token: {API_TOKEN}
Accept: application/json
Content-Type: application/json
Send your request to a URL path of (minus curly braces):
https://api.bigcommerce.com/{context}/v2/time
If you get back a 200 response then you are all set!
Additional Notes - Ways to Break Credentials
Once you have successfully generated an API Token for a certain app, that app will display in the Control Panel as an icon in the Apps section. The fact the app is there shows it is installed and allowing access. If you uninstall that app then the previously generated API token will stop working.
Changing the scopes on an already installed app will require it to be re-installed to correct the token.
Changing the store owner email on the store will cause the token to stop working. The API Token is specifically tied to the store owner that registered the app.
if you have apps in "My draft apps" and you used basic oauth, you will have to change to Oauth Authentication, but if only have private apps using "legacy api account", you will not need to change.

Azure AD Graph Get Users REST API call fails to return User entity thumbnailPhoto field

I am trying to integrate Windows Azure AD in to iOS application. I was able to do authentication with common consent framework and also able to access list of users in my active directory.
Format of my request,
URL: https://graph.windows.net/mytenantdomain/users?api-version=2013-04-05
, HTTP Method: GET,
HTTP Header: Authorization: Bearer <'access token'>
I am able to receive various other fields associated with users entity but it fails to return thumbnailPhoto field. Is there anything i need to do or its not supported as of now. Any solution to this issue will be helpful.
That is indeed the default behavior. You need to make an additional call to fetch the thumbnailPhoto property.
HTTP GET https://graph.windows.net/<directory_name_or_id>/users/<users_upn_or_objectid>/thumbnailPhoto?api-version=2013-11-08
Hope this helps
I was having this problem. I assumed the picture I was setting in my O365.com profile was the same as the thumbnailPhoto property. After unsuccessfully trying a couple times, I opted to upload a photo using Powershell: Set-AADUserThumbnailPhoto -Id "xxxx-xxxx-xxxx..." -ThumbnailPhotoFilePath "C:\users\me\Desktop\mypicture.jpg". Then it worked.

"Remember this approval" when using dotNetOpenAuth and Google Apps doesn't work as expected

I'm using dotNetOpenAuth to provide SSO to my app via a user's Google Apps account. Besides just simple authentication I also ask Google to return the user's email, first name and last name. When a user first goes in they get redirected to the typical Google Accounts page telling them that the app is asking for this info and do they want to allow it. There is the checkbox there to Remember This Approval. The problem is, the approval isn't being remembered. It does remember them if they go back to the site without closing their browser. But if they close their browser and then open it later and go back in, they are again prompted to allow it.
If I look through my Google account page that shows me connected sites, apps, and services, I see my app listed multiple times. It's like it doesn't recognize that it's the same app and keeps adding it.
I know I must be missing something obvious, but I'm not sure what it is. Any ideas?
Thanks!
You can find my code here
I see several problems in your code. To first answer your direct question, the reason Google doesn't remember you on return visits is because you are passing a random GUID in as part of your Realm each time you log in. The symptom is actually much worse than you realize. It's not just that Google prompts the user on return visits, your site won't recognize the user at all on return visits because Google will give them a new claimed identifier on each visit.
The fix is that you should use the exact same Realm for every login request:
Realm realm = "http://www.yoursite.com/";
var req = openid.CreateRequest(discoveryUri, realm, URIbuilder.Uri );
Or my personal favorite:
var req = openid.CreateRequest(discoveryUri, Realm.AutoDetect, URIbuilder.Uri );
Realm.AutoDetect will work for you unless your site is available both via HTTP and HTTPS, in which case you need to lock it down to just one or the other of these so that Google recognizes your site as always the same.
You must also remember that the returnTo URL that you pass in as the 3rd parameter to CreateRequest must always be based on the realm. So if your realm is HTTPS, so must your returnTo parameter be.
I also want to call out that you seem to have some GUID code and complex URL manipulation around trying to ensure that every OpenID response you accept comes from a request you sent out. I'm not sure why you're trying to do this in the first place, although there certainly can be legitimate reasons. The way you did it is insecure and can be circumvented. I suggest you delete all this code, in favor of adding this to your web.config file:
<dotNetOpenAuth>
<openid>
<relyingParty>
<security rejectUnsolicitedAssertions="true" />
</relyingParty>
</openid>
</dotNetOpenAuth>
The library has support for requiring all responses to come from your requests built in, and it does so securely so that the security exploit I alluded to earlier isn't possible.
But if you're only trying to apply this restriction so that you know it's coming from Google, may I recommend that instead of rejecting unsolicited assertions, you instead check the IAuthenticationResponse.Provider.Uri property when you receive responses and verify that it is coming from the Google OP Endpoint? Then, if Google ever supported sending unsolicited assertions it would work on your site, and ultimately your security gate is exactly where you intended it to be anyway.

Resources