0

I'm trying to implement Window Authentication for my React application (with apollo client). I'm using apollo graphql server as backend.I've used node-sspi to get windows logged in user.

Below is my Server side code. http://localhost:9000/graphiql is not working if add app.use(function (req, res, next) {. Also not getting windows logged in user name.

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const expressJwt = require('express-jwt'); //auth
const jwt = require('jsonwebtoken'); //auth
const db = require('./db');

const port = process.env.PORT || 9000;
const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');
const app = express();

const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
const resolvers = require('./resolvers')

const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})

// authentication middleware
const authMiddleware = expressJwt({
   secret: jwtSecret,
   credentialsRequired: false
})

app.use(cors(), bodyParser.json(), authMiddleware);

app.use(function (req, res, next) {
  var nodeSSPI = require('node-sspi')
  var nodeSSPIObj = new nodeSSPI({
    retrieveGroups: true
  })
  nodeSSPIObj.authenticate(req, res, function(err){
    res.finished || next()
  })
})

const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql', graphqlExpress((req) => ({
   schema,
   context: {user: req.user && db.students.get(req.user.sub)}
})));
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

app.post('/login', (req, res) => {
   const userName = req.connection.user; // USERNAME undefined
   // LDAP Authenticate 
   const token = jwt.sign({sub: userName}, jwtSecret);
   res.send({token});
});

app.listen(
   port, () => console.info(
      `Server started on port ${port}. use http://localhost:${port}/graphiql`
   )
);

1 Answer 1

2

I got solution after doing some workaround.

Server side code

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const expressJwt = require('express-jwt'); //auth
const jwt = require('jsonwebtoken'); //auth
const db = require('./db');

const port = process.env.PORT || 9000;
const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');
const app = express();

const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
const resolvers = require('./resolvers')

const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})

// authentication middleware
const authMiddleware = expressJwt({
   secret: jwtSecret,
   credentialsRequired: false
})

app.use(cors(), bodyParser.json(), authMiddleware);

//Setup endpoint routes
var router = express.Router();
//Basic Router Config
router.use(function(req, res, next){

   var nodeSSPI = require('node-sspi')
   //Integrated Authentication for Windows
   var nodeSSPIObj = new nodeSSPI({
       retrieveGroups: true
   });

   try{
       nodeSSPIObj.authenticate(req, res, function(err){
           res.finished || next();
       });
   }
   catch(err)
   {
       res.status(500).send(JSON.stringify({status: 500, message: "Something went wrong", detail: err.message}));
   }
});

// windows
router.get('/', function(req, res){
   // Do LDAP authentication or whatever

   const token = jwt.sign({authUser: req.connection.user}, jwtSecret);
   res.send({token});
});

// Regular login
router.post('/login', (req, res) => {
   const email = req.body.email;
   const password = req.body.password;

   const user = authenticateUser // SQL/mongo/etc..
   const token = jwt.sign({authUser: user.id}, jwtSecret);
   res.send({token});
});

app.use('/api', router);

const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql', graphqlExpress((req) => ({
   schema,
   context: {user: req.user && req.user.authUser}
})));
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

app.listen(
   port, () => console.info(
      `Server started on port ${port}. use http://localhost:${port}/graphiql`
   )
);

In Client side, I'used Ajax Jquery call for POC.

For windows login

$.ajax({
url: "http://localhost:9000/api",
contentType: "application/json",
xhrFields: {
  withCredentials: true
},
type: "GET",
data: '',
success: function (response) {
  loginToken = response.token;
      },
error: (xhr, err) => alert('error')
})

with login credentials

var email =  $("#txtEmail").val();
var password =  $("#txtPwd").val();
if(email && password) {
   $.ajax({
      url:"http://localhost:9000/api/login",
      contentType:"application/json",
      type:"POST",
      xhrFields: {
             withCredentials: true
      },
      data:JSON.stringify({email,password}),
      success:function(response) {
             loginToken =  response.token;   
      },
      error:(xhr,err) =>  alert('error')
      })
}else alert("email and pwd empty")

For GraphQL query

$.ajax({url: "http://localhost:9000/graphql",
        contentType: "application/json",
        headers: {"Authorization": 'bearer '+ loginToken},
        type:'POST',
        data: JSON.stringify({
        query:`{greetingWithAuth}` }),
        success: function(result) {
                  console.log(result.data.greetingWithAuth")
        },
        error: func
       }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.