i am building an Meteor App and using these packages for login/accounts:
accounts-base#1.3.6
accounts-password#1.4.2
accounts-google
service-configuration
I set up the service configuration like this:
ServiceConfiguration.configurations.upsert(
{ service: "google" },
{ $set: {
clientId: "xxx.apps.googleusercontent.com",
secret: "xxx"
} }
);
Is it possible to restrict the emails?
If you have a company registered at google and they have their own email adresses like
peter_parker#companyname.com
is it Possible to just allow Login with google with googlemails from #companyname.com?
And if yes, where do i have to configure those?
I found the solution i was looking for in another thread
Limit Google Sign-In to .edu accounts in Meteor
_
Nevertheless many thanks
Related
According to the firebase official documentation, to set up a custom route like /link in your custom domain like example.com, I need to use firebase hosting already and do the following configuration there:
"hosting": {
// ...
"appAssociation": "AUTO",
"rewrites": [
{
"source": "/link/**",
"dynamicLinks": true
},
]
}
But I'm not using firebase hosting, and Obviously, I don't have such a configuration.
So I can have the same result with no firebase hosting?
This has worked for me in the past with custom domain names for dynamic links: when you get the error in the dynamic links page, open the Authentication(you don't actually need to use firebase authentication on this project for this to work), go to sign in method, enable Email/Password then scroll down to Authorized Domains and add your domain as an authorized domain. This won't affect your current website or email. Go back to hosting and try to set up the URL prefix again.
I want to implement frictionless sign in process for my web app.
After some searching, I have found that there are two solutions available :
Google Smart Lock.
Credential Managment API.
My question is, What is the difference between the two API's (if any) and what are the possible use cases for both of these.
From what I have understood, both allow us to save account related info. But the advantage with smart lock is, that saved credentials can be used in corresponding android apps as well.
Thanks !
Note:
I intend to support login from multiple sources (google, facebook, linkedin etc.) , not just google.
TL;DR the one-tap sign-up / auto sign-in library includes Credential Management. You should probably just use the library: https://developers.google.com/identity/one-tap/web/get-started
Details
The JavaScript library supports account creation with Google Accounts (via a streamlined inline UX that can be shown on content pages instead user having to navigate to a traditional button-based UX and figure out which which button/option to pick and interact with pop-up/redirect)
And for returning users, the library allows you to programmatically retrieve on page load both tokens for existing one-tap / traditional Google Sign-In users as well as passwords via the Credential Management API in browsers that support it. You can do this with code such as the following:
const retrievePromise = googleyolo.retrieve({
supportedAuthMethods: [
"https://accounts.google.com",
"googleyolo://id-and-password"
],
supportedIdTokenProviders: [
{
uri: "https://accounts.google.com",
clientId: "YOUR_GOOGLE_CLIENT_ID"
}
]
});
retrievePromise.then((credential) => {
if (credential.password) {
// An ID (usually email address) and password credential was retrieved.
// Sign in to your backend using the password.
signInWithEmailAndPassword(credential.id, credential.password);
} else {
// A Google Account is retrieved. Since Google supports ID token responses,
// you can use the token to sign in instead of initiating the Google sign-in
// flow.
useGoogleIdTokenForAuth(credential.idToken);
}
}
See the documentation for details. The library does not currently support non-Google/password forms of identity, you'd have to implement sign-in flow with other mentioned identity providers SDKs yourself at the moment.
Also note that any sign-ins associated with a Google Account (OAuth token-based or stored and sync'ed password) will be available across Android and Chrome (and the rest of the for token-based accounts).
Please leave comments for any follow up questions.
I'm aware of how to create a Google authenticated app via with google-signin-client_id 3089273xx-xxxxxxxxxxxx.apps.googleusercontent.com & <script src="https://apis.google.com/js/platform.js" async defer></script>, but the problem here is that, I have not been able to LIMIT the login to just my company's G Suite instance.
The app I have is a "serverless" JS bundle hosted on S3. The logged in Google token is tied to an AWS role that accesses sensitive resources.
So typical solutions to check the email of googleUser.getBasicProfile() or pass a hd parameter don't make any security sense since they can be manipulated with browser dev tools IIUC.
Is there some other Google API I could be using or strategy I could apply? I imagine the solution would come in the form of a special google-signin-client_id for my company's domain which is hosted by G Suite. This is how it's tied to the role at AWS:
I'm aware I could setup duplicate my users in AWS "user pools" and use Cognito, but I am trying to have a "single source of truth" for the company's employees & ease the administration burden.
UPDATE: This answer is insecure as if you simply remove hosted_domain, you can authenticate with any Google login.
After straying upon https://developers.google.com/identity/work/it-apps & using GAPI directly I found I could do a
GAPI.auth2.init({
client_id: CLIENT_ID,
hosted_domain: 'example.com'
})
And then as the documentation advises, you setup Manage API client access
So now only users of #example.com on Gsuite can access this JS app! This took weeks to figure out. So just to conclude, how to authenticate using Google on a AWS powered serverless app:
Setup a client ID via OAuth client ID with your whitelisted origin URLs from https://console.developers.google.com/apis/credentials
In AWS IAM setup a Role with Google as the (web) Identity provider with the client ID
Add your client ID https://admin.google.com/AdminHome?chromeless=1#OGX:ManageOauthClients as documented here https://developers.google.com/identity/work/it-apps to crucially limit your application to your company's domain.
So now we have a statically hosted App limited to only company employees to access sensitive paid AWS APIs.
I tried 3 different options, the first one worked for my scenario:
First Option - Validating Google Id Token on each call on lambda side
I always pass the id_token as a header on the client calls(web and mobile apps).
"acceptableHds" Is the list of allowed domains.
const oauth = new Auth.OAuth2(CLIENT_ID_WEB, CLIENT_SECRET);
oauth.verifyIdToken(token, null, (err, ticket) => {
if (err) {
return reject(err);
}
const payload = ticket.getPayload();
const tokenIsOK = payload &&
payload.aud === CLIENT_ID &&
new Date(payload.exp * 1000) > new Date() &&
acceptableISSs.has(payload.iss) &&
acceptableHds.has(payload.hd)
return tokenIsOK ? resolve(payload.hd) : reject();
});
Second Option - Validating Google Id Token once on lambda side
I started this alternative way but I didn't finished because the first solutions fitted to my needs and the milestones was close(it needs a indentity pool):
1)Send the id_token to the lambda function and validate it on Google API(here is where you can check the domain using the code above)
2)Call the cognitoidentity.getOpenIdTokenForDeveloperIdentity on the lambda side using the id_token coming from the browser
3) On the client, call any of the Cognito or STS functions like assumeWebIdentity, AssumeRole using the tokens returned from getOpenIdToken.
function getCognitoToken(id_token) {
var param = {
IdentityPoolId: 'us-east-1:f7b3d55f-6b63-4097-be8f-3dc22ddec1a4',
Logins: { 'accounts.google.com': id_token }
}
return check_company(id_token).then(function (valid) {
return cognitoidentity.getOpenIdTokenForDeveloperIdentity(param).promise()
})
I couldn't finish the third step. You need use the tokens received on the second step without revealing the 'identity pool id'. If you do that and assure that the role can't list identity pool ids, it will work as intended and It will be secure.
Third Option - SAML provider
You can create a SAML provider and use SAML assertions to validate the user domain.
http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_assertions.html
I failed miserably trying to do it.
P.S.: Google Admin let you create private apps, limiting to you company domains, but It works only for mobile as far as I know
https://support.google.com/a/answer/2494992?hl=en
Hope it helps someone!
When using the meteor accounts-google package or accounts-github and others meteor asks for email and other data for example
Clicking the info icon highlighted shows
I don't need any of that info for my app. In fact I don't even need email.
Is it possible to use those account services solely to give the user an account on my service and not request access to any of their info? At most I want their username if they have one they'd prefer but otherwise I don't need email or anything else.
Services should accept required permissions configuration.
Some services may have required permissions that are added regardless the one specified.
For example, when using Google, the profile permission, which is the basic login scope and is required in order to get the user id.
Directly calling the login service package:
The API should be:
Meteor.loginWith<ExternalService>([options], [callback])
For example,
Meteor.loginWithGoogle({
requestPermissions: ["email"],
userEmail: 'foo#bar.me',
...
});
Using accounts-ui:
Accounts.ui.config({
requestPermissions: {
google: [
"email",
"given_name,
"family_name"
],
github:[...]
}
});
The available fields are available on the server as Google.whitelistedFields.
You can take a look at the source of the MDG packages for more information.
I have completed writing the login flow for a user that clicks on a linkedin button on the homepage. It takes them to the linkedin endpoint. The user signs into their linkedin account, my app receives the access_token which I use to get the users linkedin profile details, such as they full name, email address.
Now, how can I use this linkedin data, i.e., the users unique linkedin access_token, email address in order for the user to be 'logged' into the meteor app?
I do not want to use another package, I want to build this myself. I would like help to understand what I can do from this point please.
Is this what I need to set up once I have the access_token
Template.home.onRendered(function() {
})
Template.home.events({
'click #li-logo': function() {
Meteor.loginWithLinkedin();
}
})
I'm afraid implementing your own login system from scratch in Meteor is going to be too time consuming for you. Let me point out that one of the main reasons to use Meteor is to take advantage of the ease of app development it provides and the vast collection of available packages.
Anyway, if you really want to learn the inner workings of the login system and how a properly coded linkedin sign-in should work, the best possible thing to do is to look at the source code of the accounts-base and meteor-accounts-linkedin packages.
Configure your linkedin package this way (place this in a server-only block or file):
Meteor.startup(function() {
ServiceConfiguration.configurations.update(
{ "service": "linkedin" },
{
$set: {
"clientId": "<your client id>",
"secret": "<your secret>"
}
},
{ upsert: true }
);
});
HTH!