[英]Scope claim is null when requesting web api from Angular 4 SPA
I am trying to protect my web api using Azure B2C AD and consume the web api using an Angular 4 SPA. 我正在尝试使用Azure B2C AD保护我的Web api,并使用Angular 4 SPA使用该Web api。 However, for some reason the scope claim is always null even though other claims are working just fine.
但是,由于某些原因,即使其他声明工作得很好,范围声明也始终为空。
I am using the MSAL library version 0.1.6 in the Angular app and have been following this guide: https://github.com/Azure-Samples/active-directory-b2c-javascript-angular2.4-spa 我在Angular应用中使用的MSAL库版本为0.1.6,并且一直在遵循此指南: https : //github.com/Azure-Samples/active-directory-b2c-javascript-angular2.4-spa
This is my web api startup.auth: 这是我的网络api startup.auth:
public partial class Startup
{
// These values are pulled from web.config
public static string AadInstance = ConfigurationManager.AppSettings["ida:AadInstance"];
public static string Tenant = ConfigurationManager.AppSettings["ida:Tenant"];
public static string ClientId = ConfigurationManager.AppSettings["ida:ClientId"];
public static string SignUpSignInPolicy = ConfigurationManager.AppSettings["ida:SignUpSignInPolicyId"];
public static string DefaultPolicy = SignUpSignInPolicy;
/*
* Configure the authorization OWIN middleware.
*/
public void ConfigureAuth(IAppBuilder app)
{
TokenValidationParameters tvps = new TokenValidationParameters
{
// Accept only those tokens where the audience of the token is equal to the client ID of this app
ValidAudience = ClientId,
AuthenticationType = Startup.DefaultPolicy
};
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
// This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(String.Format(AadInstance, Tenant, DefaultPolicy))),
});
}
}
This is my controller: 这是我的控制器:
[Authorize]
[EnableCors(origins: "*", headers: "*", methods: "*")] // tune to your needs
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
string owner = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
var scopes = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/scope");
return new string[] {"value1", "value2"};
}
}
The owner variable contains a GUID as expected, however the scopes variable is always NULL. owner变量包含预期的GUID,但是scope变量始终为NULL。
This is my auth.service.ts: 这是我的auth.service.ts:
import { Injectable } from '@angular/core';
import environment from '../../../environments/environment';
import * as Msal from 'msal'
declare var bootbox: any;
// declare var Msal:any;
const B2CTodoAccessTokenKey = "b2c.api.access.token";
const tenantConfig = {
tenant: environment.b2cTenant,
clientID: environment.b2cClientID,
signUpSignInPolicy: environment.b2cSignUpSignInPolicy,
b2cScopes: environment.b2cScopes
};
@Injectable()
export class AuthService {
// Configure the authority for Azure AD B2C
private authority = "https://login.microsoftonline.com/tfp/" + tenantConfig.tenant + "/" + tenantConfig.signUpSignInPolicy;
private loggerCallback(logLevel, message, piiLoggingEnabled) {
console.log(message);
}
private logger = new Msal.Logger(this.loggerCallback, { level: Msal.LogLevel.Verbose });
clientApplication = new Msal.UserAgentApplication(
tenantConfig.clientID,
this.authority,
function(errorDesc: any, token: any, error: any, tokenType: any) {
console.log('calling acquireTokenSilent with scopes: ' + tenantConfig.b2cScopes);
console.log('idtoken: ' + token)
if (token) {
this.acquireTokenSilent(tenantConfig.b2cScopes).then(function (accessToken) {
// Change button to Sign Out
console.log('acquireTokenSilent');
sessionStorage.setItem("b2c.api.access.token", accessToken);
}, function (error) {
console.log(error);
this.acquireTokenPopup(tenantConfig.b2cScopes).then(function (accessToken) {
console.log('acquireTokenPopup');
sessionStorage.setItem("b2c.api.access.token", accessToken);
}, function (error) {
console.log(error);
});
});
}
else if (errorDesc || error) {
console.log(error + ':' + errorDesc);
}
},
{
logger: this.logger,
});
loginRedirect(): void {
console.log('scopes: ' + tenantConfig.b2cScopes);
this.clientApplication.loginRedirect(tenantConfig.b2cScopes);
}
login() : void {
var _this = this;
this.clientApplication.loginPopup(tenantConfig.b2cScopes).then(function (idToken: any) {
_this.clientApplication.acquireTokenSilent(tenantConfig.b2cScopes).then(
function (accessToken: any) {
_this.saveAccessTokenToCache(accessToken);
}, function (error: any) {
_this.clientApplication.acquireTokenPopup(tenantConfig.b2cScopes).then(
function (accessToken: any) {
_this.saveAccessTokenToCache(accessToken);
}, function (error: any) {
//bootbox.alert("Error acquiring the popup:\n" + error);
console.log("Error acquiring the popup:\n" + error)
});
})
}, function (error: any) {
//bootbox.alert("Error during login:\n" + error);
console.log("Error during login:\n" + error);
});
}
getTokenFromCache() : string {
return sessionStorage.getItem(B2CTodoAccessTokenKey);
}
saveAccessTokenToCache(accessToken: string): void {
sessionStorage.setItem(B2CTodoAccessTokenKey, accessToken);
}
logout(): void{
this.clientApplication.logout();
}
isLoggedIn(): boolean {
var user = this.clientApplication.getUser();
console.log('isLogged In: ' + (user != null));
console.log('token in cache ' + (this.getTokenFromCache() != null))
//console.log('token: ' + this.getTokenFromCache());
return this.clientApplication.getUser() != null && this.getTokenFromCache() != null;
}
}
Finally, this is my environment values: 最后,这是我的环境价值观:
export default {
b2cTenant: "[tenant].onmicrosoft.com",
b2cClientID: '[app-id]',
b2cSignUpSignInPolicy: "[policy]",
b2cScopes: ["https://[tenant].onmicrosoft.com/apidemo/read", "https://[tenant].onmicrosoft.com/apidemo/user_impersonation"]
};
Here is pictures of the Azure setup: 这是Azure安装程序的图片:
API published scopes: API发布范围:
Why is the value of the scopes variable NULL? 为什么范围变量的值为NULL? What did I miss?
我错过了什么? The owner variable contains a value!
owner变量包含一个值!
Best regards 最好的祝福
Try running fiddler to see what is going on. 尝试运行提琴手,看看发生了什么。
Please see if this issue is relevant to you. 请查看此问题是否与您有关。
Solved it by using a different client library: https://github.com/damienbod/angular-auth-oidc-client 通过使用其他客户端库解决了它: https : //github.com/damienbod/angular-auth-oidc-client
In case anyone posts a solution, using the MSAL library, I will ofcourse mark it as the solution 万一有人使用MSAL库发布解决方案,我当然会将其标记为解决方案
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.