React private route with Firebase federated auth? - firebase-authentication

I've seen a lot of examples on how to implement private routes with classic email/password authentication, but I'm not sure how to do the same with federated auth that redirects to the provider's UI. Meaning to say, when the auth provider redirects back to the app, is there a way to figure out what the private route that got replaced by the auth route was?
unauthenticated user -> /some-private-route -> /login -> /facebook -> /login -> how to get to /some-private-route?

It looks like adding a private route URL to the login page is sufficient to maintain the state between the request and redirect result.
unauthenticated user -> /some-private-route -> /login?redirect_uri=/some-private-route -> /facebook -> /login?redirect_uri=/some-private-route -> /some-private-route

Related

How to redirect to the original path user navigated to after AAD authentication?

I have a pretty straightforward ASP .NET Core web site that uses Azure AD + OpenID for user authentication. Inside Azure I've added "https://my-site/signin-oidc" as a Redirect URI and inside my app settings I've set my CallbackPath to "/signin-oidc".
The problem is after authentication the browser always redirects to the home page.
For example the user will enter the following url into their address bar:
https://my-site/#/foo
They'll then be redirected to the azure sign-in page which has a uri like so:
https://login.microsoftonline.com/.../oauth2/v2.0/authorize?client_id=...&redirect_uri=https%3A%2F%2Fmy-site%3A64199%2Fsignin-oidc&[...]&sso_reload=true#/foo=
(Note where the '#/foo' fragment is placed)
After authentication succeeds they end up at the home page (https://my-site/).
Is there anyway for me to preserve the original URI and redirect the user to it after auth succeeds?
Try using the post_login_redirect_url query parameter for this.
If you want to automatically navigate the user to #/foo' after logging in, you can set your login redirect to ~/.../authorize?post_login_redirect_url=/#/foo.

Cypress cannot request API or display content with the new auth0-spa-js package

I tried to sign in to Auth0 with the new package (https://github.com/auth0/auth0-spa-js).
Attempt 1: I did try a best practice that uses cy.request() but seem like new the auth0-spa-js package now requires a random state string (which I don't have and it was generated from loginWithRedirect function) in the request URL. So I can not call sign in API of Auth0
Attempt 2: I set "chromeWebSecurity": false, I click sign in button -> my web is redirected to Auth0 page, the URL is load correctly but Auth0 refused to display 'auth0 url' in a frame because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'none'".
Does you guy have any solution for this situation?
For now, this is the workaround solution of me.
Disable chrome security in Cypress config.
Login through the auth0 page (we will redirect to log-in page and log out due to the fact that I cannot generate the random state in the new auth0 package: auth0-spa-js)
Note: If you’re not custom login page in auth0, use the classic page in Universal Login. I found that the new UI of Auth0 login page has a lot of security enhance that prevents us render auth0 in an iframe. (like image below)
Auth0 seting
Then, Go to Auth0 -> Tenant Setting -> Advanced -> Enable Clickjacking Protection to allow auth0 load in an iframe.
Enalbe Clickjacking
Ok, that all the step that I did to make it work. Hope this help you

openidconnect.server, third party providers & redirection

I'm currently building my an openid connect server using https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server and asp.net core identity as a backing store. I'm aware of the protocols, the flows and the security holes.
The current setup is as follows:
[server] - the authorization server & resource server
[front-end] - an angularJS application
[third-party-provider] - Google
[external-app] - a second application which want to use a token from [server]
Both the [front-end] and the [external-app] are registered as clients for the [server]. So, they are allowed to retrieve tokens. The login page is build in the [front-end].
Keep in mind, that the login page etc is shown by the [front-end] application (instead of returning a AuthView from the AccountController)
Imagine i'd want to login with the [external-app] to get an identity from [server]. The login page is shown by [front-end]. Then the flow will be the following:
1. [external-app] -> http://[server]/account/authorize?client_id=[external-
app-clientid]&response_type=token&redirect_uri=http://[external-app-
redirecturi]
2. [front-end] -> matches route -> show login page
3. [front-end] -> user clicks on login with google
4. [front-end] -> redirect to 'http://[server]/account/authorize/connect?
provider=Google&redirect_uri=http://[front-
end]/account/thirdparty/authorized&response_type=code&client_id=[front-
end-clientid]
5. [server] -> no identity found, save request in session and let the user
login at the [third-party] (using ChallengeResult and also passing in the
request id which was stored in session)
6. [third-party-provider] user logs in
7. [front-end] -> http://[front-end]/account/thirdparty/authorized recieved
the code
8. [front-end] -> exchange authcode for token with [server] using
http://[server]/account/token&grant_type=authorization_code&code=
[code]&redirect_uri=http://[front-
end]/account/thirdparty/authorized&client=[front-end-clientid]
9. [server] -> generate claims and return token
10. [front-end] -> token recieved
A thing i'm missing (and it might be an implementation flaw, thought flaw or whatever) is that i need to redirect back to the [external-app] with the given token. Do i need to do that on the [front-end]? It feels off and i'm kinda sure i'm mixing / matching stuff wrong. Can anyone help me out?
Thanks in advance!
PS yes, i know, should be https. Above is for example purpose ;)
With interactive flows like the implicit flow, the important thing to remember is that you have to redirect the user to the identity provider's authorization endpoint so it has a chance to prepare an authorization response.
You're free to decide what happens between the moment your identity provider receives the authorization request and the moment it returns an authorization response, but you can't redirect the user from your "front-end" application directly to the "external application" because it has no way to generate an authorization response (it's not its role).
Consider reworking your flow so your front-end app redirects your users to the authorization server, that will itself redirect them to your external app.

loopback protected routes/ensure login

How do I ensure that a user is logged in before I render a view using loopback?
I can loggin in the front end using my angular app. But I wanted to block anonymous users from viewing the page.
I thought it would be a header, something like headers.authorization_token, but it does not seem to be there.
I am looking for something like connect-ensurelogin for passport, without having to use passport.
This is the $interceptor that solves your problem.
This code detects 401 responses (user not logged in or the access token is expired) from Loopback REST server and redirect the user to the login page:
// Inside app config block
$httpProvider.interceptors.push(function($q, $location) {
return {
responseError: function(rejection) {
if (rejection.status == 401) {
$location.nextAfterLogin = $location.path();
$location.path('/login');
}
return $q.reject(rejection);
}
};
});
And this code will redirect to the requested page once the user is logged in
// In the Login controller
User.login($scope.credentials, function() {
var next = $location.nextAfterLogin || '/';
$location.nextAfterLogin = null;
$location.path(next);
});
Here is one possible approach that has worked for me (details may vary):
Design each of the Pages in your Single Page Angular App to make at one of your REST API calls when the Angular Route is resolved.
Secure all of your REST API Routes using the AccessToken/User/Role/ACL scheme that LoopBack provides.
When no valid Access Token is detected on the REST Server side, pass back a 401 Unauthorized Error.
On the Client Side Data Access, when you detect a 401 on your REST Call, redirect to your Logic Route.
For the smoothest User Experience, whenever you redirect to Login, store the Route the User wanted to access globally
(localStore, $RootScope, etc.) and redirect back there when the User
Logs in and gets a valid Access Token.
Here is the LoopBack Access Control sample: https://github.com/strongloop/loopback-example-access-control

How to implement login in a Backbone app

I have a Backbone app where we know start to implement the login. Till now I we had no login and the app starts with creating all relevant models and collection on start. Now the API demands a session cookie to response.
What would be the better solution:
having a login.html that forward to the app.html after a successful login
having the login to be part of the Backbone app with an own route
In both solution, how can I prevent that the user sees the login dialog again, just by pressing the back button?
I use the standard way of login handling, a simple login page separated from the application.
/admin/ in this route I have a simple middleware checking for the user session if the user is not authenticated, he is redirected over /admin/login.
Once the user obtains a valid session he can freely go to /admin/ where my application resides. The same apply when you need to authenticate users with some OpenID or OAuth provider.
There is no use in handling authentication in the browser since it's too much simple to handle it in your backend. In fact in my backend I have only three standard routes:
/* accessible routes */
/admin/login
/* protected routes: */
/admin/
/admin/(...)
/admin/logout
For the back button issue, you just need to know if the user already have a valid session token, then redirect/trigger to the right route (beware of redirection loops)