cancel
Showing results for 
Search instead for 
Did you mean: 

Multitenant Authentication of UAA Admin APIs

bmcdonn2
Participant

Hello Everyone,

I'm trying to make use of the SAP Authorization and Trust Management APIs in a multitenant context. My primary goal is to make use of these APIs within the context of a subscribed tenant subaccount to automate the setup of default role collections and ideally the Identity Provider.

The issue I'm having is related to establishing authentication in the tenant context. These instructions, Access UAA Admin APIs, demonstrate how to access the API for a specific subaccount that has CF enabled. The enablement of CF is important because the documentation states that a new instance of the xsuaa service with plan apiaccess is required. This service instance allows you to generate a service key with the credentials necessary to establish authentication to the relevant APIs.

As a general pattern in multitenant apps though, you only have CF enabled in the provider subaccount where all tenant subscriber subaccounts left CF inactive. I've discovered that it is possible to create service instances of xsuaa in non-CF accounts but the plan apiaccess is inaccessible so this a dead alley.

Given the limitations I've run into, I believe this needs to be controlled entirely by the service instance in the provider account. To do this, I tried to make this service instance available via the getDependencies mechanism, as described here Understanding Dependencies in SaaS Provisioning. This approach has suited me well for other shared services like destinations and themes so I thought this might work.

Unfortunately, even after adjusting the dependencies I was still getting failures. The specific mechanism this usually works is that in the credentials you get from the service key, you simply swap the tenant subdomain for your main subdomain.

So, if the service key looks like this:

{
 "apiurl": "https://api.authentication.eu10.hana.ondemand.com",
 "clientid": "aa-bb-cccc11c1-d222-333e-44f4-g5g55ggg555g!a6666",
 "clientsecret": "aA1B2CcCCC3dDd+ee444fFF5ggG=",
 "identityzone": "my-subdomain",
 "identityzoneid": "a11aaaa1-22b2-33c3-dd44-5555f5555f55",
 "sburl": "https://internal-xsuaa.authentication.eu10.hana.ondemand.com",
 "tenantid": "a11aaaa1-22b2-33c3-dd44-5555f5555f55",
 "tenantmode": "dedicated",
 "uaadomain": "authentication.eu10.hana.ondemand.com",
 "url": "https://my-subdomain.authentication.eu10.hana.ondemand.com",
 "verificationkey": "-----BEGIN PUBLIC KEY-----sadklfjdsaflja
	...-----END PUBLIC KEY-----",
 "xsappname": "aa-bbbb11b1-c222-333d-44e4-f5f55fff555f!a6666"
}

Instead of getting your token here: https://my-subdomain.authentication.eu10.hana.ondemand.com/oauth/token

To get it in a tenant context you'd get it here: https://my-tenant-subdomain.authentication.eu10.hana.ondemand.com/ouath/token

What I'm seeing so far is the normal token retrieval works fine but the tenant specific one fails, even after doing the changes via getDependencies.

Does anyone know if what I'm trying to achieve is even possible and if so, how can it be achieved? I appreciate all responses. We also recently received access to Feature Set B so I'm not sure if that's relevant to this question or not.

Thanks,

Brian

bmcdonn2
Participant

FYI I filed an incident inquiring about the availability of such functionality and was told that multi-tenant support does not currently exist but is planned.

former_member801915
Discoverer
0 Kudos

Hi Brian,
Hope you doing well !
Any luck finding the multitenant support for the issue you had posted?
We have similar requirement of populating the list of Users from each tenant with specific role.

Would be great if you could share whatever you know about it.

Thanks,

Puja

bmcdonn2
Participant

Puja,

Thanks for the response.

As far as I know, this type of functionality is still not available. I did a quick check just now and the apiaccess plan is still unavailable for non-CF accounts. Similarly, I reviewed the incident I filed last year and the last communication I received from SAP was that this type of feature would be added to the roadmap but I can't find anything resembling it on the roadmap either Security Roadmap.

Given your affiliation with SAP, you may have greater luck getting answers on this than me though. If you do, I encourage you to share them here if you're able to!

Despite this lack of official support, I was able inspect the underlying calls that occur when interacting with roles in the cockpit through a browser and hack together a script that helps me automate much of these tasks. Given that I'm using an unpublished API and manually inputting required header params into each request, it's not a solution I would advise.

I only pursued this approach because I was under time pressure to update dozens of role collection to IAS group mappings across hundreds of subaccounts. To give a sense of how much using this unpublished API helped, it originally took 3-5 minutes to update all the roles in a given subaccount and with the script it only took a few seconds. This really demonstrates how much of a need there is for this API and how disappointing it is that SAP does not provide anything official.

Anyway, I wish you luck in solving your problem given these limitations!

Thanks,

Brian

Accepted Solutions (0)

Answers (1)

Answers (1)

alperdedeoglu
Product and Topic Expert
Product and Topic Expert
0 Kudos

XSUAA service instance with service plan api-access is currently only valid for the subaccount its created, therefore currently you can not make a token exchange across tenant subaccounts with returning that instance as a dependency.

Let us approach the problem from a different angle.

In general you need following scopes:

  • xs.authorization.read
  • xs.authorization.write
  • xs.idp.read
  • xs.idp.write
  • xs.user.read
  • xs.user.write

Since you have a multitenant application I assume you already have an XSUAA Instance with application plan with tenant-mode shared option.

You can put that scopes into your xs-security.json file as foreign-scope-references.

In addition to that, when you put that scopes into a role collection in your xs-security.json file, you can assign that role collection to a user from tenant subaccount, after that user will have these scopes. Which means when that user logges in to your multitenant application, the user token will contain this scopes, therefore you can directly call the XSUAA API's with that users token.

Please see the example xs-security.json file below:

{
    "xsappname": "mycoolxsappname",
    "tenant-mode": "shared",
    "foreign-scope-references": [
        "xs_authorization.read",
        "xs_authorization.write",
        "xs_user.read",
        "xs_user.write",
        "xs_idp.read",
        "xs_idp.write"
    ],
    "scopes": [
        {
            "name": "$XSAPPNAME.mtcallback",
            "description": "SaaS Provisioning",
            "grant-as-authority-to-apps": [
                "$XSAPPNAME(application,sap-provisioning,tenant-onboarding)"
            ]
        },
        {
            "name": "$XSAPPNAME.mtdeployment",
            "description": "SaaS Model Upgrade"
        },
        {
            "name": "$XSAPPNAME.MtxDiagnose",
            "description": "SaaS Diagnose"
        },
        {
            "name": "uaa.user",
            "description": "UAA"
        },
        {
            "name": "$XSAPPNAME.Viewer",
            "description": "Viewer"
        },
        {
            "name": "$XSAPPNAME.Admin",
            "description": "Administrator"
        },
        {
            "name": "$XSAPPNAME.ExtendCDS",
            "description": "Create Extensions"
        },
        {
            "name": "$XSAPPNAME.ExtendCDSdelete",
            "description": "Delete Extensions"
        }
    ],
    "role-templates": [
        {
            "name": "Token_Exchange",
            "description": "UAA Token Exchange",
            "scope-references": [
                "uaa.user"
            ]
        },
        {
            "name": "Viewer",
            "description": "Viewer",
            "scope-references": [
                "$XSAPPNAME.Viewer"
            ]
        },
        {
            "name": "Admin",
            "description": "Administrator",
            "scope-references": [
                "$XSAPPNAME.Admin",
                "xs_authorization.read",
                "xs_authorization.write",
                "xs_user.read",
                "xs_user.write",
                "xs_idp.read",
                "xs_idp.write"
            ]
        },
        {
            "name": "SaaSAdmin",
            "description": "SaaS Administrator",
            "scope-references": [
                "$XSAPPNAME.mtcallback",
                "$XSAPPNAME.mtdeployment",
                "$XSAPPNAME.MtxDiagnose"
            ]
        },
        {
            "name": "ExtendCDS",
            "description": "Extension Developer",
            "scope-references": [
                "$XSAPPNAME.ExtendCDS"
            ]
        },
        {
            "name": "ExtendCDSdelete",
            "description": "Extension Developer - Delete",
            "scope-references": [
                "$XSAPPNAME.ExtendCDSdelete"
            ]
        },
        {
            "name": "MyCoolUserManagementAdmin",
            "description": "Manage authorizations, trusted identity providers, and users.",
            "default-role-name": "User and Role Administrator",
            "scope-references": [
                "xs_authorization.read",
                "xs_authorization.write",
                "xs_user.read",
                "xs_user.write",
                "xs_idp.read",
                "xs_idp.write"
            ]
        },
        {
            "name": "UserManagementAuditor",
            "description": "Read-only access for authorizations, trusted identity providers, and users.",
            "default-role-name": "User and Role Auditor",
            "scope-references": [
                "xs_authorization.read",
                "xs_user.read",
                "xs_idp.read"
            ]
        }
    ],
    "role-collections": [
        {
            "name": "My Super Admin",
            "description": "Administrator Access",
            "role-template-references": [
                "$XSAPPNAME.Admin",
                "$XSAPPNAME.SaaSAdmin",
                "$XSAPPNAME.MyCoolUserManagementAdmin",
                "$XSAPPNAME.Token_Exchange"
            ]
        }
    ],
    "authorities": [
        "$XSAPPNAME.mtcallback",
        "$XSAPPNAME.mtdeployment",
        "$XSAPPNAME.MtxDiagnose"
    ],
    "oauth2-configuration": {
        "token-validity": 3600,
        "redirect-uris": [
            "http://localhost:5000",
            "http*://*.cfapps.us10.hana.ondemand.com/**",
            "http*://*.cfapps.eu10.hana.ondemand.com/**"
        ]
    }
}

As you can see above, we first have written down the foreign scopes, then we put the scopes into the MyCoolUserManagementAdmin role, then we referred that role in My Super Admin role collection. ( Other sections from example just there but not relevant for this case. )

You might already know that when you subscribe from a tenant subaccount, the role collections will be automatically generated in tenant subaccount.

After you modified your xs-security.json as given example, following steps should help:

  1. Assign the role which has the scopes to a user from tenant subaccount.
  2. Login to your application with the user from tenant subaccount
  3. Call a custom action or API from your application and get the logged in user token
  4. Put the logged in user token as bearer token and call the XSUAA API.

Very Important Warning: The user you gave this role will be really powerful. That user can assign or remove any role on that tenant subaccount to any user, can also remove and create any user as shadow user etc.

If you do not want this behaviour, you need to control it on the application level and the responsibility of limiting this authorization is also %100 on the application side.

Let me know if this helps.

bmcdonn2
Participant
0 Kudos

Alper,

Appreciate the advice on this. I'll take a look and see if I can get this working as a proof of concept on my end.

Thanks,

Brian