InternalServerError when calling the synchronization API's - azure-active-directory

I'm looking for a way to automate the process of updating admin credentials inside an enterprise app in AAD. Looking at the Microsoft docs e.g. here this should be possible via the graph api. Whenever I attempt these steps I'm running into "InternalServerError" along with "Microsoft.Graph.ServiceException: Code: UnknownError".
My dotnet code for validating existing credentials is the following.
await graphServiceClient.ServicePrincipals[$"{servicePrincipalId}"].Synchronization.Jobs[$"{jobsId}"]
.ValidateCredentials(null,null,null,credentials)
.Request()
.PostAsync();
The result is the error above with the same error for any other synchonization method. I've considered it could be a permissions issue but I've found that the api does a reasonable job of sending permission issues back so I'm stumped at this point.
Does anybody have any advice on this?

I see that you're updated that "The result is the error above with the same error for any other synchronization method". In such scenario, I would do the basic sanity checks
Validate the credentials that
you're using
Make sure the user context has necessary scopes/roles
defined too
Make sure the template and the parameters that you're
is correct.
Once you assigned app role to the user that you're using for delegating permissions, it worked for you.

Related

Logic App how to read secret info for use within a workflow from app settings/some other secure place?

Currently, I'm trying to access Graph API from within a (Standard) Logic App to search for Sharepoint documents. To do so, I try using the following flow (I need delegated permissions, application permissions cannot use search endpoint):
https://techcommunity.microsoft.com/t5/integrations-on-azure-blog/calling-graph-api-from-azure-logic-apps-using-delegated/ba-p/1997666
As one can see in the blog post above, there is a step where the following string gets passed into the body of the first request to get an access token for a delegated user:
grant_type=password&resource=https://graph.microsoft.com&client_id=client_id&username=serviceaccountusername&password=serviceaccountpassword&client_secret=clientsecret
Now the client secret and service account password are two things which I absolutely don't want to have visible in the Logic App code and/or designer screen. Is there a way to securely read these from for instance the 'app settings' (in which I could reference them from a KeyVault)? I really can't find a good way on how to achieve this and I think it's a must to not be able to read these secrets/passwords from the Designer/code view.
Definitely use a KeyVault and make sure that for all steps involved, secure the inputs/outputs where ever that secret information may be visible.
The below example is the call to get the secret and therefore, I only want the outputs to be secured.
Result
With your HTTP call, it's likely that you'll only want the inputs to be secured.
Be sure to use a managed identity on your LogicApp and then assign that managed identity to the KeyVault Secrets User role on the KV itself.
There's plenty of documentation on this topic ...
https://learn.microsoft.com/en-us/azure/logic-apps/create-managed-service-identity?tabs=consumption

Unable to get other users calendar event by using graph API using custom connector in Power Apps

My requirement to show all the calendar events of my wishlisted user in my Canvas App. To access the graph API, I have done App registration in AAD with Calendar.Read and User.Read permission.
Using the Client and Secret received from the registered app, Power Apps Custom Connector is created. While Testing the Custom Connector, I am getting the below error.
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again."
}
}
On Analysis:
Scenario 1 : Calendar.Read - Delegated Permission Type
Api - https://graph.microsoft.com/v1.0/users/{UserID}/events
When Delegated permission is given , I am able to access and response from the calendar event API only when the UserID is mine.
But it is throwing the above mentioned error for other users (This is the actual requirement)
Scenario 2 : Calendar.Read - Application Permission Type
Api - https://graph.microsoft.com/v1.0/users/{UserID}/events
When Application permission is given , it is failing and throwing the same error.
First, Will I be able to get other user's calendar event?
What are the steps to be taken to access?
What permission type should be considered for my scenario?
Am I missing any basic settings?
Please advice. I have lost my time for this requirement.
Thanks in advance
If you where to use Delegates permission (which sounds wrong for the authentication flow you want to use) then to access another users calendar (that you have been delegated rights to either via Outlook or the Mailbox Permissions) you will need (Calendars.Read.Shared or Calendars.ReadWrite.Shared) see https://learn.microsoft.com/en-us/graph/outlook-get-shared-events-calendars
For the client credentials flow https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow which it sounds like what you want to use ? then the Calendar.Read should be enough to access the calendar if your doing anything else in the Directory then User.Read will also need to be an application permission. You probably need to look at https://support.microsoft.com/en-us/topic/verifying-oauth-configuration-for-custom-connectors-d733fdb9-6108-4199-b4f5-06e99b02d10f to do some debugging to see what actually happening with your token generation process, you can the use something like jwt.io to check the correct scopes etc.

Best practices for similar RBAC schemas?

I all, I'm writing a boilerplate for future projects. Composition is as follows:
Server:
Express,
Prisma 2,
Typescript,
JWT Auth (Access token in memory, Refresh in cookie)
MySQL
I'm writing an RBAC schema, and have successfully written express middlewares to determine if a user is logged in, and for if a user has a specific permission on their role.
If you've ever used any of the minecraft server permission plugins, I'm trying to emulate the common pattern used there.
Users have role(s)
Roles have permissions
Roles can inherit permissions from one or more roles
Roles have a "nextRole" field to determine what role to give when the "promote" event is triggered.
Everything works fine on the server side.
What I'm wondering about is, how should I go about copying the middlewares (login, permissions) to the client side, and how should I determine whether a user has permission to do something?
What I've looked at:
Creating a "hasPermission" endpoint wouldn't be very good as I'd need to make an API call every time a permission check is needed.
Eager loading all roles and permissions from the api when logging in and returning them in the response (I can't eager load the recursive role inheritance/nextRole as far as I know)
Returning ONLY the user without roles and permissions for the JWT/login bit and getting roles/permissions from their own endpoints (again, needs to be recursive to get all inheritance and said permissions from inheritance)
Has anyone created an RBAC schema like this, and how did you go about checking permissions on the client side without being too redundant/using too much memory/too many api calls?
This is a good question, here's my answer to it.
An app is normally protected by the auth info, which means it could be blocked if a user is not permitted. If this is a server application, it can be easily done, because the session can be used to find out the current user info including roles.
However if this is a client app, it's a bit tricky. Say we can protect a route (page or section of page) once the user log in.
if (!user.authenticated) return null
We can use the above line to block private or public user. Or other information you can grab from the user to protect more.
if (user.role !== 'Admin') return null
We could wrap in these into a component, such as
<Allow role="admin" render={...} />
I believe you get the point. However there's something which is very unique about the client approach. The entire user info is returned back, and only the user info, not the user type or permission type.
So to follow your plan, do we need to share a permission or role type to the client side? This is a million dollar question.
In practice, the UI never needs the complete info, why? because UI normally reshapes the permission a bit. That doesn't mean you can't share the complete info from the backend. Doing that may make the UI job easy or more complicated. Nobody knows.
The reason is what I explained above, the UI is writing a if statement (could be hidden) anyway. Either this if is true or false, most of the front-end code is already loaded. It's very different than the backend version, which can entirely block the deliver of the content.

Shibboleth custom password flow

I need to set up Shibboleth IdP to validate user name and password against a custom application.
Our application exposes a REST API to which one can pass a user's credentials and either returns a 401 on failure or a JSON object with some user metadata on success.
I was able to achieve this in SimpleSamlPHP IdP with a 30-line class, but having to switch to Shibboleth, I am having a hard time finding directions to do the same there.
Reading through the documentation the suggested solution seems to be to create a custom back end for the password login flow but the Wiki does not explain in detail how to do this.
Can somebody point me out to some tutorials or sample code on which files need to be created or changed in order to do this (even basic examples of checking against a credential file or database would be fine)?
You are looking for an [External Authentication Flow] (https://wiki.shibboleth.net/confluence/display/IDP30/ExternalAuthnConfiguration)
For an example, see the shib-cas-authn3 project (https://github.com/Unicon/shib-cas-authn3). It uses the CAS Server to authenticate the users. It then creates an IdP session from information retrieved from CAS.

What about the Users Python API?

Add me to the list of people confused by all this: https://developers.google.com/accounts/docs/OpenID#openid-connect. I currently use the Python Users API in an AppEngine application running at https://www.stackmonkey.com/. I build the login URL for my login button like this:
login_url = users.create_login_url(federated_identity='gmail.com', dest_url=dest_url)
self.redirect(login_url)
The Users API manages my user DB for me. I'm able to pull the current user's session with this code:
current_user = users.get_current_user()
Given the complete lack of information on the topic anywhere I've looked on Google's pages, I'm wondering if anyone has any information on whether the Users API can be made to work with the suggested migrations, or if Google is going to update the Users API to support the new authentication methods they suggest?
At least I have some time on this, but I'm really not looking forward to reimplementing an entire auth system in my app.
Small update, I've tried creating a sample application running at kordtest2.appspot.com which is returning a 400:
Error: Bad Request
Your client has issued a malformed or illegal request.
The code used for that sample app is cut and pasted from the Python getting started guide on their site (I can't post another link with this account).
I had the same problem, and it appears to be when I was logged into multiple GMAIL/GOOGLE accounts at the same time. When I logged out of all of them except one, that one worked fine with my code, based on the sample Python code.

Resources