Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Targeting NET Standard #30

Open
snobu opened this issue Feb 9, 2017 · 11 comments
Open

Targeting NET Standard #30

snobu opened this issue Feb 9, 2017 · 11 comments

Comments

@snobu
Copy link
Contributor

snobu commented Feb 9, 2017

Judging by the output of ApiPort it may or may not be a big effort to target NET Standard instead of full NET Framework :)

Given ARMClient is such a handy thing to have around i wonder if we could port this over so it runs on NET Core cross-plat.

image

Currently it doesn't seem to work on Mono - complains about missing Windows Forms when trying to authenticate. Although it MIGHT work if you manage to produce the token cache some other way.

Just a thought..

@snobu snobu added the question label Feb 9, 2017
@davidebbo
Copy link
Member

Yes, would be great to have it work on Core. For auth, I think we'd need to switch to a model like what xplat CLI is doing. It gives you some code that you have to paste in a browser page, and then auth continues without needed to ever pop up UI. It's just too hard to pop up a browser window in a portable way.

Here is what it looks like with cli, though I don't know about implementation:

info:    Executing command login
info:    To sign in, use a web browser to open the page https://aka.ms/devicelogin and enter the code EKCCKBJ6D to authenticate.

@snobu
Copy link
Contributor Author

snobu commented Feb 10, 2017

I saw that in the Mac PowerShell and az as well, so it must be coming from ADAL. I'll do some detective work since PowerShell is now open. This magic must be revealed.

@snobu
Copy link
Contributor Author

snobu commented Feb 10, 2017

Alright, so it's called OAuth 2.0 Device Flow Grant, it's in ADAL and it goes like this:

https://github.com/Azure-Samples/active-directory-dotnet-deviceprofile/blob/master/DirSearcherClient/Program.cs#L205-L209

DeviceCodeResult codeResult = ctx.AcquireDeviceCodeAsync(resource, clientId).Result;
Console.WriteLine("You need to sign in.");
Console.WriteLine("Message: " + codeResult.Message + "\n");
result = ctx.AcquireTokenByDeviceCodeAsync(codeResult).Result;

Result:

image

So it's definitely doable. I'll take a shot at adding it to ARMClient (unless you guys want to do it - i'm finding it difficult to commit time lately).

Vittorio's blog post on ADAL 3.x and Device Flow here:
http://www.cloudidentity.com/blog/2015/12/02/new-adal-3-x-previewdevice-profile-linux-and-os-x-sample/

@davidebbo
Copy link
Member

Ha yes, now that I hear 'device flow', that rings a bell from some thread I was on when they were coming up with it for xplat CLI. If you can make it work here, that's awesome.

And hopefully that's the only thing preventing it from using Core (or Mono). The rest should be very portal http request logic.

@snobu
Copy link
Contributor Author

snobu commented Feb 16, 2017

Well, Device Flow login now works (build this branch) but i broke the X509 cert auth in the process and i'm not sure how to get out of this one:
image

C:\lab\armclient\bin\Debug>armclient devicelogin
Using OAuth 2.0 Device Flow
You need to sign in.
Message: To sign in, use a web browser to open the page https://aka.ms/devicelogin and
enter the code DY2RRGXVN to authenticate.

Got Bearer token from Device Flow: eyJ0eXAiOiJKV1QiLCJh..
User: [email protected], Tenant: xxxxxxxxxxxxxxxx (microsoft.onmicrosoft.com)
        There are 3 subscriptions
        Subscription 6xxxxxxxxxxxxxxxx (yyyyyyyyyy)
        Subscription axxxxxxxxxxxxx (zzzzzzzzzzzzzzzz)
        Subscription bxxxxxxxxxxxxxxx (qqqqqqqqqqqqqq)

User: [email protected], Tenant: xxxxxxxxxxxxxxxxxxxx (swearjarbank.onmicrosoft.com)
        There are 0 subscriptions


C:\lab\armclient\bin\Debug>armclient get %testurl%
{
  "id": "/subscriptions/axxxx-xxxx-xxxxx-xxxxxx/resourceGroups/securitywhat",
  "name": "securitywhat",
  "location": "eastus",
  "properties": {
    "provisioningState": "Succeeded"
  }
}

C:\lab\armclient\bin\Debug>armclient listcache
User: [email protected], Tenant: xxxxx-xxxxx-xxxxxx-xxxxxx (microsoft.onmicrosoft.com)
        There are 3 subscriptions
        Subscription xxxxxxxx
        Subscription yyyyyyy
        Subscription zzzzzzzz

User: [email protected], Tenant: xxxx-xxxx-xxxx-xxxx (swearjarbank.onmicrosoft.com)
        There are 0 subscriptions

Not sure about:

  • Token store and refresh tokens, since ADAL 3.0 no longer exposes refresh tokens. Seems the token gets stored correctly in %userprofile%\.arm, but will it work in 1 hour? Didn't test.
  • I'm using common here as tenant, am i doing it right? The token seems to be fine.
  • There's no more context.AcquireTokenByRefreshTokenAsync() - so do we just do this instead?

I'm still fixing and testing but would value your input here @davidebbo @ahmelsayed

@snobu
Copy link
Contributor Author

snobu commented Feb 17, 2017

Looks like i broke the token refresh mechanism.
This is what happens after >1h from devicelogin:

C:\lab\armclient\bin\Debug>armclient get "https://management.azure.com/subscriptions/x-x-x-x/resourceGroups/?api-version=2014-04-01"

The method or operation is not implemented.

Which i believe is this line here.

Well, back to the drawing board.

back

@davidebbo
Copy link
Member

Presumably, the xplat CLI is able to continue to work after one hour? Sorry, I'm not very familiar with the refresh mechanism.

@snobu
Copy link
Contributor Author

snobu commented Feb 21, 2017

Yes it is. I suspect i'm not saving the correct thing to offline cache with ADAL 3. I'll figure it out.

@fawohlsc
Copy link

Any plans to make armclient cross-platform by porting to .NET Core? Would be handy to have it in Cloud Shell, Linux and Mac.

@snobu
Copy link
Contributor Author

snobu commented Mar 18, 2021

I believe this effort is now abandoned in favor of Azure CLI's az rest which is cross-platform from birth.

Example -

~ $ az rest --help

Command
    az rest : Invoke a custom request.
        This command automatically authenticates using the logged-in credential: If Authorization
        header is not set, it attaches header `Authorization: Bearer <token>`, where `<token>` is
        retrieved from AAD. The target resource of the token is derived from --url if --url starts
        with an endpoint from `az cloud show --query endpoints`. You may also use --resource for a
        custom resource.
        If Content-Type header is not set and --body is a valid JSON string, Content-Type header
        will default to application/json.
$ az rest --method get --url https://management.azure.com/subscriptions/<SUBSCRIPTION_ID>?api-version=2021-01-01

{
  "authorizationSource": "Legacy",
  "displayName": "xx",
  "id": "/subscriptions/xxxxxxxx",
  "managedByTenants": [
    {
      "tenantId": "xxxxxxx"
    },
    {
      "tenantId": "xxxxxxx"
    }
  ],
  "state": "Enabled",
  [...]

@fawohlsc
Copy link

Thanks @snobu!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants