passport-saml 和访问 SAML 值

passport-saml & Accessing SAML Values

我的 passport-saml 工作正常,但我无法访问从声明规则返回的 ADFS 属性,例如 firstName 属性。

当在网络浏览器中点击 /login 端点时,以下代码会在 console.log 中显示以下内容:

GET [/] user authenticated! req.user: {}

关于以下为何不起作用的任何想法,似​​乎没有填充 req 对象?

var app = express();

var samlStrategy = new saml.Strategy(
    {
        entryPoint: 'https://adfs.mydomain/adfs/ls/',
        issuer: 'https://foo.mydomain/login/callback',
        callbackUrl: 'https://foo.mydomain/login/callback',
        privateCert: fs.readFileSync('./certs/my.key', 'utf-8'),
        cert: fs.readFileSync('./certs/adfs.mydomain.crt', 'utf-8'),
        authnContext: 'http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/windows',
        acceptedClockSkewMs: -1,
        identifierFormat: null,
        signatureAlgorithm: 'sha256'
    },
    function (profile, done) {
        return done(null,
            {
                nameIDFormat: profile.nameIDFormat,
                nameID: profile.nameID,
                firstName: profile.firstName
            }
        );
    }
);

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

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

passport.use(samlStrategy);

app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.use(session({ resave: true, saveUninitialized: false, secret: 'xxxxx' }));

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

app.get('/', function (req, res) {
    if (req.isAuthenticated()) {
        console.log('GET [/] user authenticated! req.user: %s \n', JSON.stringify(req.user));
    } else {
        console.log('GET [/] user not authenticated! \n');
    }
    res.send(200);
});

app.get('/login', passport.authenticate('saml', { failureRedirect: '/' }), function (req, res) { res.redirect('/') });

app.post('/login/callback', passport.authenticate('saml', { failureRedirect: '/login', failureFlash: true }),
    function (req, res) {
        res.redirect('/');
    }
);

更新: 问题似乎出在未填充的配置文件详细信息中,如果我设置静态值它可以正常工作:

var samlStrategy = new saml.Strategy(
    {
        entryPoint: 'https://adfs.mydomain/adfs/ls/',
        issuer: 'https://foo.mydomain/login/callback',
        callbackUrl: 'https://foo.mydomain/login/callback',
        privateCert: fs.readFileSync('./certs/my.key', 'utf-8'),
        cert: fs.readFileSync('./certs/adfs.mydomain.crt', 'utf-8'),
        authnContext: 'http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/windows',
        acceptedClockSkewMs: -1,
        identifierFormat: null,
        signatureAlgorithm: 'sha256'
    },
    function (profile, done) {
        return done(null,
            {
                nameIDFormat: profile.nameIDFormat,
                nameID: profile.nameID,
                firstName: 'test_user'
            }
        );
    }
);

GET [/] user authenticated! req.user: {"firstName":"test_user"}

解决方案是从配置文件中获取正确的元素,下面是一个简单的示例。

function (profile, done) {
        console.log('passport.use() profile: %s \n', JSON.stringify(profile));
        return done(null,
            {
                upn: profile['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn']                
            }
        );
    }