在用户使用 Azure AD 登录应用程序后,我们尝试使用 Microsoft Graph API for Teams。用户应该能够向应用程序内的 Teams 频道发送消息。我尝试获取登录用户的 access_token 并将其作为不记名令牌传递给图形 API,但确实失败并抛出错误:
无效受众。
下面是我的代码
public void ConfigureAuth(IAppBuilder app)
{
app.UseSwaggerUi3(typeof(CoreErrorController).Assembly,settings=> { settings.GeneratorSettings.Title = "Sample API"; });
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
CookieName = "azureADCookie",
ExpireTimeSpan = TimeSpan.FromMinutes(60)
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions()
{
ClientId = clientId,
Authority = authority,
Scope = OpenIdConnectScope.OpenIdProfile,
Resource = clientId,
ResponseType = OpenIdConnectResponseType.IdTokenToken,
SaveTokens = true,
RedeemCode = true,
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = false
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = (o) =>
{
o.ProtocolMessage.RedirectUri = DetermineRedirectUri(o.Request).ToLower();
return Task.CompletedTask;
},
AuthorizationCodeReceived = (o) =>
{
o.TokenEndpointRequest.RedirectUri = DetermineRedirectUri(o.Request).ToLower();
return Task.CompletedTask;
},
AuthenticationFailed = OnAuthenticationFailed
}
});
}
获取access_token,
HttpContext.Current.GetOwinContext().Authentication.AuthenticateAsync("Cookies").GetAwaiter().GetResult().Properties.Dictionary["access_token"]
我遇到了这个博客,并相应地更改了我的代码,将范围设置为离线访问,将响应类型设置为代码。现在我收到错误:
为“单页应用程序”客户端类型发行的令牌只能 通过跨域请求进行兑换。
public void ConfigureAuth(IAppBuilder app)
{
app.UseSwaggerUi3(typeof(CoreErrorController).Assembly,settings=> { settings.GeneratorSettings.Title = "Sample API"; });
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
CookieName = "azureADCookie",
ExpireTimeSpan = TimeSpan.FromMinutes(60)
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions()
{
ClientId = clientId,
Authority = authority,
Scope = OpenIdConnectScope.OfflineAccess,
Resource = clientId,
ResponseType = OpenIdConnectResponseType.Code,
SaveTokens = true,
RedeemCode = true,
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = false
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = (o) =>
{
o.ProtocolMessage.RedirectUri = DetermineRedirectUri(o.Request).ToLower();
return Task.CompletedTask;
},
AuthorizationCodeReceived = (o) =>
{
o.TokenEndpointRequest.RedirectUri = DetermineRedirectUri(o.Request).ToLower();
return Task.CompletedTask;
},
AuthenticationFailed = OnAuthenticationFailed
}
}
);
}
以下是我在 Azure AD 应用程序注册中的应用程序设置。我已授予团队、频道和消息的应用程序权限。我应该提供委托权限以使 access_token 工作吗?如果是,应该给予什么权限?
我完全困惑我需要更改哪些配置才能使其工作。任何帮助将不胜感激。
注意:我同意@Ermiya Eskandary,要在用户使用Azure AD登录到应用程序后向Teams频道发送消息,您必须授予
委托API权限。ChannelMessage.Send
我创建了一个 Azure AD 应用程序并授予了 API 权限:
为了授权用户,我使用了以下端点:
https://login.microsoftonline.com/TenantID/oauth2/v2.0/authorize?
&client_id=ClientID
&response_type=code
&redirect_uri=https://jwt.ms
&response_mode=query
&scope=ChannelMessage.Send
&state=12345
通过Postman使用以下参数生成访问令牌:
https://login.microsoftonline.com/TenantID/oauth2/v2.0/token
client_id:ClientID
scope:ChannelMessage.Send offline_access openid
grant_type:authorization_code
redirect_uri:https://jwt.ms
client_secret:ClientSecret
code:code
使用上述访问令牌,我能够成功向 Teams 频道发送消息,如下所示:
POST https://graph.microsoft.com/v1.0/teams/TeamID/channels/ChannelID/messages
Content-type: application/json
{
"body": {
"content": "Test Message"
}
}
通过将 scope 传递为
ChannelMessage.Send
来修改代码以获得结果。
如果您使用 SPA 身份验证且未传递源标头,通常会出现错误“为‘单页应用程序’客户端类型颁发的令牌只能通过跨源请求兑换”。
如果您希望应用程序作为 SPA,请参考我的这个 SO Thread 进行 SPA 身份验证。
否则,要解决该错误,请将重定向 URL 配置为 WEB:
参考:
为“单页应用程序”客户端类型发行的令牌只能通过跨域请求进行兑换 - Stack Overflow by user2096577