[英]Scope claim is null when requesting web api from Angular 4 SPA
我正在嘗試使用Azure B2C AD保護我的Web api,並使用Angular 4 SPA使用該Web api。 但是,由於某些原因,即使其他聲明工作得很好,范圍聲明也始終為空。
我在Angular應用中使用的MSAL庫版本為0.1.6,並且一直在遵循此指南: https : //github.com/Azure-Samples/active-directory-b2c-javascript-angular2.4-spa
這是我的網絡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))),
});
}
}
這是我的控制器:
[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"};
}
}
owner變量包含預期的GUID,但是scope變量始終為NULL。
這是我的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;
}
}
最后,這是我的環境價值觀:
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"]
};
這是Azure安裝程序的圖片:
為什么范圍變量的值為NULL? 我錯過了什么? owner變量包含一個值!
最好的祝福
通過使用其他客戶端庫解決了它: https : //github.com/damienbod/angular-auth-oidc-client
萬一有人使用MSAL庫發布解決方案,我當然會將其標記為解決方案
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.