2016-11-28 89 views
3

我有一個使用NodeJS + ReactJS創建的項目應用程序,我想要的就是使用Azure AD驗證用戶並獲取他的數據,如姓名,圖片,職業等,使用Azure的Graph API。使用Azure AD,ReactJS和NodeJS驗證用戶並使用Graph API

我已經在Azure門戶上正確配置了Azure AD和應用程序。包括權限授權和所有這些員工。

我想了解如何做到這一點,但沒有成功的最佳途徑。我一直在尋找谷歌,StackOverflow,微軟文檔,甚至項目樣本。

一些樣本已經工作,但沒有一個我可以理解並投入到我的項目中作爲生產應用程序工作。

我用這個爲認證用戶,但返回的accessToken無效調用圖形API:

passport.use(new OIDCStrategy({ 
    redirectUrl: config.creds.returnURL, 
    realm: config.creds.realm, 
    clientID: config.creds.clientID, 
    clientSecret: config.creds.clientSecret, 
    oidcIssuer: config.creds.issuer, 
    identityMetadata: config.creds.identityMetadata, 
    skipUserProfile: config.creds.skipUserProfile, 
    responseType: config.creds.responseType, 
    responseMode: config.creds.responseMode, 
    allowHttpForRedirectUrl: config.creds.allowHttpForRedirectUrl 
    }, 
    function(iss, sub, profile, accessToken, refreshToken, done) { 
    console.log(accessToken); 
    profile = profile._json; 
    if (!profile.email) { 
     return done(new Error("No email found"), null); 
    } 
    // asynchronous verification, for effect... 
    process.nextTick(function() { 
     findByEmail(profile.email, function(err, user) { 
     if (err) { 
      return done(err); 
     } 
     if (!user) { 
      // "Auto-registration" 
      users.push(profile); 
      return done(null, profile); 
     } 
     return done(null, user); 
     }); 
    }); 
    } 
)); 

而這一次給了我正確的accessToken使用的圖形API,但我不明白如何使用它來代替護照:

function createAuthorizationUrl(state) { 
    var authorizationUrl = templateAuthzUrl.replace('<client_id>', sampleParameters.clientId); 
    authorizationUrl = authorizationUrl.replace('<redirect_uri>',redirectUri); 
    authorizationUrl = authorizationUrl.replace('<state>', state); 
    authorizationUrl = authorizationUrl.replace('<resource>', resource); 
    return authorizationUrl; 
} 

// Clients get redirected here in order to create an OAuth authorize url and redirect them to AAD. 
// There they will authenticate and give their consent to allow this app access to 
// some resource they own. 
app.get('/auth', function(req, res) { 
    crypto.randomBytes(48, function(ex, buf) { 
    var token = buf.toString('base64').replace(/\//g,'_').replace(/\+/g,'-'); 

    res.cookie('authstate', token); 
    var authorizationUrl = createAuthorizationUrl(token); 

    res.redirect(authorizationUrl); 
    }); 
}); 

// After consent is granted AAD redirects here. The ADAL library is invoked via the 
// AuthenticationContext and retrieves an access token that can be used to access the 
// user owned resource. 
app.get('/getAToken', function(req, res) { 
    if (req.cookies.authstate !== req.query.state) { 
    res.send('error: state does not match'); 
    } 
    var authenticationContext = new AuthenticationContext(authorityUrl); 
    authenticationContext.acquireTokenWithAuthorizationCode(req.query.code, redirectUri, resource, sampleParameters.clientId, sampleParameters.clientSecret, function(err, response) { 
    var message = ''; 
    if (err) { 
     message = 'error: ' + err.message + '\n'; 
    } 
    message += 'response: ' + JSON.stringify(response); 

    if (err) { 
     res.send(message); 
     return; 
    } 

    // Later, if the access token is expired it can be refreshed. 
    authenticationContext.acquireTokenWithRefreshToken(response.refreshToken, sampleParameters.clientId, sampleParameters.clientSecret, resource, function(refreshErr, refreshResponse) { 
     if (refreshErr) { 
     message += 'refreshError: ' + refreshErr.message + '\n'; 
     } 
     message += 'refreshResponse: ' + JSON.stringify(refreshResponse); 

     res.send(message); 
    }); 
    }); 
}); 

如果有人可以幫助我做一些真正的應用程序樣本,視頻什麼的,將是非常好的。我正在失去理智去弄清楚。

謝謝!

回答

2

護照的OIDCStrategy後跟Authorize access to web applications using OpenID Connect and Azure Active Directory驗證&授權用戶。如果您需要訪問資源,則仍需完成Use the authorization code to request an access token的步驟。

我添加一個基於openid connection sample一些代碼片段:

迴路功能將得到使用code獲得訪問令牌,並保存到用戶的SEESION對象。

app.post('/auth/openid/return', 
    passport.authenticate('azuread-openidconnect', { failureRedirect: '/login' }), 
    function (req, res) { 
    let option = { 
     method:'POST', 
     uri:'https://login.microsoftonline.com/<tenant_id>/oauth2/token', 
     headers:{ 
     'Content-Type':'application/x-www-form-urlencoded' 
     }, 
     form:{ 
     grant_type:'authorization_code', 
     client_id:'<client_id>', 
     resource:'https://graph.windows.net', 
     client_secret:'<secret_key>', 
     code:req.body.code, 
     redirect_uri:'http://localhost:3000/auth/openid/return' 
     } 
    } 
    console.log(option); 
    request(option,function(err,res,body){ 
     req.user.access_token = JSON.parse(body).access_token; 
    }) 

    // log.info('We received a return from AzureAD.'); 
    res.redirect('/'); 
    }); 

路由'/我'將採樣以使用訪問令牌來要求資源。

app.get('/me',ensureAuthenticated ,function(req,response){ 
    request.get("https://graph.windows.net/<tenant_id>/me?api-version=1.5", { 
    'headers': { 
     'Authorization': "Bearer " + req.user.access_token, 
     'Content-Type': 'application/json' 
    } 
    }, function(err, res, body){ 
    if(err){ 
     console.log("err: " + err); 
    } 
    else{ 
     console.log("res: " + res); 
     response.send(res); 
    } 
    }); 
}); 

任何進一步的問題,請隨時讓我知道。

+0

嗨加里!感謝您的回覆... 在看到您的答案之前,我使用adal-node而不是Passport使用此方法得到結果: 'authenticationContext.acquireTokenWithAuthorizationCode()' 但是現在,我在Azure上配置了另一個WebAPI我仍然有問題要調用這個API的方法。我改變了adal-node方法的資源參數,並且我得到了一個有效的標記來調用我的WebAPI,但是現在該圖不能用這個標記。 –

+0

我的問題是:我是否需要獲取2個不同的標記才能使用我的WebAPI和Graph API?如果我使用「acquireTokenWithAuthorizationCode」對用戶進行身份驗證並調用Graph並使用「acquireTokenWithClientCredentials」來要求令牌用於調用WebAPI,那麼可以嗎? –

+0

更改這些示例https://github.com/AzureAD/azure-activedirectory-library-for-nodejs#authorization-code中不同資源的'resource'參數。例如。使用'resource =「https://graph.windows.net」'獲取Azure AD圖形資源的訪問令牌。 –

相關問題