Reputation: 1883
I created sample react login application where user can login by implict oauth2 login via azure ad by refering to this documentation.
After successful login I am not able to access keyvault secrets by using microsoft graph api with the help of access token.
This is the error I am getting while I am trying to access secrets from keyvault
I also updated the scopes in my code by adding additional keyvault scope in config.js file.
module.exports ={
appId: "6c90510c-82fd-4113-8aa5-6abdac107839",
scopes: [
"user.read",
"https://vault.azure.net/user_impersonation"
]
};
I also added Keyvault Api permissions in app registration from azure portal.
.
Here is my login code
import { UserAgentApplication } from 'msal'
class Login extends React.Component {
constructor(props) {
super(props);
this.submitHandler = this.submitHandler.bind(this);
this.email = React.createRef();
this.password = React.createRef();
this.token = "";
this.expiresOn = 0;
this.userAgentApplication = new UserAgentApplication({
auth: {
clientId: config.appId,
clientSecret: "W~~4iZ.uKv~eoAd-hKKU35WJVv.---83Gm",
redirectUri: "http://localhost:3000/events"
},
cache: {
cacheLocation: "localStorage", // This configures where your cache will be stored
storeAuthStateInCookie: true, // Set this to "true" if you are having issues on IE11 or Edge
}
});
this.state = {
error: null,
isAuthenticated: false,
user: {}
};
}
login = async () => {
try {
// Login via popup
await this.userAgentApplication.loginPopup(
{
scopes: config.scopes,
prompt: "select_account"
});
// After login, get the user's profile
await this.getUserProfile();
var user = this.userAgentApplication.getAccount();
}
catch (err) {
console.log("errror", err.message)
this.setState({
isAuthenticated: false,
user: {},
error: err.message
});
}
}
logout = () => {
this.userAgentApplication.logout();
}
getUserProfile = async () => {
try {
const data = await this.userAgentApplication.acquireTokenSilent({
scopes: config.scopes
});
if (data.accessToken) {
console.log("Token", data.accessToken);
this.token = data.accessToken;
this.expiresOn = data.expiresOn;
}
}
catch (err) {
console.log("err", err.message);
}
}
render() {
const { isLogin } = this.props;
const buttonTitle = isLogin ? "Sign Up" : "Login";
return (
<form className="login-form">
{ !isLogin && <IconButton backgroundColor="#0A66C2" font="14px" width='35%' padding='8px' microsoftLoginHandler={this.login} />}
</form>
);
}
}
After getting access token when I tried the hit api from postman. It is showing some error. Can anyone please guide me to resolve this error as I am new to Azure Ad and Keyvault
Thanks in advance
Upvotes: 1
Views: 1487
Reputation: 16066
Take my code into consideration, it offers function to get access token which can used to call api to access key vault:
And pls note, at first I got the same error message as yours when I call api with access token in ["openid", "profile", "User.Read", "https://vault.azure.net/user_impersonation"], then I decode the token and found it didn't contain 'user_impersonation' in claim 'sub', so I changed the scope in the code and then it worked.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="https://alcdn.msftauth.net/lib/1.2.1/js/msal.js" integrity="sha384-9TV1245fz+BaI+VvCjMYL0YDMElLBwNS84v3mY57pXNOt6xcUYch2QLImaTahcOP" crossorigin="anonymous"></script>
</head>
<body>
<button id="btn">click</button>
<div>
userName:<input type="text" id="userName" />
</div>
<div id="accessToken"></div>
<script type="text/javascript">
$("#btn").click(function(){
showWelcome();
})
const msalConfig = {
auth: {
clientId: "<your azure ad app id>", // pls add api permission with azure key vault
authority: "https://login.microsoftonline.com/<your-tenant>",
redirectUri: "http://localhost:8848/msalTest/index.html",
},
cache: {
cacheLocation: "sessionStorage", // This configures where your cache will be stored
storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
}
};
const myMSALObj = new Msal.UserAgentApplication(msalConfig);
//at first, I used scope like ["openid", "profile", "User.Read", "https://vault.azure.net/user_impersonation"]
//but with this accesstoken, I got the same error as yours
//and I try to use the scope below, and it worked
//I decode the token with jwt, when I get error, the token didn't contains correct scope
const loginRequest = {
scopes: ["openid", "profile", "https://vault.azure.net/user_impersonation"],
};
function showWelcome(){
myMSALObj.loginPopup(loginRequest)
.then((loginResponse) => {
console.info(loginResponse);
console.log("========= myMSALObj.getAccount() =======");
console.log(myMSALObj.getAccount());
$("#userName").val(myMSALObj.getAccount().name);
getAccessToken();
//Login Success callback code here
}).catch(function (error) {
console.log(error);
});
}
function getAccessToken(){
getTokenPopup(loginRequest)
.then(response => {
$("#accessToken").text(response.accessToken);
}).catch(error => {
console.log(error);
});
}
function getTokenPopup(request) {
return myMSALObj.acquireTokenSilent(request)
.catch(error => {
console.log(error);
console.log("silent token acquisition fails. acquiring token using popup");
// fallback to interaction when silent call fails
return myMSALObj.acquireTokenPopup(request)
.then(tokenResponse => {
return tokenResponse;
}).catch(error => {
console.log(error);
});
});
}
</script>
</body>
</html>
Upvotes: 1