W
Wasp3w ago
lazi

Microsoft SSO Support

Hello. I'm looking for a way to integrate Microsoft SSO Login for a Wasp project. Unfortunately, it's not one of the already-supported ones. Any ideas on how could I even start integrating? Thank you.
4 Replies
kapa.ai
kapa.ai3w ago
Hi @lazi. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Currently, Wasp doesn't have built-in support for Microsoft SSO, but there are a few approaches you could consider. Wasp officially supports the following authentication methods: - Email - Username & Password - Google - GitHub - Keycloak The good news is that Wasp is planning to integrate Arctic, a library that supports many OAuth providers including Microsoft. According to the Discord discussions, this integration was planned to be completed around March 2023, but you should check the current status as this information might be outdated. In the meantime, you have a couple of options: 1. Wait for Arctic integration: Wasp is moving to Arctic as their library for OAuth, which supports many providers including Microsoft. This would make Microsoft SSO available natively in Wasp. 2. Custom implementation: You could try implementing Microsoft SSO using custom API endpoints and a Microsoft authentication library for Node.js. One community member mentioned they successfully connected with Keycloak via a custom API action before official support was added. If you need Microsoft SSO urgently, the custom implementation route would be your best bet, though it would require more work. You'd need to: - Create custom API endpoints - Install a Microsoft OAuth library - Handle the authentication flow manually - Inject the user object into the context for queries For the latest updates on OAuth provider support, I recommend checking the Wasp Auth documentation or asking in the Wasp Discord community. Hope this helps! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @lazi, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
lazi
laziOP3w ago
@kapa.ai Okay so let's say I'd need a very urgent custom implementation. Could you give me some specific ideas on how I'd do it ?
kapa.ai
kapa.ai3w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I'll outline a specific approach for implementing Microsoft SSO in Wasp as a custom solution based on the knowledge sources. Custom Microsoft SSO Implementation in Wasp 1. Create a Custom API Endpoint First, define a custom API endpoint in your main.wasp file:
api microsoftAuth {
fn: import { handleMicrosoftAuth } from "@src/server/api/microsoftAuth.js",
entities: [User],
httpRoute: (POST, "/api/auth/microsoft")
}
api microsoftAuth {
fn: import { handleMicrosoftAuth } from "@src/server/api/microsoftAuth.js",
entities: [User],
httpRoute: (POST, "/api/auth/microsoft")
}
2. Implement the Authentication Handler Create the implementation file for your API endpoint:
// src/server/api/microsoftAuth.js
import * as jwt from 'jsonwebtoken';
import { Request, Response } from 'express';
import { prisma } from 'wasp/server';

// You'll need to install a Microsoft OAuth library
// e.g., npm install @azure/msal-node
export const handleMicrosoftAuth = async (req, res, context) => {
try {
// 1. Receive the auth code from Microsoft
const { code } = req.body;

// 2. Exchange code for tokens using Microsoft OAuth library
// This is where you'd use the Microsoft-specific library
const tokenResponse = await exchangeCodeForTokens(code);

// 3. Get user info from Microsoft
const userInfo = await getMicrosoftUserInfo(tokenResponse.access_token);

// 4. Find or create user in your database
let user = await prisma.user.findUnique({
where: { email: userInfo.email }
});

if (!user) {
user = await prisma.user.create({
data: {
email: userInfo.email,
// Add other user fields as needed
}
});
}

// 5. Generate JWT token for your app
const token = jwt.sign(
{ id: user.id },
process.env.JWT_SECRET,
{ expiresIn: '7d' }
);

// 6. Return the token to the client
res.json({ token, user });
} catch (error) {
console.error('Microsoft auth error:', error);
res.status(500).json({ error: 'Authentication failed' });
}
};
// src/server/api/microsoftAuth.js
import * as jwt from 'jsonwebtoken';
import { Request, Response } from 'express';
import { prisma } from 'wasp/server';

// You'll need to install a Microsoft OAuth library
// e.g., npm install @azure/msal-node
export const handleMicrosoftAuth = async (req, res, context) => {
try {
// 1. Receive the auth code from Microsoft
const { code } = req.body;

// 2. Exchange code for tokens using Microsoft OAuth library
// This is where you'd use the Microsoft-specific library
const tokenResponse = await exchangeCodeForTokens(code);

// 3. Get user info from Microsoft
const userInfo = await getMicrosoftUserInfo(tokenResponse.access_token);

// 4. Find or create user in your database
let user = await prisma.user.findUnique({
where: { email: userInfo.email }
});

if (!user) {
user = await prisma.user.create({
data: {
email: userInfo.email,
// Add other user fields as needed
}
});
}

// 5. Generate JWT token for your app
const token = jwt.sign(
{ id: user.id },
process.env.JWT_SECRET,
{ expiresIn: '7d' }
);

// 6. Return the token to the client
res.json({ token, user });
} catch (error) {
console.error('Microsoft auth error:', error);
res.status(500).json({ error: 'Authentication failed' });
}
};
3. Create a Custom Middleware To inject the authenticated user into the context for all requests, create a custom middleware:
// src/server/middleware.js
import jwt from 'jsonwebtoken';
import { prisma } from 'wasp/server';
export const microsoftAuthMiddleware = async (req, res, next) => {
try {
const token = req.headers.authorization?.split(' ')[1];

if (token) {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
const user = await prisma.user.findUnique({
where: { id: decoded.id }
});

if (user) {
req.user = user; // This will make the user available in the context
}
}

next();
} catch (error) {
console.error('Auth middleware error:', error);
next();
}
};
// src/server/middleware.js
import jwt from 'jsonwebtoken';
import { prisma } from 'wasp/server';
export const microsoftAuthMiddleware = async (req, res, next) => {
try {
const token = req.headers.authorization?.split(' ')[1];

if (token) {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
const user = await prisma.user.findUnique({
where: { id: decoded.id }
});

if (user) {
req.user = user; // This will make the user available in the context
}
}

next();
} catch (error) {
console.error('Auth middleware error:', error);
next();
}
};
4. Register the Middleware in Wasp Add the middleware to your main.wasp file:
app MyApp {
// ... other app config
server: {
middleware: [
import { microsoftAuthMiddleware } from "@src/server/middleware.js"
]
}
}
app MyApp {
// ... other app config
server: {
middleware: [
import { microsoftAuthMiddleware } from "@src/server/middleware.js"
]
}
}
5. Client-Side Implementation On the client side, you'll need to: 1. Redirect users to Microsoft's OAuth page 2. Handle the callback with the auth code 3. Send the code to your custom API endpoint 4. Store the returned JWT token for future requests This approach is similar to what a community member did with Keycloak before official support was added, as mentioned in the Discord discussion. Remember to set up the necessary environment variables: - MICROSOFT_CLIENT_ID - MICROSOFT_CLIENT_SECRET - MICROSOFT_REDIRECT_URI - JWT_SECRET This is a simplified outline, and you'll need to adapt it to your specific requirements and the Microsoft OAuth flow details. For more information on creating custom API endpoints in Wasp, refer to the Custom HTTP API Endpoints documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @lazi, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Carlos
Carlos3w ago
Hi @lazi, we don't have a officially-supported way of connecting with providers other than the ones on our website right now. BUT, with some custom code you can code your own login/signup actions and connect it to Wasp's user mechanism. We have this Spotify auth example that you can change to your own provider, you will keep the ability to use the user normally.

Did you find this page helpful?