SpanningCloudApps / SB365-Powershell

Spanning Backup for Office 365 REST API PowerShell Module
https://spanning.com
Apache License 2.0
10 stars 5 forks source link

Auth with token #66

Closed micceo closed 1 year ago

micceo commented 1 year ago

Hi,

What: A powershell script for managing licenses in Spanning through semi-intelligent filtering (group member, disabled account...) from Office 365.

Problem: Auth with token to Spanning. It works for other tenants but not for one of them. Had a support case/request with Spanning and they claim that there is no problem with the instance of the failing tenant at their backup solution.

Module version: 4.4.0.1

Error:

Invoke-WebRequest : {"code":"Unauthorized","message":""}
At C:\prg\dev\SpanningO365\4.4.0.1\Private\Invoke-SpanningRequest.ps1:330 char:20
+ ...  $results = Invoke-WebRequest -uri $request -Headers $headers -Method ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand 

I use the same powershell script for multiple tenants just changing the admin and token for Spanning and the Office 365 credentials.

$token = "cf85****-c5**-49**-a***-7********" # token masked here, but I change this corresponding to the one generated in Spanning
$admin = "admin@'tenant domain'.se" # 'tenant domain' is the real domain name.
$region = "EU"

The working tenant report this with -verbose

PS C:\> $auth = Get-SpanningAuthentication -ApiToken $token -Region $region -AdminEmail $admin -Verbose
VERBOSE: Get-SpanningAuthentication...
VERBOSE: Session ApiToken: 

PS C:\> Get-SpanningTenantInfo -Verbose
VERBOSE: Get-SpanningTenantInfo
VERBOSE: No AuthInfo provided, checking Session State
VERBOSE: Get-AuthInfo
VERBOSE: Get-AuthInfo: AuthInfo is null
VERBOSE: Get-AuthInfo with AuthInfo from SessionState
VERBOSE: Get-AuthInfo with the returns this AuthInfo
VERBOSE: Headers.Authorization: Basic bmVvbW9AemVuZ******************************g4LTcwMGM2ODkxZDFhZA==
VERBOSE: Region EU
VERBOSE: Invoke-SpanningRequest
VERBOSE: Applying TLS 1.2
VERBOSE: Invoke-SpanningRequest Request Type Tenant
VERBOSE: Invoke-SpanningRequest Tenant
VERBOSE: Invoke-SpanningRequest: https://o365-api-eu.spanningbackup.com/external/tenant
VERBOSE: GET https://o365-api-eu.spanningbackup.com/external/tenant with 0-byte payload
VERBOSE: received 59-byte response of content type application/json

licenses users assigned status
-------- ----- -------- ------
     206   550      202 paid

The failing tenant reports this:

The difference start at VERBOSE: GET https://o365-api-eu.spanningbackup.com/external/tenant with 0-byte payload the working tenant follows up with VERBOSE: received 59-byte response of content type application/json, the failing with the error.

PS C:\> $auth = Get-SpanningAuthentication -ApiToken $token -Region $region -AdminEmail $admin -Verbose
VERBOSE: Get-SpanningAuthentication...
VERBOSE: Session ApiToken:  
PS C:\> Get-SpanningTenantInfo -Verbose
VERBOSE: Get-SpanningTenantInfo
VERBOSE: No AuthInfo provided, checking Session State
VERBOSE: Get-AuthInfo
VERBOSE: Get-AuthInfo: AuthInfo is null
VERBOSE: Get-AuthInfo with AuthInfo from SessionState
VERBOSE: Get-AuthInfo with the returns this AuthInfo
VERBOSE: Headers.Authorization: Basic eHNhZG1pbkB4c3ByYXk*********************TExLTRkMTMyZjA0OTU2NA==
VERBOSE: Region EU
VERBOSE: Invoke-SpanningRequest
VERBOSE: Applying TLS 1.2
VERBOSE: Invoke-SpanningRequest Request Type Tenant
VERBOSE: Invoke-SpanningRequest Tenant
VERBOSE: Invoke-SpanningRequest: https://o365-api-eu.spanningbackup.com/external/tenant
VERBOSE: GET https://o365-api-eu.spanningbackup.com/external/tenant with 0-byte payload
Invoke-WebRequest : {"code":"Unauthorized","message":""}
At C:\prg\dev\SpanningO365\4.4.0.1\Private\Invoke-SpanningRequest.ps1:330 char:20
+ ...  $results = Invoke-WebRequest -uri $request -Headers $headers -Method ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

So need help to figure this one out, why one of the auths fails and others don't. To me they are exactly the same. Both accounts has a Spanning license enabled (a difference that Spanning support noticed. But adding a Spanning license to the tenant failing didn't solve anything).

Brgs,

SPMatthewMcD commented 1 year ago

Mikael,

Thanks for contacting us. It looks like you are doing everything right.

Can you try:

  1. Ensure you are logged into the Spanning tenant with a Microsoft Identity.
  2. Revoking and recreating the API key.
  3. Retest your script.

If that fails please send me the user and api key to my company email matt.mcdermott@spanning.com

Also, have you tried out the new Azure AD Group licensing feature? The team just released it and it may reduce the amount of scripting you have to do.

micceo commented 1 year ago

Hi and thanks for the swift response.

Sorry missed that part.

  1. Using a Global Admin account from the Microsoft tenants in all cases.
  2. I've regenerated the API token multiple times and verified it vigorously.
  3. Same-same error sad enough.

Azure AD Group -thingy? No I've missed that. Got a link to educate myself? My spagetti-code forking out what should be removed and added sure needs cleaning up, so maybe this is the way to go.

Mailing away the requested stuff right now.

SPMatthewMcD commented 1 year ago

We are continuing to investigate your tenant, in the mean time, here is the KB on the new Group Based Licensing feature: Azure AD Group Based Licensing

Also, if you are not getting Spanning email, you need to fix that. When you run low on licenses we email you so you don't run out!

micceo commented 1 year ago

Thank you.

I noticed "Spanning DOES NOT automatically unassign licenses even if users are removed from a group or from Microsoft 365 ". My script takes care of removal also, and if not licenses are enough it takes what it can and reports how many missing, so for now I'll use that. But maybe the above will be an option in the future?

I've got email setup alright! Spanning is spamming me with error that it can't backup 0-byte files... 😀

SPMatthewMcD commented 1 year ago

Correct,

As a backup provider we did not want to have automation to remove the license in the event, either through intent, accident, or malicious activity, you remove users from the AD group. The application removes the backups for unlicensed users after 30 days. If you make a mistake and remove users from the group and don't notice for 30 days, you will not be able to restore the user's data.

We decided to err on the side of SAFETY.

Yes, 0 byte files cannot be restored, because there is no data.

micceo commented 1 year ago

Completely understand the decision. But this gives me some motivation to keep struggling with my own solution.

Off topic: Yeah the zero-file is a shortcoming in the API from Microsoft I understand. This is not a problem just would nice if it could be filtered out.

SPMatthewMcD commented 1 year ago

Good point, I'll ping the PM about it.

SPMatthewMcD commented 1 year ago

OK, I think we have this one figured out. There is an issue with creating the API Token if you log into the Spanning tenant from VSA or UniView. Start with a clean browser session and login directly to Spanning Backup as a Global Admin or Spanning Admin. Then generate the API Token.

I'll leave this issue open until you determine that is the solution.

micceo commented 1 year ago

Yes! Signing directly into Spanning with the tenants Global Admin account generates a working API Token. Confirmed.

In my case i used the an Edge profile signed in with the customers GA. Was presented with the dialog for letting Spanning access the tenant and from there went into settings. In Settings it showed that no API Token was generated even though I had created one previously when I logged in through UniView.

SPMatthewMcD commented 1 year ago

Excellent! Thanks Again. Once we update the UI to prevent this confusion I'll contact yo for a field test.