reactjs - 如何从 keyvault 访问秘密?
问题描述
我创建了示例反应登录应用程序,其中用户可以通过参考此文档通过 azure ad 隐含 oauth2 登录来登录。
成功登录后,我无法在访问令牌的帮助下使用 microsoft graph api 访问 keyvault 机密。
我还通过在 config.js 文件中添加额外的 keyvault 范围来更新我的代码中的范围。
module.exports ={
appId: "6c90510c-82fd-4113-8aa5-6abdac107839",
scopes: [
"user.read",
"https://vault.azure.net/user_impersonation"
]
};
我还在 azure 门户的应用注册中添加了 Keyvault Api 权限。 .
这是我的登录代码
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>
);
}
}
当我尝试邮递员的命中 api 时获得访问令牌后。它显示了一些错误。谁能指导我解决此错误,因为我是 Azure Ad 和 Keyvault 的新手
提前致谢
解决方案
考虑到我的代码,它提供了获取访问令牌的功能,该令牌可用于调用 api 来访问密钥库:
请注意,起初我在 ["openid"、"profile"、"User.Read"、"https://vault.azure.net/user_impersonation" 中使用访问令牌调用 api 时收到与您相同的错误消息],然后我对令牌进行解码,发现它在声明“sub”中不包含“user_impersonation”,所以我更改了代码中的范围,然后它就起作用了。
<!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>
推荐阅读
- twitter-bootstrap - bootstrap 4 col 与 ml-auto 右对齐
- python - Matplotlib 不会按照它们出现的顺序打印列表中的值
- arrays - PostgreSQL:更新 JSONB 结构中嵌套数组中元素的属性
- perforce-client-spec - 无法在 perforce 中创建简单的客户端
- sql-server - 无法将值 NULL 插入列“intGolferEventYearID”,表不允许空值
- c - Clang 编译器忽略 .a 库文件
- docker - 在 Windows Docker 容器上安装 MS Build Tools 失败
- python - 用孔获取numpy数组形状的边界
- python - 创建一个通过使用列表中的键返回分数的程序
- javascript - javascript复选框默认返回第一个值而不是选定值