【问题标题】:Unable to get SSO working for NodeJS in BlueMix无法让 SSO 在 BlueMix 中为 NodeJS 工作
【发布时间】:2016-09-21 22:58:45
【问题描述】:

这是我不断收到的错误 “CWOAU0062E: OAuth 服务提供商无法重定向请求,因为重定向 URI 无效。请联系您的系统管理员解决问题。”

var express = require('express');

// Add for SSO
var cookieParser = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var OpenIDConnectStrategy = require('passport-idaas-openidconnect').IDaaSOIDCStrategy;
var redis = require('redis');
var RedisStore = require('connect-redis')(session);

// cfenv provides access to your Cloud Foundry environment
// for more info, see: https://www.npmjs.com/package/cfenv
var cfenv = require('cfenv');
// get the app environment from Cloud Foundry
var appEnv = cfenv.getAppEnv();

// create a new express server
var app = express();
var services = JSON.parse(process.env.VCAP_SERVICES || null);
// get configuration for redis backing service and connect to service
var redisConfig = appEnv.getService(/Redis.*/);
if(redisConfig == null) {
  console.log('ERROR: Failed to create REDDISCONFIG!!!');
} else {
  var redisPort = redisConfig.credentials.port;
  var redisHost = redisConfig.credentials.hostname;
  var redisPasswd = redisConfig.credentials.password;

  var redisclient = redis.createClient(redisPort, redisHost, {no_ready_check: true});
  redisclient.auth(redisPasswd, function (err) {
      if (err) {
        throw err;
      }
  });

  redisclient.on('connect', function() {
      console.log('Connected to Redis');
  });
}

// define express session services, etc for SSO
app.use(cookieParser());
// app.use(session({resave: 'true', saveUninitialized: 'true' , secret: 'keyboard cat'}));
if(redisConfig != null) {
  app.use(session({
    store: new RedisStore({ client: redisclient }),
    resave: 'true',
    saveUninitialized: 'true',
    secret: 'top secr8t'
  }));
}

app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser(function(user, done) {
   done(null, user);
});

passport.deserializeUser(function(obj, done) {
   done(null, obj);
});

// find config object for the SSO services from VCAP_SERVICES through cfenv/appEnv
var ssoConfig = services.SingleSignOn[0];
//appEnv.getService(/Single Sign On.*/)
if(ssoConfig == null) {
  console.log('ERROR: Failed to instantiate SSOCONFIG. Its not available!!!');
} else {
  var client_id = ssoConfig.credentials.clientId;
  var client_secret = ssoConfig.credentials.secret;
  var authorization_url = ssoConfig.credentials.authorizationEndpointUrl;
  var token_url = ssoConfig.credentials.tokenEndpointUrl;
  var issuer_id = ssoConfig.credentials.issuerIdentifier;
}
// you MUST change the host route to match your application name
// var callback_url = 'https://scaleSSO-TOR0815.mybluemix.net/auth/sso/callback';
var callback_url = 'https://krishnodejs.mybluemix.net/auth/sso/callback';

var OpenIDConnectStrategy = require('passport-idaas-openidconnect').IDaaSOIDCStrategy;
var Strategy = new OpenIDConnectStrategy({
                 authorizationURL : authorization_url,
                 tokenURL : token_url,
                 clientID : client_id,
                 scope: 'openid',
                 response_type: 'code',
                 clientSecret : client_secret,
                 callbackURL : appEnv.url + '/auth/sso/callback',
                //  callbackURL : callback_url,
                 skipUserProfile: true,
                 issuer: issuer_id},
    function(accessToken, refreshToken, profile, done) {
                process.nextTick(function() {
        profile.accessToken = accessToken;
        profile.refreshToken = refreshToken;
        done(null, profile);
            })
});

passport.use(Strategy);
app.get('/login', passport.authenticate('openidconnect', {}));

function ensureAuthenticated(req, res, next) {
    if(!req.isAuthenticated()) {
      // req.session.originalUrl = 'https://krishnodejs.mybluemix.net';
        res.redirect('/login');
    } else {
        return next();
    }
}

app.get('/auth/sso/callback',function(req,res,next) {
        var redirect_url = 'https://krishnodejs.mybluemix.net/hello'; 
      // req.session.originalUrl;
            passport.authenticate('openidconnect',{
                 successRedirect: redirect_url,
                 failureRedirect: '/failure',
          })(req,res,next);
        });


app.get('/hello', ensureAuthenticated, function(req, res) {
  res.send('Hello, '+ req.user['id'] + '!'); }
);

app.get('/failure', function(req, res) {
             res.send('login failed'); });

// serve the files out of ./public as our main files
app.use(express.static(__dirname + '/public'));

// start server on the specified port and binding host
app.listen(appEnv.port, function() {

    // print a message when the server starts listening
  console.log("server starting on " + appEnv.url);
});

我在 SSO“https://krishnodejs.mybluemix.net/hello”的返回 URL 设置中有以下 URL

非常欢迎任何修复建议。

失败的重定向 URL 有我的回调 URL 正确,除了奇怪的 &scope=openid....但我想,这可能不是问题

我查看了服务器端日志是否有错误。但是没有。让我不知道问题出在哪里

https://ssotest-gx1592z76o-cl12.iam.ibmcloud.com/idaas/oidc/endpoint/default/authorize?response_type=code&client_id=EdzctxPuQ4&redirect_uri=https://krishnodejs.mybluemix.net/auth/sso/callback&scope=openidopenid”

【问题讨论】:

    标签: node.js single-sign-on ibm-cloud


    【解决方案1】:

    对于有类似问题的人,请注意登录时从 BlueMix 返回的 redirect_url 参数。

    在我的例子中,我在 2 个地方设置了这个 URL

    虽然两个链接都指向同一个 URL,但出于某种原因,应用程序会从代码中选择一个。我能够弄清楚的方法是从参数 callback_url 中返回的(如上) 首先,我们在代码中提供的重定向 URL 不必是完整的 URL。就我而言,它应该是“bluemix/callback”。我修好了。有没有用,没有。但事情从一个问题转移到另一个问题。向前迈出一步,如果我可以这么说的话。 下一个问题是什么? URL 恢复正常,但协议不正确。它总是返回 http 而不是 https,所以页面仍然没有加载。 最后,我摆脱了从代码中设置这个 URL 并从 UI 中的 URL 驱动整个东西。我将“配置应用程序”中的 URL 设置为“https://krishnodejs.mybluemix.net/auth/bluemix/callback”。 如果您想知道,在这些更改之后,我的代码是什么样子的,那就去吧

    var OpenIDConnectStrategy = require('passport-idaas-openidconnect').IDaaSOIDCStrategy;
    var OpenIDStrategy = new OpenIDConnectStrategy({
        authorizationURL : authorization_url,
        tokenURL : token_url,
        clientID : client_id,
        scope: 'openid',
        response_type: 'code',
        clientSecret : client_secret,
        // callbackURL : callback_url,
        skipUserProfile: true,
        issuer: issuer_id
    }, function(accessToken, refreshToken, profile, done) {
        process.nextTick(function() {
            profile.accessToken = accessToken;
            profile.refreshToken = refreshToken;
            done(null, profile);
        });
    });
    passport.use(OpenIDStrategy);
    

    }

    如您所见,我注释掉了传递 callback_url 的代码。宾果游戏,一切正常。 经验教训:注意“redirect_url”。如果 URL 返回错误,那么您将无法在代码或 UI 中正确设置它。 我的下一个尝试是完全不在 UI 中设置它,而是完全从代码中驱动它。暂时以为我已经解决了这个问题,我可以继续前进。 希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      CWOAU0062E: OAuth 服务提供者无法重定向请求,因为重定向 URI 无效。请与您的系统管理员联系以解决问题。 通常表示在单点登录服务中未正确配置返回 URL。

      所以请更新服务的集成部分下的单点登录的返回 URL,使其与代码中的 callback_url 匹配,然后重新启动应用程序

      【讨论】:

        猜你喜欢
        • 2012-11-19
        • 2016-08-29
        • 1970-01-01
        • 2020-08-10
        • 1970-01-01
        • 2014-03-14
        • 1970-01-01
        • 1970-01-01
        • 2015-10-28
        相关资源
        最近更新 更多