Redirect after successful ADB2C login - asp.net-core

I'm using Azure ADB2C authentication in my ASP.NET Core web app.
Based on the claims received after the user logging in, I'd like to redirect the user to another page.
I thought I might be able to redirect the user on the OnTokenValidated event of OpenIdConnectEvents. But frankly, I'm not sure if this is redirecting the client, or redirecting the auth flow. Bottom line, it doesn't redirect the user.
public async Task OnTokenValidated(TokenValidatedContext context)
{
// ... clipped code ...
context.HttpContext.Response.Redirect("~/somewhere");
}
My event handler works otherwise--just doesn't redirect.
What is the final event received after a user successfully logs in with ADB2C?
And how, specifically, can I redirect a user?
Thanks

Related

Velusia Sample - Redirect after Registration

In the sample "Velusia" provided here Github OpenIdDict-Samples, upon most of the action the user is redirected back to the client, however upon the registration, the user is sent to the server 'home/index' page. How can I make it send a user same as the login action, back to the client?
We do have the ability to specify the SignOut redirect uri, however there is no visible option for Sign In
I could as well add in a home controller for index view a redirect to my app, however i would loose the uri I started with and would have to probably redo the request

How signin-google in asp.net core authentication is linked to the google handler?

I went into the source code but I can't see where it's wired to the handler.
In the GoogleExtensions.cs file, I see the
=> builder.AddOAuth<GoogleOptions, GoogleHandler>(authenticationScheme,
displayName, configureOptions);
But I don't understand how the route "/signin-google" calls the handler.
How signin-google in asp.net core authentication is linked to the google handler?
The question can be divided into two small questions .
How user is redirected to the url of /signin-google
How GoogleHandler process the request on /signin-google
How user is redirected to signin-google
Initially, when user clicks the Google button to login with Google Authentication, the browser will post a request to the following url:
https://your-server/Identity/Account/ExternalLogin?returnUrl=%2F
Your server simply redirects the user to Google.com and asks Google to authenticate the current user :
https://accounts.google.com/o/oauth2/v2/auth?
response_type=code
&client_id=xxx
&scope=openid%20profile%20email
&redirect_uri=https%3A%2F%2Fyour-server%2Fsignin-google
&state=xxx
When Google has authenticated the user successfully, it will redirect the user to your website with a parameter of code according to redirect_uri above.
https://your-server/signin-google?
state=xxx
&code=yyy
&scope=zzz
&authuser=0
&session_state=abc
&prompt=none
Note the path here equals /signin-google. That's the first key point.
How GoogleHandler process the signin-google
Before we talk about how GoogleHandler goes , we should take a look at how AuthenticationMiddleware and AuthenticationHandler work:
When there's an incoming request, the AuthenticationMiddleware (which is registered by UseAuthentication() in your Configure() method of Startup.cs), will inspect every request and try to authenticate user.
Since you've configured authentication services to use google authentication , the AuthenticationMiddleware will invoke the GoogleHandler.HandleRequestAsync() method
If needed, the GoogleHandler.HandleRequestAsync() then handle remote authentication with OAuth2.0 protocol , and get the user's identity.
Here the GoogleHandler inherits from RemoteAuthenticationHandler<TOptions> , and its HandleRequestAsync() method will be used by AuthenticationMiddleware to determine if need to handle the request. . When it returns true, that means the current request has been already processed by the authentication handler and there's no further process will be executed.
So how does the HandleRequestAsync() determine whether the request should be processed by itself ?
The HandleRequestAsync() method just checks the current path against the Options.CallbackPath . See source code below :
public abstract class RemoteAuthenticationHandler<TOptions> : AuthenticationHandler<TOptions>, IAuthenticationRequestHandler
where TOptions : RemoteAuthenticationOptions, new()
{
// ...
public virtual Task<bool> ShouldHandleRequestAsync()
=> Task.FromResult(Options.CallbackPath == Request.Path);
public virtual async Task<bool> HandleRequestAsync()
{
if (!await ShouldHandleRequestAsync())
{
return false;
}
// ... handle remote authentication , such as exchange code from google
}
}
Closing
The whole workflow will be :
The user clicks on button to login with Google
Google authenticates the user and redirects him to /signin-google
Since the path== signin-google, the middleware will use HandleRequestAsync() to proecess current request, and exchange code with google.
... do some other things

Prevent forms authorisation redirect in MVC when Web Api authentication fails

I'm basically a novice with Web Api, but I have finally added Web Api into an existing project and implemented a basic authorisation filter which allows me to both authenticate the user and use their identity in my apicontroller action methods.
The problem I'm having is that when the user is not successfully authenticated (their authorisation credentials are not valid) I am not able to return a 401 forbidden response as the MVC site automatically redirects to the login page and returns the html with a 302 redirect code.
I have seen fixes like:
protected void Application_EndRequest(Object sender, EventArgs e)
{
HttpApplication context = (HttpApplication)sender;
context.Response.SuppressFormsAuthenticationRedirect = true;
}
in global.asax
Which simply have not worked. Even if it had worked it would prevent the redirect for users browsing the website which I would like to keep.
Is there a way of preventing this redirect from taking place only in instances of failed authorisation with my Web Api, whilst also keeping the redirect for the main MVC site?

Redirect on successful Login using servicestack

I've recently decided to migrate over to using servicestack authentication. From what I can tell, to have a redirect after a successful login of an oauth provider, you add the url to the appSettings of your web.config, i.e. oauth.GoogleOpenId.RedirectUrl.
My question is, is there anyway to make this more dynamic so that if a user get's redirected to the log on page when trying to access an authorized page, say their profile page, that once they log on successfully they get routed to their profile page instead of what's configured in the web.config? Forms authentication did this by using a 'returnUrl' query parameter.
Any help would be appreciated.
The behavior of accessing a protected page, redirecting to a /login page (overridable with HtmlRedirect on AuthFeature or Authenticate attribute) and on successful login should automatically redirect to the previously attempted protected page.
To do this you want to specify the redirect url in the continue or ReturnUrl FormData POST variable or QueryString when attempting to authenticate with the /auth service.

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)