I am working on a website that will allow multiple tenants using subdomains.
Accounts will be able to add their own subdomains, as long as they don't already exist; eg:
http://tenant1domain1.mywebsite.com
http://tenant1domain2.mywebsite.com
http://tenant2domain1.mywebsite.com
http://tenant2domain2.mywebsite.com
I am also adding in the ability to sign in using a number of oauth providers (google, microsoft, azure ad etc) using passport.js.
All these services will all callback to the main domain (mywebsite.com/login/google/callback) and I need to identify the subdomain of the login request to redirect the user.
As a single user can have multiple subdomains, I can't easily store this against their user record.
I'm running into a problem at the moment where I can't find a way to persist the tenant information past the passport authenticate stage.
I tried using session variables but the session is reset at the callback stage and loses any information I've stored there.
I did think about adding the subdomains as allowed callback urls against each service then just setting the callback to the subdomain but this quickly becomes unmanageable.
Is there any way to make passport.js keep existing session variables intact or to use another method to transfer the tenant information?
Not a complete answer, but there's a design pattern that keeps &redirect=/url-after-login as a URL query parameter when moving to a login page. After successful login, the login handler then redirects back to this url. The url can be chosen based on the user or the originating page.
Could this work in your situation? Obviously this needs some research on how to implement it in passport.js. Sorry, I can't offer working code.
Related
I want to edit the reply URL in my user flow. How can I do this? This is a reset password user-flow. Is this even possible or do I have to create a new user flow from scratch?
You can't edit it.
But what you can do is have lots of reply URL in the app. and then pick from the dropdown.
Those URLs are tied to the Application Registrations, each app registration can have multiple return URLs (as you're showing in your screenshot).
If you want to add another URL to that list you need to add it to the app registration for your LoginAppAndWeb application. The Microsoft Docs explain how to add an app registration, you likely just need to find the existing one for your app and update it.
It's down to the relying party (your actual LoginAppAndWeb app) to pass up the correct return URL as part of it's /authorize request, B2C will then redirect to that URL at the end of the journey provided it's in the list you've set up in the app registration.
Often, relying parties will have a single return URL so there's a single point B2C redirects to that processes the B2C tokens, then they'll have a separate way of redirecting the user on to another internal URL afterwards. That could be something that's passed as part of the state parameter or it could be something that's stored by the browser (e.g. in a cookie), the client library you're using to interact with B2C will likely have a standard way of doing this.
I'm working on a react app where the pages can be used both by authenticated and anonymous users. The pages show more features for the authenticated users.
If a user previously has signed in and revists the website, I want the user to be automatically authenticated, and am struggling to achieve this.
I'm using redirect methods because I don't believe popup is working well on phones (is that assumption correct?).
I have tried storing the homeAccountId in local storage and use that to get the account used and then calling login in the msal instance. I also set up a addEventCallback and listen for EventType.LOGIN_SUCCESS which I use to set some internal state about the logged in user.
I have tried using MsalAuthenticationTemplate but strangely this doesn't invoke a login. I have also tried to detect if this is a "first run" and then invoking the login, but that doesn't work all the time. Sometime I get a SSO error indicating I should provide a login_hint or sid which is not possible because I use B2C.
If I don't do anything the user can click the login button and if the user has a valid cookie with B2C the user is logged in without providing credentials which is a strange behavior for the user because my website indicate the user is not authenticated (and show no logout button).
So I can't really get this to work and are wondering if somebody has a concept for achieving this?
Please checkout the msal-react samples which all demonstrate the behavior you're looking for. The MsalAuthenticationTemplate would be the recommended way to do this and if you're still having issues getting this to work after reviewing the samples I would recommend opening an issue on our repo with code snippets so we can take a closer look at what's going on.
Also using localStorage, if you're not already, would help to maintain application state between browser sessions. sessionStorage is the default.
As for B2C not asking for credentials; server state is separate from client state. You can be signed in on the server without the application knowing about it. Until your application makes a request to the B2C server your application will show that a user is not signed in. If a session already exists on the server when you make a login request, the server may redirect you back to your application without asking for credentials again.
Basic scenario: Azure AD is used as just an authentication provider a web app, the identity retrieved from azure is matched by email to a local identity and a forms auth cookie is issued for api authorization against the app's webapi.
Problem: If a user has multiple azure accounts, they may be pre-authenticated when they come to my app. In this case, when the redirect back to my app occurs there may be no matching user and login cannot complete.
Desired Solution: If the cached azure account is invalid for my app, I would like to direct the user back to the microsoft login page with a chance to manually type in their credentials
How do I achieve this, and is there something wrong with this flow? It seems currently the only way for the user to get into my app is to go to azure and log out of the bad account. What other methods could achieve a better user experience? Should I use the auth token from azure and log the user out programatically and then back to azure for another go around? Can I hint for azure to prompt the user even if they are logged in already?
I discovered that I really wanted the prompt=select_account flag on the redirect to azure, but the library I was using made it difficult to determine how to set this. I am using the ms-adal-angular6 library, which is a wrapper for azure-activedirectory-library-for-js.
After digging through the code I found a config property that was not documented called extraQueryParameter which when I set to "prompt=select_account" got the behavior close enough to what is needed.
Ultimately the user must select their account every time, instead of just when the account is wrong. I could most likely get tricky with the error response and redirect back a second time with prompt=select_account to get the behavior I was looking for, although the library doesn't make it easy to change this on the fly either so I may stick with it always on.
I would like to use Active Directory with a REST API Express backend: users would fill out a username and login form on the client side, and get authenticated with their Active Directory credentials, through the backend. Then, based on their user groups, they would see certain information. I have tried the node package passport-windowsauth, but I am not able to authenticate, possibly because I don't know what the bindDN or bindCredentials are. I have also tried node-sspi, and had better luck with this, but the issue with this is that it's only server-side, and as far as I can tell, I can't create a form that would then allow the user to authenticate from the client side. I am hosting this site on IIS, and using iisnode for the backend. How can I can achieve this Active Directory authentication with Node/Express server-side and a client-side login form, or in other words, not a .NET application?
Active Directory (AD) authentication is accomplished by binding to the Active Directory with credentials (not the credentials from the User form) supplied by your AD engineers. After binding, AD is searched for matching credentials (from the User form).
Basically you need to talk to your AD engineers about what you should use.
Then you need a /login/ route the user form sends to, the route accomplishes the login (AD bind, authentication) and returns to the client.
A simpler workaround can be to bind to AD with the credentials entered into the login form - a successful bind means the user is logged in. I would, again, talk to your AD engineers about how they prefer this to be done. I've run into problems in the past where it's taken a long time to authenticate users after binding so we used this as a workaround.
You might ask if your AD already has single-sign-on options - maybe they use Shiboleth or something similar.
You should try that package : https://www.npmjs.com/package/ad I'm not sure it will meet your requirements, but it's a very easy t work with Active Directory in a node/express back end.
I'm learning Node, doing authentication stuff at the moment with passport.
Say my server has 2 pages, a public home page with various login options, then a super-secret page(and perhaps more) that is only accessible after authenticating.
If I'm only going to be using 3rd party strategies, is there any reason to have a database?
I know that you'd obviously need one for local user's id and pass, but if the server exclusively relies on 3rd party authentication, would session persistence be enough things to work? Or are there still various things that you would need to save for some reason (apart from logging) ?
Could you do without a database, sure... but in this case what is the point in authenticating at all? All you would be proving is that the user has a Google account which anyone can set up for free in a matter of minutes.
If your content is super secret then chances are you want to have a database of users (email addresses and the like) that have permission to see the content. By authenticating through OAuth you will be given an access token that will allow you to fetch the authenticated users email address. This can then be looked up against your user table to see if the user is registered and if your app enforces it, check whether the user has access to the page requested.
OAuth is proving that this person is the owner of the Google/Facebook/Twitter/Github Account. You can use this knowledge to sign someone in against a database of "local accounts" based on email used at sign up, assuming you validate the email on sign up locally.