I have a SPA App (VueJS) which uses Azure B2C with MSAL to authenticate users. Authentication works just fine.
But what does not work is, that the user is not kept logged in.
As long as i use the app, everything works just fine. But when i start my app the next day i have to relogin (or just reselect the account I want to use), but I would like to have the same user experience like for example the azure portal. I can revisit the portal after one week and do not have to relogin.
How can i achieve this behavior with MSAL? Is this even possible with this library? The library uses the implicit flow.
Is there another library i can use where this works?
Generally, browser-based applications shouldn't keep users logged in, since activity, such as a password change or reset, at the identity provider can invalidate a persistent session and should force an interactive login.
You should consider the "keep me signed in (KMSI)" capability that has been enabled for custom policies.
Before the answer...
I think you'll likely need to expand on what's happening by looking at a network tracing tool. Also, as the other answer said, KMSI will help but likely isn't the only problem here. I recommend looking if the cookie is being set (check below), your app is successfully getting ID, Access tokens, and check this state in subsequent auth requests.
Basics
SSO with MSAL.js is absolutely possible and should occur without much configuration. For some background in browser-based apps implementing authentication, achieving SSO is a factor of cookies/sessions rather than tokens/token management.
How this works
When your single page app redirects the user to the Azure AD B2C sign in page and the end user successfully signs in, Azure AD will set a cookie in the browser of that end user. Then, when your app wants to get an ID token or Access token for the user (assuming the existing one from the initial sign in is expired), MSAL is able to launch a silent i-frame in the background, redirect to the Azure AD site with special query parameters (prompt=none), and utilize the cookie that was set earlier.
Related
I need to login to Auth0 without login prompt on my intranet under certain circumstances.
I have a very particular use-case, where I have created a very special user in auth0 called "analytics" which has access to some of our analytics in Tableau.
I created it, so I know the login password and can create refresh tokens with unlimited life.
I had to create this user in auth0 and have it managed by auth0 because that's how our company access Tableau and I can't change this policy.
In another web application, which doesn't use Auth0 at all and has its own authentication methods, I need some users to have access to the ressources that the "analytics" user can access. (there also, no way to change this web application to use Auth0, because that's another company policy and I can't change it)
To achieve this, I have no choice but to allow all logged in users of the web application to be also automatically logged in as "analytics" in auth0.
Since this is an intranet, it is perfectly ok to hardcode a refresh token or login password. Also there's nothing too confidential about the analytics in question.
I know how to use the refresh token to call an API, but I don't know how to use it to "login" the user, e.g. his browser has the right cookie so auth0 knows that his browser is indeed him.
Is there any way to achieve this ?
I don't understand very well the OAuth 2.0 protocol, hence my question.
From the Valance documentation it looks like the user is always required to enter credentials at the D2L site. Is there a way for Valence to be used, without the user re-entering credentials, when a user is already authenticated by the originating webapplication? Is some type of SSO available?
Yes, In the typical configuration for SSO between a web app and the Learning Suite the same authentication service is used (either the Learning Suite itself, or a separate authentication service , or possibly the webapp that is calling in is also acting as an authenticator in the case of a portal). If any of these scenarios apply, SSO will work as follows:
Authentication is done within the browser so if the user is authenticated already and goes to the authentication service it will already have the session cookies associated with the authentications service. Therefore when the auth step is triggered it will be pass through -- meaning the user is not prompted for credentials (on the first use the user will be prompted to allow access to this app).
Additionally note that Valence APIs do not use session tokens that are subject to hijacking and instead uses ids and keys (http://docs.valence.desire2learn.com/basic/auth.html) that are used to perform signatures. As a result those keys are long lived. Apps do not need to reauthenticate the user to the LMS if they still have keys from a previous execution of the app (these keys will be reset in certain circumstances so callers must be prepared to respond to a reset key). As a result you would not typically reauthenticate a user to the Learning Suite every time the user has a session.
(if the above does not apply other SSO scenarios may possible)
Currently we are not using OAuth with our apps but we are working on making the shift, we have direct login and capture the user/pass that was entered and store those. We then turn around and use the stored credentials for a feature that allows the user to open a record within Salesforce.com, we pass the user/pass in to the login endpoint along with a starting URL to the specific record, this works great and is a well liked feature as it is a simple SSO from the App to Salesforce.com where the user can see all data that may not be visible within the app.
Moving to OAuth 2.0 and using the standard webflow, we no longer can capture the user/pass, which is actually a good thing as far as security is concerned. We would however like to keep this functionality, is there anyway of SSO'ing into Salesforce.com by passing along one of the OAuth tokens or some kind of sesson id?
After reading more and thinking about what OAuth accomplishes I feel like this probably isn't possible being that the tokens obtained are meant to be used only with the API and not with the front end system. I hope that I am wrong though and there is a way to login to the front end using these tokens.
EDIT
Ok I am editing to hopefully make this more clear. Currently user's authenticate using the login() API method with their user/pass, we store this user/pass locally (not ideal). We then sync a subset of data that the users can access anytime within the app, being that it is a subset, we have a feature to "SSO" to the Salesforce.com front-end. This simply opens Salesforce.com in a web-view (UIWebView) using the URL https://ns8.salesforce.com/?pw=PASSWORD&un=username#example.com&startURL=/recordId. This will log us in to Salesforce.com and open the specified record.
Moving forward we want to use OAuth 2.0 with the web flow so that we aren't handling the user/pass and so that we do not have to deal with Security Tokens or opening specific IP ranges to allow login without a Security Token.
With that said, is there anyway to use the tokens/credentials received from the OAuth authentication to open Salesforce.com, automatically log the user in, and goto a specific record?
I may have mis-used "single sign on" before, but in a sense, this simulates an SSO from our App to Salesforce.com, in that our users can touch a single button within the app and be logged in to the Salesforce.com web interface.
When you request an OAuth token, you can specify what scope it has, options include api only (the original type of tokens), or other options which include the ability to use the token with the UI pages. (see the scope parameter detail in the help). One of the still missing peices is a way to bootstrap the UI with that token when all you can do is tell a browser/webview to goto a URL, but a widely used (but unsupported) way is via frontdoor.jsp, e.g. you'd open https://{instance}/secur/frontdoor.jsp?sid={the_Access_token}&retURL={optional_relative_url_to_open} remember to URLEncode the 2 values.
So I think you are saying your application uses the SFDC username and password to just authenticate to retrieve a record from SFDC to display in your app?
IF this is correct - which I think it is - then you could just use the standard Salesforce Single Sign On system to authenticate. There is a guide here which outlines the process of setting up a SAML SSO system with Pat Patterson writing an interesting feature on how the security system works here. He has also written a great blog post on DeveloperForce here about the nitty details of OAuth in general for Force.com and not just the SAML setup. I have used the OAuth system in an iPad app against SFDC and it works quickly and easily. I can't see why your system should be unable to use the protocol as you desire.
Direct access into Salesforce is a key benefit of SSO and definitely provided. I'm not sure where you read that SSO in Salesforce is API only. From the SSO PDF pbattisson linked for you:
With single sign-on, users only need to memorize a single password to
access both network resources or external applications and Salesforce.
When accessing Salesforce from inside the corporate network, users are
logged in seamlessly, without being prompted to enter a username or
password. When accessing Salesforce from outside the corporate
network, users' corporate network login works to log them in. With
fewer passwords to manage, system administrators receive fewer
requests to reset forgotten passwords.
OAuth 1 & 2 are both supported, though I'm a fan of OAuth 2 since 1 has really finicky additional steps involving the order of parameters and their encoding sequences. I recently wrote an Apex-Twitter integration and quickly realized it wasn't going to be as easy as Facebook, which uses OAuth 2.0.
But in your case it sounds like you just want to provide users with the ability to actually login to Salesforce and go to a specific landing page once authenticated. This is definitely doable.
Good luck!
Goal:
Allow a user to authentication with Facebook into an iOS application which requires access to a protected web service that I'm running.
Assumptions:
There is a native authentication (and registration) system in place for those users that opt not to use Facebook for sign in.
Details:
Assume we want to offer the option for a user to sign in with Facebook without creating a separate account/credential for our system.
Because we support our own native auth mechanism (username and password) we have our own user IDs and issue an authentication token that is used for subsequent interactions after the initial credential validation.
I'm surprised that Facebook doesn't have best practices for this in their developer documentation. All the existing documentation is either assuming you are building FB auth into a website, or a standalone mobile app with no service that requires authentication.
Here's my initial thoughts on how this would be designed but want validation on whether it's correct.
Client pops the Facebook iOS Login
UI User signs in with Facebook credentials and gets access token
iOS App passes access token to our server
Our server talks to FB graph API using access token to (a) validate the token and (b) get the FB user ID for that access token.
e.g. Our server would call https://graph.facebook.com/me/?access_token=XYZ which would return profile info in a JSON object
Assuming it's valid, our server extracts the User ID from the JSON object and checks whether the user already has an account. If so, we issue our own auth ticket to client to use for that session. If user doesn't have an account, we create a new one with the Facebook User ID, assign our own unique UserID and issue our auth ticket.
Client then passes auth ticket back on subsequent interactions that need authentication.
This seems like the right approach to me but not sure if I'm missing something insanely basic and going down the wrong (complicated) path.
I just dealt with this myself, and here's the part that bit me:
In your step 5... It's possible for a user to register for an account with you entirely separate from their Facebook ID, right? Then some other time they log in with Facebook.... And you just created them a second account and lost their first one.
There needs to be a way to be logged in to your web service, then log in to facebook, and capture the association between the facebook ID and the local account.
Apart from that, your plan sounds solid.
Update: Facebook has added a doc outlining such a scenario HERE
Use https to transmit the auth token to your server, as stated by Facebook
Sharing of Access Tokens
Our Data Policies explicitly prohibit any sharing of an Access Token
for your app with any other app. However, we do allow developers to
share Tokens between a native implementation and a server
implementation of the same App (ie. using the same App ID) as long as
the transfer takes place using HTTPS.
One problem I can see with this strategy, is that somebody can give you an access token obtained for a different facebook app. As far as I know, there's no way to verify that the access token is for your application, so you'll just go on and use it.
It doesn't sound very harmful, though. Generally people/apps try to protect the access tokens, rather than sharing them.
One possible exploit of this would be, for somebody to create their own site or mobile app, obtain access tokens for their users and try to authenticate them, using your API. If this succeeds (the user is has a facebook account in your site), the malicious site will be able to use your API impersonating the user.
It's a bit of a long shot, but I think it could work.
Edit: It looks like there is a way to validate the access token after all. See the answer by #Daaniel on question Get application id from user access token (or verify the source application for a token).
your solution totally works.
Maybe an alternative: why not just get the email on the client from the initial social service request and send to your web service? The web service could just store the email, and maybe a social_provider as well. I understand that your web service will not be able to validate where the email came from, but isn't there a high-trust relationship between your web service and your client? If there is, seems like you can depend on the email coming from the right place. Someone please let me know what obvious thing I'm missing that makes the email-based approach silly...
I'm trying to use OAuth with .NET (DotNetOpenAuth) to send updates to a Twitter account via a web application. I understand the basic workflow of OAuth and Twitter.
Where I'm confused if is it useful in a server web application? I don't want any user interaction.
But how it seems after an application start, the request token needs to be recreated and also an access token. This involves user interaction.
What is the correct workflow for my case?
Storing the request token or access token in config file?
Or the easist way, using HTTP basic authentication?
Thanks
If I understand you correctly your application will not be interacting with Twitter on behalf of your users but will be acting as the Twitter account for your application.
In this case there are 2 main factors to consider.
1) Do you want "from API" attached to each status as will be if you use basic auth or your applications name will happen if you use OAuth.
2) Do you want to put in the extra effort to implement OAuth.
If you decide to go with OAuth you would store your apps consumer key/secret and the accounts access token in configuration just like you would store the accounts screenname/password.
Your "request token needs to be recreated" phrase suggests you might be running into the problem where every time your user visits you need to re-authorize to Twitter, and perhaps you're looking for a way to access the user's Twitter account while he's not at your web site, and how can you do this when their token isn't fresh from being re-authorized. Is that right?
If so, the user isn't supposed to have to re-authorize Twitter every time they visit your site. The token is supposed to last a long time, which would also allow your site to access their Twitter account when they are not directly interacting with your web site. The problem may be that you haven't implemented the IConsumerTokenManager interface, but are instead using the default InMemoryTokenManager, which is for sample use only, since this memory-only token manager loses tokens every time the web app is restarted. Your own implementation of this simple interface should store and read the tokens out of some persistent storage such as a database.