passport-azure-ad Strategy.prototype.jwtVerify: невозможно проверить токен - PullRequest
0 голосов
/ 01 октября 2018

Я создал веб-API по следующей статье: https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v1-nodejs-webapi

const restify = require('restify'),
    restifyPlugins = require('restify-plugins'),
    config = require('./config'),
    serverPort = process.env.PORT || config.serverPort,
    passport = require('passport'),
    BearerStrategy = require('passport-azure-ad').BearerStrategy,
    authenticatedUserTokens = [];

const server = restify.createServer({ name: 'Azure Active Directroy with Node.js Demo' });

const authenticationStrategy = new BearerStrategy(config.credentials, (token, done) => {
    let currentUser = null;
    let userToken = authenticatedUserTokens.find((user) => {
        currentUser = user;
        user.sub === token.sub;
    });

    if (!userToken) {
        authenticatedUserTokens.push(token);
    }

    return done(null, currentUser, token);
});

passport.use(authenticationStrategy);

server.use(restifyPlugins.authorizationParser());
server.use(passport.initialize());
server.use(passport.session());

server.get('/api', (req, res, next) => {
    res.send(200, 'Try: curl -isS -X GET http://127.0.0.1:3000/api');
    next();
});

server.get('/authenticated', passport.authenticate('oauth-bearer', { session: false }), (req, res, next) => {
    res.json({ message: 'response form authenticated API endpoint' });
    return next();
});

server.listen(serverPort);

Но когда я пытаюсь вызвать API, я получаю эту ошибку: Strategy.prototype.jwtVerify: не могу проверитьтокен

В нем говорится, что он не может проверить токен… Я прочитал это: https://github.com/AzureAD/passport-azure-ad/issues/373, и я добавил свойство аудитории, но оно не работает:

Вот параметры дляпаспорт:

const tenantName = "MY_TENANT",
    clientID = "CLIENT_ID",
    serverPort = 3000;

module.exports.serverPort = serverPort;

module.exports.credentials = {
    identityMetadata: `https://login.microsoftonline.com/${tenantName}.onmicrosoft.com/v2.0/.well-known/openid-configuration`,
    //identityMetadata: `https://login.microsoftonline.com/${tenantName}.onmicrosoft.com/.well-known/openid-configuration`,
    clientID: clientID,
    audience: `https://${tenantName}.onmicrosoft.com/9fc847b6-92d0-4739-9eb1-6201752d6af1`
};

Идея состоит в том, чтобы вызвать аутентифицированный API из клиента или другого веб-приложения ... вот метод, который я использую:

static async Task CallWebApiProtectedAsync()
        {
            var parameters = new PlatformParameters(PromptBehavior.Always);

            string authority = "https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47/oauth2/token";
            string resource = "9fc847b6-92d0-4739-9eb1-6201752d6af1"; //Web API Client Id
            string clientId = "0564e082-e1f3-4506-9263-d2171516f934";
            string clientSecret = "CLIENT_SECRET";
            string redirectUri = "http://clientAPIADD";

            try
            {
                var authContext = new AuthenticationContext(authority);
                //var token = await authContext.AcquireTokenAsync(resource, clientId, new Uri(redirectUri), parameters);
                var clientCredential = new ClientCredential(clientId, clientSecret);
                var token = await authContext.AcquireTokenAsync(resource,clientCredential);

                var authHeader = token.CreateAuthorizationHeader();

                Console.WriteLine($"AccessTokenType: {token.AccessTokenType} AccessToken:{token.AccessToken}");

                var client = new HttpClient();
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token.AccessTokenType, token.AccessToken);
                var requestURI = new Uri("http://localhost:3000/authenticated");
                Console.WriteLine($"Reading values from '{requestURI}'.");
                HttpResponseMessage httpResponse = await client.GetAsync(requestURI);
                Console.WriteLine($"HTTP Status Code: '{httpResponse.StatusCode.ToString()}'");
                Console.WriteLine($"HTTP Response: '{httpResponse.ToString()}'");
                string responseString = await httpResponse.Content.ReadAsStringAsync();
                var json = JsonConvert.DeserializeObject(responseString);
                Console.WriteLine($"JSON Response: {json}");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception in CallWebApirotectedAsync(): " + ex.Message);
            }
        }
    }

Есть мысли?

Спасибо!

1 Ответ

0 голосов
/ 28 декабря 2018

Это вызывает много головной боли для правильной настройки BearerStrategy, поэтому я делюсь с правильной конфигурацией:

  • На стороне сервера, добавьте audience: 'https://graph.windows.net/' prop в конфигурацию вашей стратегии,
  • На стороне клиента, в вашем примере в методе CallWebApiProtectedAsync измените переменную resource на string resource = "https://graph.windows.net/", поэтому вы запрашиваете разрешения на использование Microsoft Graph API (даже если вам не нужно его использовать,Вы должны поместить это в конфигурацию).

Надеюсь, это поможет: D

...