最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

azure - ASP.NET Framework get Graph access token on behalf of user - Stack Overflow

programmeradmin0浏览0评论

I am looking for a solution, where ASP.NET Framework is able to access MS Graph. In every examples that I found, a desktop app is always included (On-behalf-of flows with MSAL.NET).

I do not need/want any desktop app, the ASP.NET Framework should directly trigger Microsoft authentication, to ask the user to approve the scope.

I have came so far to ask for an access token (see code below), which is always rejected with the following message:

'AADSTS65001: The user or administrator has not consented to use the application with 
   ID '00aa00aa-bb11-cc22-dd33-44ee44ee44ee' named 'Auth-1'. 
   Send an interactive authorization request for this user and resource. 
   Trace ID: 00aa00aa-bb11-cc22-dd33-44ee44ee44ee 
   Correlation ID: 00aa00aa-bb11-cc22-dd33-44ee44ee44ee 
   Timestamp: 2025-02-03 09:58:48Z The returned error contains a claims challenge. 
   For additional info on how to handle claims related to multifactor authentication, Conditional Access, and incremental consent, 
   see . 
   If you are using the On-Behalf-Of flow, see  for details.   

I do not understand how to ask the user to confirm the claims which could be found in the exception, and are in the following format:

{
    "access_token": 
    { 
        "capolids":
        { 
            "essential": true,
            "values": [ "00aa00aa-bb11-cc22-dd33-44ee44ee44ee"]
        }
    }
}

directly in ASP.NET Framework.

Any hints are welcome.

Code:

namespace Example
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var authInfo = new AuthInfo
            {
                AuthenticationType = "Auth-1",
                ClientId = "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
                AadInstance = "/",
                Domain = "company.onmicrosoft",
                TenantId = "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
                RedirectUri = "https://localhost:44323/About",
                PostLogoutRedirectUri = "https://localhost:44323/About"
            };

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
                AuthenticationMode = AuthenticationMode.Passive,
                CookiePath = HostingEnvironment.ApplicationVirtualPath,
                CookieHttpOnly = true,
                ExpireTimeSpan = TimeSpan.FromMinutes(5),
            });

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                AuthenticationType = authInfo.AuthenticationType,
                RedirectUri = authInfo.PostLogoutRedirectUri,
                ClientId = authInfo.ClientId,
                Authority = authInfo.Authority,

                RequireHttpsMetadata = false,
                Scope = "openid email profile offline_access user.read",
                SignInAsAuthenticationType = "Cookies",
                RedeemCode = true,
                ResponseType = OpenIdConnectResponseType.CodeIdToken,
                TokenValidationParameters = new TokenValidationParameters
                {
                    // For demo purposes only
                    ValidateIssuer = false
                },
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    AuthorizationCodeReceived = async (notification) =>
                    {

                        var idClient = ConfidentialClientApplicationBuilder.Create(authInfo.ClientId)
                            .WithRedirectUri(authInfo.RedirectUri)
                            .WithClientSecret(authInfo.AppSecret)
                            .WithAuthority(authInfo.Authority)
                            .Build();

                        string[] scopes = new[] { "user.read" };

                        try
                        {
                            AuthenticationResult result = await idClient.AcquireTokenByAuthorizationCode(
                                scopes, notification.Code)
                            .WithTenantId(authInfo.TenantId)
                            .ExecuteAsync();

                            var token = result.AccessToken;
                        }
                        catch (Exception ex)
                        {
                            // Exception always occurs: AADSTS65001: The user or administrator has not consented to use the application
                            throw;
                        }
                    },
                },
            });

            app.UseStageMarker(PipelineStage.Authenticate);
        }
    }
}

API Permission Blade

I am looking for a solution, where ASP.NET Framework is able to access MS Graph. In every examples that I found, a desktop app is always included (On-behalf-of flows with MSAL.NET).

I do not need/want any desktop app, the ASP.NET Framework should directly trigger Microsoft authentication, to ask the user to approve the scope.

I have came so far to ask for an access token (see code below), which is always rejected with the following message:

'AADSTS65001: The user or administrator has not consented to use the application with 
   ID '00aa00aa-bb11-cc22-dd33-44ee44ee44ee' named 'Auth-1'. 
   Send an interactive authorization request for this user and resource. 
   Trace ID: 00aa00aa-bb11-cc22-dd33-44ee44ee44ee 
   Correlation ID: 00aa00aa-bb11-cc22-dd33-44ee44ee44ee 
   Timestamp: 2025-02-03 09:58:48Z The returned error contains a claims challenge. 
   For additional info on how to handle claims related to multifactor authentication, Conditional Access, and incremental consent, 
   see https://aka.ms/msal-conditional-access-claims. 
   If you are using the On-Behalf-Of flow, see https://aka.ms/msal-conditional-access-claims-obo for details.   

I do not understand how to ask the user to confirm the claims which could be found in the exception, and are in the following format:

{
    "access_token": 
    { 
        "capolids":
        { 
            "essential": true,
            "values": [ "00aa00aa-bb11-cc22-dd33-44ee44ee44ee"]
        }
    }
}

directly in ASP.NET Framework.

Any hints are welcome.

Code:

namespace Example
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var authInfo = new AuthInfo
            {
                AuthenticationType = "Auth-1",
                ClientId = "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
                AadInstance = "https://login.microsoftonline/",
                Domain = "company.onmicrosoft",
                TenantId = "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
                RedirectUri = "https://localhost:44323/About",
                PostLogoutRedirectUri = "https://localhost:44323/About"
            };

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
                AuthenticationMode = AuthenticationMode.Passive,
                CookiePath = HostingEnvironment.ApplicationVirtualPath,
                CookieHttpOnly = true,
                ExpireTimeSpan = TimeSpan.FromMinutes(5),
            });

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                AuthenticationType = authInfo.AuthenticationType,
                RedirectUri = authInfo.PostLogoutRedirectUri,
                ClientId = authInfo.ClientId,
                Authority = authInfo.Authority,

                RequireHttpsMetadata = false,
                Scope = "openid email profile offline_access user.read",
                SignInAsAuthenticationType = "Cookies",
                RedeemCode = true,
                ResponseType = OpenIdConnectResponseType.CodeIdToken,
                TokenValidationParameters = new TokenValidationParameters
                {
                    // For demo purposes only
                    ValidateIssuer = false
                },
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    AuthorizationCodeReceived = async (notification) =>
                    {

                        var idClient = ConfidentialClientApplicationBuilder.Create(authInfo.ClientId)
                            .WithRedirectUri(authInfo.RedirectUri)
                            .WithClientSecret(authInfo.AppSecret)
                            .WithAuthority(authInfo.Authority)
                            .Build();

                        string[] scopes = new[] { "user.read" };

                        try
                        {
                            AuthenticationResult result = await idClient.AcquireTokenByAuthorizationCode(
                                scopes, notification.Code)
                            .WithTenantId(authInfo.TenantId)
                            .ExecuteAsync();

                            var token = result.AccessToken;
                        }
                        catch (Exception ex)
                        {
                            // Exception always occurs: AADSTS65001: The user or administrator has not consented to use the application
                            throw;
                        }
                    },
                },
            });

            app.UseStageMarker(PipelineStage.Authenticate);
        }
    }
}

API Permission Blade

Share Improve this question edited Feb 5 at 11:33 Rukmini 16.2k2 gold badges8 silver badges20 bronze badges Recognized by Microsoft Azure Collective asked Feb 3 at 11:36 user16857750user16857750 313 bronze badges 3
  • Can you attach the API permissions blade screenshot? – Rukmini Commented Feb 3 at 11:45
  • Check this nishantrana.me/2020/12/01/… – Rukmini Commented Feb 4 at 5:55
  • Posted the answer, please check the below:) – Rukmini Commented Feb 25 at 11:05
Add a comment  | 

1 Answer 1

Reset to default 0

The error "AADSTS65001: The user or administrator has not consented to use the application" usually occurs if admin consent is not granted to the API permissions.

API app:

ClientApp:

For sample, I generated assertion using below parameters:

https://login.microsoftonline/TenantID/oauth2/v2.0/token

client_id: ClientAppClientID
grant_type: authorization_code
scope: api://XXX/access_as_user
redirect_uri: RedirectURL
code: code
client_secret: ClientAppSecret

To acquire on-behalf-of flow access token to call Microsoft Graph, I used below parameters:

POST https://login.microsoftonline/TenantID/oauth2/v2.0/token

client_id:APIappID
client_secret:APIappSecret
scope: https://graph.microsoft/User.Read
grant_type: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion:<paste_token_from_above_step>
requested_token_use:on_behalf_of

I got the same error:

To resolve the error, you need to grant admin consent to the API permissions granted to application:

You can also make use of admin consent URL:

https://login.microsoftonline/{tenant-id}/adminconsent?client_id={client-id}

After granting the admin consent, I got the access token successfully:

Otherwise, you can allow the user to consent to apps by selecting the below option:

Go to Azure Portal -> Azure Active Directory -> Enterprise applications -> Consent and permissions -> User consent settings

You can also configure known client applications by adding the client ID ClientApp in the APIApp:

发布评论

评论列表(0)

  1. 暂无评论