skip to Main Content

I am building an ASP.NET (v4.8) Web application that will be hosted as an Azure App Service, but for now we are on localhost.

I am configured for Azure AD successfully and I am receiving an authorization code because I configured my app service to send the access token. The app registration has ONLY User.Read (delegated) permissions.

App Registration Settings - Access Tokens

In my Startup.cs file, I’ve configured OpenIdConnectAuthenticationNotifications so that I am receiving the access code in AuthorizationCodeReceived. Here is the code:

public void ConfigureAuth(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType( CookieAuthenticationDefaults.AuthenticationType );
    app.UseCookieAuthentication(new CookieAuthenticationOptions());
        authority = aadInstance + tenantId;
        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions  {
            ClientId = clientId, Authority = authority,
            PostLogoutRedirectUri = postLogoutRedirectUri,
            Notifications = new OpenIdConnectAuthenticationNotifications()
            {
                TokenResponseReceived = (tr) => { return Task.FromResult(0); }, 
                AuthorizationCodeReceived = (code) => {
                    // you are here! what's next?
                    access_code = code.Code;
                    return Task.FromResult(0);
                },
                SecurityTokenReceived = (token) => 
                {
                    return Task.FromResult(0);
                },
                AuthenticationFailed = (context) => { return System.Threading.Tasks.Task.FromResult(0); }
            }
        });
        app.UseStageMarker(PipelineStage.Authenticate);
    }

My objective is to call this graph endpoint as the current user to get their JobTitle and > Department from Azure AD. Here is the resource: https://graph.microsoft.com/v1.0/me

I was following this documentation, but it was not clear what to do with the provided access_code. Please help me understand.

  1. Is this access_code a bearer token? can I use it directly to call the graph API?
  2. Do I have to use it to call the /token endpoint to get a bearer token?
  3. Do I have to use it to call the /authorize endpoint to get a bearer token?
  4. I am making direct HTTP requests now, should I use MSAL or Graph SDK?

I think I am trying to accomplish this step:

enter image description here

This is the code I am currently working on, and it returns HTTP CODE 400 (Bad Request):

private void GetOtherProfileData()
{
    var cId = Startup.clientId;
    var tenantId = Startup.tenantId;
    var scope = Startup.scope;
    // scope: https%3A%2F%2Fgraph.microsoft.com%2Fuser.read
    var code = Startup.access_code;
    var redir = HttpUtility.UrlEncode(Startup.redirectUri);
    var req_url = $@"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token?client_id={cId}&scope={scope}
                        &code={code}&redirect_uri={redir}&grant_type=authorization_code
                        &code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong";
    var req = WebRequest.CreateHttp(req_url);
    req.Method = "POST";
    req.ContentLength = 0;
    req.ContentType = "application/x-www-form-urlencoded";
    var resp = req.GetResponse();
    var str = resp.GetResponseStream();
    var json = new StreamReader(str).ReadToEnd();
    Trace.TraceInformation(json);
    /// this should return bearer token and then we go call the /me endpoint... 
///right?
}

Any code samples or pointers to recent documentation would be helpful.

2

Answers


  1. Chosen as BEST ANSWER

    I found a good sample here: https://github.com/Azure-Samples/ms-identity-aspnet-webapp-openidconnect

    I was trying to do this without a client secret, that was a mistake.

    This is how I implemented it =>

    AuthorizationCodeReceived = async (context) => {
        // you are here!
        IConfidentialClientApplication clientApp = MsalAppBuilder.BuildConfidentialClientApplication();
        AuthenticationResult result = await clientApp.AcquireTokenByAuthorizationCode(new[] { "User.Read" }, context.Code)
                            .WithSpaAuthorizationCode() //Request an authcode for the front end
                            .ExecuteAsync();
                        access_code = result.AccessToken;
                        // this is the bearer token.
                    },
    

    This is what is inside the implementation of BuildConfidentialClientApplication:

    clientapp = ConfidentialClientApplicationBuilder.Create(Startup.clientId)
                .WithClientSecret(Startup.secret)
                .WithRedirectUri(Startup.redirectUri)
                .WithAuthority(new Uri(Startup.authority))
                .Build();
    

  2. Is this access_code a bearer token? can I use it directly to call the graph API?

    No, code and Access_token are different. You will need a access_token to call Graph API.

    Do I have to use it to call the /token endpoint to get a bearer token?

    Yes, you’ll need code to call token endpoint to get the bearer token.

    Do I have to use it to call the /authorize endpoint to get a bearer token?

    You will get the code after calling authorize endpoint. You need to pass grant_type=code to get the code in response.

    I am making direct HTTP requests now, should I use MSAL or Graph SDK?

    You’ll need to call Graph API after you get the access_token. Along with the token it also needs proper dedicated and application User permissions from Azure side.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search