Nodejs - Passport-saml implementation with One-login - javascript

I'm trying to run below passport-sample example with one login SSO. But I couldn't make it successful. I have given Onelogin HTTP-redirect url in the SAML entry point(config.js). It was redirecting to one login authentication page and redirecting back to application page but the application is not loading.
https://github.com/gbraad/passport-saml-example
Please advise what am I missing here.
module.exports = {
development: {
app: {
name: 'Passport SAML strategy example',
port: process.env.PORT || 3000
},
passport: {
strategy: 'saml',
saml: {
path: process.env.SAML_PATH || '/login/callback',
entryPoint: process.env.SAML_ENTRY_POINT || 'https://domain.onelogin.com/trust/saml2/http-redirect/slo/200908',
issuer: 'passport-saml',
cert: process.env.SAML_CERT || null
}
}
}
};

The saml entryPoint doesn't look right in the passport saml configuration.
It is currently configured to the single logout service URL; whereas
the single sign on service URL should read similar to:
'https://domain.onelogin.com/trust/saml2/http-post/sso/200908'
The protocol binding used in entry point above is also ascertained to be the right one because the AuthNRequest sent in passport-saml module at version 0.5.0 uses http-post protocol binding for the authentication request with the identity provider and not http-redirect protocol binding.

Related

How to access httpOnly cookies from Nuxt 3 server

I am implementing a login feature to a website project. The backend is Express and the frontend is Nuxt 3. Upon successfully authenticating a user login, the Express backend returns necessary data to the webserver, which then creates an httpOnly cookie and sets any necessary data in a Pinia store. On page refresh, I would like the Nuxt 3 server to look at the cookie and setup the Pinia store (since it is lost on page refresh).
Can someone provide some guidance? I have looked at the useNuxtApp() composable, and I can see the cookie in nuxtApp.ssrContext.req.headers.cookie, but that only provides a K/V pairing of all set cookies, which I would need to parse. I know of the useCookie composable, but that only works during Lifecycle hooks, which seems to only resolve undefined.
Thanks.
Not sure if this is the right way,
but it's a solution I used to get through a similar case - dotnet api + nuxt3 client.
First, we need to proxy API (express in your case),
this will make it, so our cookie is on the same domain and browser will start sending it to /api/ endpoints.
Install #nuxtjs-alt/proxy - npm i #nuxtjs-alt/proxy.
Add configuration to nuxt.config.ts (my api running on localhost:3000):
nuxt.config.ts:
export default defineNuxtConfig({
modules: [
'#nuxtjs-alt/proxy'
],
proxy: {
enableProxy: true,
fetch: true,
proxies: {
'/proxy': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/proxy/, '')
}
}
}
});
Then we can the request that will set a cookie anywhere on client using proxy instead of a direct call.
Anywhere on client, do a request using newly setup proxy instead of calling API directly.
Adjust parameters based on your setup.
await $fetch('/proxy/user/sign-in', {
method: 'POST',
body: {
email: 'example#mail.com',
password: 'password'
}
});
Ultimately, should end up with a cookie set on our client domain.
And lastly, when we handle request client side - we read the cookie and set up on forwarding request.
Replace COOKIE_NAME and API URL accordingly.
server/api/user/me.get.ts:
export default defineEventHandler(async (event) => {
return await $fetch('http://localhost:3000/user/me', {
headers: {
Cookie: `COOKIE_NAME=${
getCookie(event, 'COOKIE_NAME')
}`
}
});
});
API call will use the same cookie we got when we did a first request using cookie and the server should be able to read it.

Node http-middleware-proxy and express against Tomcat

we are running our Java app (spring based) including the UI modules in a Tomcat container. Calling tomcat directly over http://localhost:8080 a login page is displayed and a redirect 302 occurs to the web app.
Now we want to develop the UI modules separately from the Java app by running an Express server with http-middleware-proxy and browser-sync. The modules have not been extracted out of the war-file and are running on the Tomcat instance. For testing purposes we just copied the UI module to another dir to setup Express and corresponding modules.
The problem is that we are not able to get the authorization cookies (JSESSIONID) and CSRF tokens correctly set.
How can the redirect 302 intercepted and redirected to the separately hosted UI app?
We´ve got the authorization working, so no login is required but calling the "copied app" does not work and results in "auth error" or "forbidden".
We already checked the documentation and other posts in here.
var cookie;
function relayRequestHeaders(proxyReq, req) {
if (cookie) {
proxyReq.setHeader('cookie', cookie);
}
};
function relayResponseHeaders(proxyRes, req, res) {
var proxyCookie = proxyRes.headers["set-cookie"];
if (proxyCookie) {
cookie = proxyCookie;
}
};
const oOptions = {
target: 'http://localhost:8080',
changeOrigin: true,
auth: 'user:pw',
pathRewrite: {
'^/dispatcher': '/dispatcher',
},
//cookieDomainRewrite: 'localhost',
onProxyReq: relayRequestHeaders,
onProxyRes: relayResponseHeaders,
logLevel: 'debug'
};
const wildcardProxy = createProxyMiddleware( oOptions );
app.use(wildcardProxy);
Any ideas on how to get that solved?
Thanks.
Update:
We tried as well to filter context paths which works but then it does not access the resources of the hosted webapp via express.
const oOptions = {
target: 'http://localhost:8080',
changeOrigin: true,
auth: 'user:pw',
logLevel: 'debug'
};
const wildcardProxy = createProxyMiddleware(['index.html', 'index.jsp', '!/resources/scripts/**/*.js'], oOptions );
app.use(wildcardProxy);
This is because we are proxying "/". How can it be achieved to only proxy the login and initial index.jsp but then using the resources of "webapp" and not of tomcat resources (e.g. *.js)? Is this possible somehow via the app.use to bind to certain files and paths?
We got that solved. We just excluded certain files from being served by the target host.
config.json:
{
...
"ignoreFilesProxy": ["!/**/*.js", "!/**/*.css", "!/**/*.xml", "!/**/*.properties"],
...
}
...
createProxyMiddleware(config.ignoreFilesProxy, oOptions);
...
Next step was to change the Maven build, so that the UI modules are not served/packaged with the war-file in the local dev environment. We solved that by introducing two Maven Profiles to include or exclude the UI modules in the WAR-project.

Apple SignIn with Parse Server

My App is hosted on sashido.io, which offers Parse Server Hosting. Since it is required, I am trying to implement Apple SignIn for my app. As a first step, I've added the following code to my app. The Apple SignIn works, I get the token and the id, but I cannot create a Parse User with this data. This is my iOS-Code:
var authData = [String: String]()
authData["id"] = id
authData["token"] = token
PFUser.logInWithAuthType(inBackground: "apple", authData: authData).continueWith(block: {
task -> Void in
...
})
I have verified that the authData contains the id and the token properly. Unfortunately, I get an internal server error as response {"code":1,"message":"Internal server error."}
After that, I have modified the following part of my index.js file like this and pushed it to sashido. Unfortunately, this didn't change anything and I'm still getting the internal server error.
var api = new ParseServer(
{
databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
appId: process.env.APP_ID || 'myAppId',
masterKey: process.env.MASTER_KEY || 'masterKey',
serverURL: process.env.SERVER_URL || 'http://localhost:' + port + '/1',
// If you change the cloud/main.js to another path
// it wouldn't work on SashiDo :( ... so Don't change this.
cloud: process.env.CLOUD_CODE_MAIN || 'cloud/main.js',
auth: {
apple: {
client_id: process.env.IOS_BUNDLE_ID
}
},
liveQuery: {
classNames: []
},
});
Sign in with Apple support was initially released in Parse Server 3.5.0. However significant improvements and bug fixes have been made subsequently in 3.7.0, 3.8.0 and 4.2.0.
The latest version supported by Sashido is 3.6.0, however they haven't added support for Sign in with Apple yet. See the screenshot below from app settings > users > social login on 3.6.0...
Please also be aware that editing your index.js file and pushing it to your private Sashido GitHub repo will not change the Parse Server config. This facility is purely intended for local development use.
I would suggest you contact Sashido and ask them to add support for Sign in with Apple - ideally on Parse Server 4.2.0 this way you will get the latest improvements.

How to have the refresh token?

I need to use Google Play Android API, i follow a lot of instructions to be connected with the API but I block at one.(Authorization documentation)
Exactly at the step 4 when they say:
Sending a Post with this code:
grant_type=authorization_code
code=<the code from the previous step>
client_id=<the client ID token created in the APIs Console>
client_secret=<the client secret corresponding to the client ID>
redirect_uri=<the URI registered with the client ID>`
I specify i use serverless and node, how can I do to have my refresh token in https://accounts.google.com/o/oauth2/token please ?
Thank's a lot and sry for my english ^^.
Sry for this oversight, my serverless it’s just that
#serverless.yml
service: scrapper-app
provider:
name: aws
runtime: nodejs8.10
region: eu-west-3
functions:
app:
handler: index.handler
events:
- http: ANY /
- http: 'ANY {proxy+}'
and my js it’s just that too:
//index.js
const serverless = require('serverless-http');
const express = require('express')
const app = express()
//API
const { google } = require('googleapis');
const oauth2Client = new google.auth.OAuth2(
IDCLient,
Secret,
'https://accounts.google.com/o/oauth2/auth',
);
const scopes = 'https://www.googleapis.com/auth/androidpublisher';
const url = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: scopes
)}
// GET
app.get('/', function (req, res) {
res.send('Scrapper Rs!');
})
module.exports.handler = serverless(app);
I really dont know how can i do http-post using node and serverless, i succeed with a database (with curl) but not post to an url.
I didn't used Google Authentication. But I think you need to use access_type = offline
access_type Recommended. Indicates whether your application can
refresh access tokens when the user is not present at the browser.
Valid parameter values are online, which is the default value, and
offline.
Set the value to offline if your application needs to refresh access
tokens when the user is not present at the browser. This is the method
of refreshing access tokens described later in this document. This
value instructs the Google authorization server to return a refresh
token and an access token the first time that your application
exchanges an authorization code for tokens.
To set this value in PHP, call the setAccessType function:
$client->setAccessType('offline');
Source: https://developers.google.com/identity/protocols/OAuth2WebServer

Where should the service configuration go in meteor? At the client side or at the server side?

I'm working on a custom login-with-linkedin button. I have accounts-base, accounts-oauth, and pauli:accounts-linkedin packages. I have used the client id and the secret from the linkedin developers site as follows
Meteor.startup(function() {
ServiceConfiguration.configurations.update({
'service': 'linkedin',
},
{
$set: {
'clientId': 'myClientId',
'secret': 'mySecret'
}
},
{
upsert: true
});
});
In the iron router, I've also defined the waitOn function on /login template as follows:
this.route('login', {
path: '/login',
waitOn: function() {
Accounts.loginServicesConfigured();
}
});
Now, when I click on the button, a pop-up window opens but it doesn't load the linkedin login page and it says 'ERR_CONTENT_DECODING_FAILED'.
I have written the ServiceConfiguration in the Meteor.startup function at the client side. Am I right to write serviceconfiguration at the client side? or should I be writing it at the server side?
It should be on the server-side. From the Meteor documentation here,
http://docs.meteor.com/#/full/meteor_loginwithexternalservice which says
Login service configuration is sent from the server to the client over
DDP when your app starts up
I have done service configuration successfully for accounts-google on server side as well.
It seems like there is a generic solution for this common issue
First, add the service configuration package:
meteor add service-configuration
Then, in your app:
ServiceConfiguration.configurations.upsert(
{ service: 'weibo' },
{
$set: {
clientId: '1292962797',
loginStyle: 'popup',
secret: '75a730b58f5691de5522789070c319bc'
}
}
);
I usually just put a service-config.js file with this code in the server.

Categories

Resources