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

Integration for Microsoft Azure Login APIs #145

Open
Biztactix-Ryan opened this issue Aug 14, 2022 · 4 comments
Open

Integration for Microsoft Azure Login APIs #145

Biztactix-Ryan opened this issue Aug 14, 2022 · 4 comments

Comments

@Biztactix-Ryan
Copy link

I see you have windows live integration working, which is great, however if you're looking for business registrations not just Personal Microsoft Accounts... then you need Microsoft Azure

I've modelled up the basics for an AzureClient, however I'm repeatedly getting and UnexpectedResponseException,
Seems to be throwing an error at the rest response, I know it's returning a 200 Ok, as I've tested in PostMan.
But keep getting this issue, Usually I'd pull your code base and update, But unfortunately I've run out of time at the moment for this. So I'll come back later, If the owner of the code wants to test it, I can hand you a client ID and Secret to test with.

OAuth2.Client.UnexpectedResponseException: Exception of type 'OAuth2.Client.UnexpectedResponseException' was thrown. at OAuth2.Infrastructure.RestClientExtensions.VerifyResponse(IRestResponse response) in /home/runner/work/OAuth2/OAuth2/OAuth2/Infrastructure/RestClientExtensions.cs:line 16 at OAuth2.Infrastructure.RestClientExtensions.ExecuteAndVerifyAsync(IRestClient client, IRestRequest request, CancellationToken cancellationToken) in /home/runner/work/OAuth2/OAuth2/OAuth2/Infrastructure/RestClientExtensions.cs:line 24 at OAuth2.Client.OAuth2Client.GetUserInfoAsync(CancellationToken cancellationToken) in /home/runner/work/OAuth2/OAuth2/OAuth2/Client/OAuth2Client.cs:line 301 at OAuth2.Client.OAuth2Client.GetUserInfoAsync(NameValueCollection parameters, CancellationToken cancellationToken) in /home/runner/work/OAuth2/OAuth2/OAuth2/Client/OAuth2Client.cs:line 315

Here's my base client, I also included the response fields at the bottom as well.

`public class MicrosoftAzureClient : OAuth2Client
{

    public MicrosoftAzureClient(IRequestFactory factory, IClientConfiguration configuration)
        : base(factory, configuration)
    {
    }
    protected override Endpoint AccessCodeServiceEndpoint
    {
        get
        {
            return new Endpoint
            {
                BaseUri = "https://login.microsoftonline.com",
                Resource = "/common/oauth2/authorize"
            };
        }
    }

    protected override Endpoint AccessTokenServiceEndpoint
    {
        get
        {
            return new Endpoint
            {
                BaseUri = "https://login.microsoftonline.com",
                Resource = "/common/oauth2/token"
            };
        }
    }

    protected override Endpoint UserInfoServiceEndpoint
    {
        get
        {
            return new Endpoint
            {
                BaseUri = "https://graph.microsoft.com/v1.0",
                Resource = "/me"
            };
        }
    }
    protected override void BeforeGetUserInfo(BeforeAfterRequestArgs args)
    {
        args.Request.AddParameter("access_token", AccessToken);
    }
    protected override UserInfo ParseUserInfo(string content)
    {
        var response = JObject.Parse(content);

        var userinfo = new UserInfo
        {
            Id = response["id"].Value<string>(),
            FirstName = response["first_name"].Value<string>(),
            LastName = response["last_name"].Value<string>(),
            Email = response["mail"].Value<string>()

        };

        return userinfo;
    }

    public override string Name
    {
        get { return "MicrosoftOAuth"; }
    }

    public class RetUserInfo
    {
        public string businessPhones { get; set; }
        public string displayName { get; set; }
        public string givenName { get; set; }
        public string jobTitle { get; set; }
        public string mail { get; set; }
        public string mobilePhone { get; set; }
        public string officeLocation { get; set; }
        public string preferredLanguage { get; set; }
        public string surname { get; set; }
        public string userPrincipalName { get; set; }
        public Guid id { get; set; }
    }
}

}`

@justinharrell
Copy link

justinharrell commented Oct 29, 2022

I have this working you need to check the response content from GetUserInfoAsync, there could be various issues and may be reported in there. I am using v2.0 so /common/oauth2/v2.0 instead scope needs to be "openid profile email" and you need to set Bearer token correctly on graph call:

protected override void BeforeGetUserInfo(BeforeAfterRequestArgs args)
{
args.Client.Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(AccessToken, "Bearer");
}

my parse user info looks like this:

	protected override UserInfo ParseUserInfo(string content)
	{
		var response = JObject.Parse(content);

		var userinfo = new UserInfo
		{
			Id = response["userPrincipalName"].Value<string>(),
			FirstName = response["givenName"].Value<string>(),
			LastName = response["surname"].Value<string>(),
			Email = response["mail"].Value<string>()
		};

		return userinfo;
	}

@niemyjski
Copy link
Collaborator

niemyjski commented Oct 30, 2022

@justinharrell would you mind providing a pr and also update the readme? Do you think we need extra configuration for this specific configuration, or this should be the default?

@justinharrell
Copy link

I have forked the codebase signficantly at this point removing the RestSharp dependency going to just HttpClient since very little of RestSharp is being used so a PR wouldn't make sense.

I would say going with V2 is probably the way to go, you could have two different clients if you want for v1 vs v2. One thing that probably does need configuration is the tenant ID which replaces the /common/ in the url otherwise you need to make your app registration multi tenant on the Azure side for it to accept common. The configuration is sort of rigid since it's a separate class, I added tenant ID as a property of the client I would do the same for version since they only make sense for this client.

@niemyjski
Copy link
Collaborator

@justinharrell We would be open to a pr that removes rest sharp :).

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

No branches or pull requests

3 participants