Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
782 views
in Technique[技术] by (71.8m points)

reactjs - How access a secret from keyvault?

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 enter image description here

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. enter image description here.

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...