Set Redirect UrlAfter Login - azure-ad-b2c

I have Blazor Server hooked up with Azure B2C Cookie Auth.
services.AddAuthentication(AzureADB2CDefaults.CookieScheme)
.AddAzureADB2C(options => Configuration.Bind("AzureAdB2C", options));
services.Configure<CookieAuthenticationOptions>(
AzureADB2CDefaults.CookieScheme, options =>
{
options.Cookie.Name = "MyCookieName";
});
I'm mapping Controllers so I have Controller Endpoints to hit:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
In my Blazor Server _Host I simply am using the built in Authorize attirbute:
#attribute [Microsoft.AspNetCore.Authorization.Authorize]
On load, if the user isn't Authorized, it will redirect to B2C Sign in without issue. I can then sign in and it directs me back to the App.
However, what I can't figure out is after login how to redirect to a specific controller/action endpoint prior something like: /api/auth/mynewuser This action would then do some verification and redirect back to "/" allowing the user to continue using the Blazor app.
Given my out of the box setup pretty much... how to achieve this?
edit
Code:
https://github.com/aherrick/BlazorServerB2C
Goal is to hit this endpoint after every login/sign up:
https://github.com/aherrick/BlazorServerB2C/blob/master/BlazorServerB2C/Controllers/AuthorizeController.cs

When you sign in using Azure AD B2C, the B2C service sends a token to the "redirect_uri" .You can mention the Redirect URL used in the authentication route to a specific controller/action endpoint dynamically. This helps the app to redirect to the controller when authentication is successful.
Also, You can easily handle user is logged in or not by implementing AuthorizeView component or [Authorize] attribute.
I looked into your code Authorizationcontroller and the newuser action which is under construction.
If you can trigger on the razor page, you can use the following:
#page "/YourPageName"
#inject NavigationManager NavigationManager
<h1>xxx</h1>
.
.
.
#code {
void MethodToTriggerUrl()
{
NavigationManager.NavigateTo("PageToRedirect");
}
}
Also, please refer MS Document.

Related

Log Out B2C Hangs

Working on an app that will log internal users through AD and external users through B2C. We're using openid. The login process works great for both. Logging out of AD works fine. Logging out of B2C hangs up. Here's the method I'm using to log out:
[Authorize]
public IActionResult LogoutAsync()
{
var scheme = User.Claims.FirstOrDefault(c => c.Type == ".AuthScheme").Value;
return new SignOutResult(new[] { CookieAuthenticationDefaults.AuthenticationScheme, scheme });
}
I get https://localhost:44320/signout-oidc?state=XXXXXXXXXXXXXXXXXXXXX in the URL. Any clues as to what is happening??
Is my only option to use the logoff endpoint, like this (obviously with my information and redirect)?
https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/logout?post_logout_redirect_uri=https%3A%2F%2Fjwt.ms%2F]
I had the same issue and it was because of missing support of Razor pages. The default Microsoft.Identity.Web.UI SignOut action uses /Account/SignedOut Razor page as callback URL.
var callbackUrl = Url.Page("/Account/SignedOut", pageHandler: null, values: null, protocol: Request.Scheme);
I added Razor support in my ASP.NET Core web app, and it fixed the issue:
services.AddRazorPages();
and
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
Alternatively, you can use your own logout endpoint, which can use any action as the signed out callback URL.

How to redirect to home page after sign out in a Blazor serverside application

My Blazor server-side application is authenticated using Azure B2C. After signing out, the user is redirected to a generic page that informs that sign out was successful. How can I make the app redirect to the home page (i.e. login page) instead?
Here is a part of my authentication:
<AuthorizeView>
<Authorized>
#if (canEditProfile)
{
Hello, #context.User.Identity.Name!
}
else
{
<span style="color: white">Hello, #context.User.Identity.Name!</span>
}
Log out
</Authorized>
<NotAuthorized>
Log in
</NotAuthorized>
</AuthorizeView>
services.Configure<OpenIdConnectOptions> (OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Events.OnSignedOutCallbackRedirect = async context =>
{
context.HttpContext.Response.Redirect(context.Options.SignedOutRedirectUri);
context.HandleResponse();
};
});
This is based on an old issue here.
In the logout request, send a post_logout_redirect_uri
post_logout_redirect_uri: The URL that the user should be redirected to after successful sign out. If it isn't included, Azure AD B2C shows the user a generic message. Unless you provide an id_token_hint, you should not register this URL as a reply URL in your Azure AD B2C application settings.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/openid-connect#send-a-sign-out-request

OWIN middleware: signout without redirecting to IdP when IdTokenHint is not available

Is there anyway to signout using OWIN middleware without redirecting to IdP? Everytime i call Authentication.SignOut(), my MVC application is redirecting to IdP. It's fine if the identity token is available. However I don't want user to get stuck on IdentityServer's logout screen when identity token is gone without knowing how to come back to login screen.
It turns out i just handle LogoutRequest event on RedirectToIdentityProvider and use following lines of code to redirect user to front-channel logout page:
if (identityToken != null)
{
n.ProtocolMessage.IdTokenHint = identityToken;
}
else
{
n.HandleResponse();
n.Response.Redirect("/Account/FrontChannelLogout");
}

Dynamic Redirect after Successful Login in Azure B2C

I am developing a Single Page Application using .NET Core V2 and am using Azure B2C Authentication.
My Startup.cs has the following:
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddAzureAdB2CBearer(options => Configuration.Bind("AzureAdB2C", options));
public static AuthenticationBuilder AddAzureAdB2CBearer(this AuthenticationBuilder builder)
=> builder.AddAzureAdB2CBearer(_ => { });
public static AuthenticationBuilder AddAzureAdB2CBearer(this AuthenticationBuilder builder, Action<AzureAdB2COptions> configureOptions)
{
builder.Services.Configure(configureOptions);
builder.Services.AddSingleton<IConfigureOptions<JwtBearerOptions>, ConfigureAzureOptions>();
builder.Services.AddScoped<IClaimsTransformation, ClaimsTransformer>();
builder.AddJwtBearer();
return builder;
}
I have a Signin Endpoint which redirects to the B2C Login Page
ie.
https://login.microsoftonline.com/{mydomain}/oauth2/v2.0/authorize?p={mysigninpolicy}&client_id={3}&nonce=defaultNonce&redirect_uri={myredirecturl}&scope=openid&response_type=id_token&response_mode=form_post&prompt=login
I have created a callback endpoint of myredirecturl which checks for any error message from B2C Sign in and grabs the Bearer token.
I have set up an Azure SignIn Policy with the myredirecturl specified.
All of my controllers are then protected with [Authorize] attributes to prevent access unless signed in.
This all works fine. But I would like the following to happen:
1) If I am logged off and I enter https://mydomain/somecontroller/somemethod
2) I would like to be taken to the SignIn page (this happens now)
3) After succesful sign in I want to be redirected automatically to
https://mydomain/somecontroller/somemethod
This does not happen now, I can only be taken to the home page because there is no way I can find to pass with ReplyUrl as a query string parameter to the SignIn Endpoint and then retrieve it from the B2C Callback.
I want my redirecturl to be whatever was submitted from the browser.
If I was using standard Identity Authentication I could do:
mydomain/account/login?redirecturl=mydomain/controller/method
Found the answer:
If you include a &state={some value} parameter in the call to B2C login ie.
https://login.microsoftonline.com/{mydomain}/oauth2/v2.0/authorize?p={mysigninpolicy}&client_id={3}&nonce=defaultNonce&redirect_uri={myredirecturl}&scope=openid&response_type=id_token&response_mode=form_post&prompt=login&state=myvalue
the endpoint that B2C calls in the redirect_uri also includes this value, so you can use this to redirect the user after successful login.

Azure App Services Twitter Authentication Web API

How do you use Azure App Services to authenticate a Web API Route?
What do I need to send to the /api/test/auth route to return a 200!?
The /api/test/noauth route works fine without the [Authorize] attribute.
[Authorize]
[HttpGet]
[Route("auth")]
public IActionResult TestAuth()
{
return new ObjectResult("This requires authentication.");
}
[HttpGet]
[Route("noauth")]
public IActionResult TestNoAuth()
{
return new ObjectResult("This doesn't require authentication.");
}
I've set it up so when you hit the /.auth/login/twitter route, it will redirect to the Twitter login page, which returns to the callback URL with a Bearer token, but my bearer token is not working??
Send with Bearer Token
This returns a 401 Unauthorized error? Do I need to set up something in my code to handle Twitter Authorization?
In your twitter application,first click on Settings and change the Application Type to "Read, Write and Access direct messages".Then once your Twitter application has been updated to "Read, Write and Access direct messages", click on the Home tab, and "create your access token". If you have already created the token, regenerate it.
Also Regenerate Consumer Key and Consumer Secret.
Microsoft released adal.js to handle the grunt work of handling the tokens from authentication services. I'm struggling with the same problem using AzureActiveDirectory authentication for an App Service web api. There is a sample leveraging it with Angular, but it will need to be modified for use in an ajax call. https://github.com/AzureAD/azure-activedirectory-library-for-js

Resources