Blazor WebAssembly server side use like Authorization Server - authorization

After a long search, unfortunately I could not find any interesting information on this issue.
My question. Can i use web assembly blazor server side like authorization server.
I want create one new web api and use authorization mechanism (and users) from blazor web api (server side). Is it possible?
I can get jwt token from blazor web api, but how i can configure another web api for use this token?
Somethins like this:
Blazor web api configured like:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtBearerOptions);
Thank. Sorry if something wrong with my question.

Related

Trying to use token acquisition with ADFS authenticated app

I am stuck on a problem that i cannot think my way out of and have searched everywhere online for answers to no avail.
Here is the problem:
I usually embed PowerBI reports in asp.net application. I follow the Microsoft tutorial. Where we registered an azureAD app as service principal. And we use the Microsoft.Identity.Web library to authenticate our users as well as authenticate as the app's service principal for accessing PowerBI reports.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
builder.Services.AddScoped(typeof(PowerBiServiceApi));
The problem now is that I am building an app that doesn’t authenticate with the Microsoft.Identity.Web but will actually be authenticating users using individual accounts/ ADFS and federation service.
The problem is that I am unable to do token acquisition by authenticating as the app's service principal.
.AddOpenIdConnect(options =>
{
options.ClientId = "xxxxx-xxxxx-xxx-xxx-xxxxxx";
options.Authority = "https://xxxxxxxxxxx";
options.SignedOutRedirectUri = "https://localhost:xxxx/";
options.Events = new OpenIdConnectEvents
{
OnRemoteFailure = OnAuthenticationFailed,
};
})
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
However when I am unable to run this app and embed successfully.
My main question is:
is it possible to authenticate my users with one authentication provider (ADFS federation service via openID or wsFederation )
whilst also doing using Microsoft.Identity to do token acquisition
Thus far I've had success with using OpenIDConnect directly with ADFS and MSAL library to get tokens (also from ADFS) for downstream api's. For entries in ADFS using a client secret (i.e. server apps) I would use the IConfidentialClientApplicationBuilder, whereas native apps would use IPublicClientApplicaationBuilder.
This means I never need nor can use this code:
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi() .AddInMemoryTokenCaches();

How to authenticate both Blazor web app and api?

I am using .NET 6 RC1 with Blazor Server for my Server and a separate Blazor Webassembly project for my client. Both authenticate with Azure Ad B2C. The authentication aspect is working fine.
The server hosts both a BlazorHub for the server side (admin) pages as well as a separate hub for the client to be able to authenticate and call into.
The client connects to the hub mentioned above, as well as perhaps calls any potential API endpoints.
The authentication setup I have is as follows
var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
var configuration = builder.Configuration;
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(configuration, AzureB2C);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(configuration, AzureB2C);
The problem here is that if I have both of these defined, the Client (localhost:4201) works and can connect to the protected Hub on the server.
If I attempt to connect to the server endpoint (localhost:5001) I simply receive a browser 401 page, with nothing in the console and Visual Studio output except for a crbug/1173575, non-JS module files deprecated. warning and additionally in the browser console I receive an Uncaught pause_on_uncaught error.
If I comment out the section for AddMicrosoftIdentityWebApp, the client can still connect fine as before, and the Server fails to authenticate as described above.
If I instead comment out the section for AddMicrosoftIdentityWebApi, the server can authenticate and works as expected, but now the client fails to authenticate with the Hub because the JWT token is not being validated.
How do I mix both of these successfully so I can both authenticate in the Server and the Client?
I have found this on the Microsoft Identity Web github page which basically is what I am trying to accomplish, except the code they provided doesn't work for me the same as I have in my example.
I seem to have resolved my issue by doing the following.
Change the order of my Authentication methods.
AddMicrosoftIdentityWebApi is first.
AddMicrosoftIdentityWebApp is second.
Specify for my Hub that it will use the JwtBearerDefaults.AuthenticationScheme
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapHub<GameHub>("/hubs/gamehub")
.RequireAuthorization(new AuthorizeAttribute
{
AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme,
Policy = PlayerPolicy
});
endpoints.MapFallbackToPage("/_Host");
});
Now both authorize just fine!
I'd love to hear if anybody knows the solution for this keeping the original order of them.

Different authentication methods for MVC Controllers and WebAPI (Cookies+Bearer) using Microsoft Identity Platform

I have a web application that implements both MVC controllers and webapi controllers. This web application uses Microsoft account authentication based on external cookies.
Now I want to query the webapi from a native (desktop) application using MSAL to authenticate the users against the Microsoft identity platform.
I tried to do this adding the following code to use bearer authentication: app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
TokenValidationParameters = new TokenValidationParameters
{
ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
}
});
I can authenticate the client through the PublicClientApp.AcquireTokenInteractive method and use the resulting AccessToken for compounding the Authorization header, but the webapp responds with a 401 error code.
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
var response = httpClient.SendAsync(request).Result;
In summary, the goal is not use both cookies and bearer authentication at the same time, but to have a unique web application using MVC that:
Could serve web pages with an authorization mechanism
Could publish a REST based API (through WebAPI) using the same authorization mechanism, that:
Authenticates against Microsoft Azure AD accounts
Could be consumed by Desktop clients
Could be consumed by the previous web app pages for displaying dynamic content.

ASP.net MVC Core and IdentityServer 4: Setting defaultScheme in AddAuthentication

I am looking at the code below. The AddAuthentication added defaultScheme with "Cookies". Does this mean the current mvc application only accept Cookie authentication but not Access Token by default.
services.AddOptions();
//services.Configure(Configuration);
services.AddDistributedMemoryCache(); // Adds a default in-memory implementation of IDistributedCache
services.AddSession();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
Currently, I wanted to have access one single page with my mobile application which authenticated with it's access token which logged in from the app itself.
I wonder how do I request the webpage inside my webview by using AccessToken instead of Cookie.
There is something called Authorize attribute with difference acceptable scheme I can pass in. I wonder is this the way to set it up.
[Authorize(AuthenticationSchemes =
JwtBearerDefaults.AuthenticationScheme)]
That is for Accesstoken only, if I need both I add cookie as well
options.DefaultScheme = "Cookies";
This means that the authentication scheme, if not specified otherwise, will be "Cookies".
options.DefaultChallengeScheme = "oidc";
This means that the default challenge authentication scheme, if not specified otherwise, will be "oidc".
This is how the OIDC and Cookie authentication schemes will usually work with each other: The application will attempt to authenticate the user using the existing cookie. If that fails (because there’s no cookie), then an authentication challenge will be made using the OIDC scheme. This will then relay the authentication to the external provider, and when that succeeds, the OIDC scheme will sign the user in using the Cookie authentication scheme. This creates the cookie, so on the next request, the cookie authentication scheme will be able to authenticate the user (without having to ask the OIDC scheme again).
If you want other authentication schemes to work, then you will have to add those too. AddAuthentication(…).AddCookie(…).AddOpenIdConnect(…) will just set this chain up. If you also want a JWT bearer authentication, you need to configure that as well.
But just because you .AddJwtBearer(…) that does not mean that anything about the normal flow will change: The Cookie scheme will still be the default, and the OIDC scheme will still be the default challenge. As I said above: Unless you specify otherwise.
So when you want to authorize the user using JWT Bearer authentication, you will need to trigger that explicitly. As you have noticed yourself, this can be done using the Authorize attribute. But in order for that to work, you will still have to set up the JWT Bearer authentication properly. But then it can work in parallel to the already set up Cookie/OIDC setup.

How to set up cookie based authentication with NancyFx and IdentityServer3 (non-API website)

We have an environment with the following:
Standalone IdentityServer3 instance (issues reference tokens, not jwt)
ASP.NET WebAPI resource server
.NET client applications that authenticate against IdSvr (via resource owner flow)
...and now we'd like to start adding an OWIN-hosted web app that will use NancyFx to serve server-rendered pages as well as a couple AngularJS SPAs. This Nancy website will NOT host any APIs, but may consume data from our existing API. I'd like to add authentication in the OWIN pipeline to help secure our Angular applications from being sent down to users who don't have access.
This would be in contrast to sending down the SPA code, and having Angular determine if the user should see anything. In that case we've already exposed the javascript code base, and this we want to avoid.
I'm trying to understand how I should configure this Nancy site to authenticate users against IdentityServer using the implicit flow. I have implemented this authentication scheme in standalone SPAs before (where all authentication was handled by AngularJS code and tokens were stored in HTML5 local storage), but I'm a bit lost on how to properly tackle this within the OWIN pipeline.
I'm thinking that the OWIN cookie authentication middle-ware is the answer, but does that mean the following?
I need to redirect the user to IdentityServer (using the proper url arguments for implicit flow)?
IdentityServer will redirect the user back to my site on a successful login, so is that where I hook into the OWIN Authorization manager to set the appropriate cookie?
...or am I thinking about this all wrong?
For reference, I've read through the following posts, and they're very helpful but I'm not quite seeing the big picture with OWIN. I'm going to experiment with the UseOpenIdConnectAuthentication middle-ware next, but I would appreciate any guidance SO might have here.
http://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/
https://github.com/IdentityServer/IdentityServer3/issues/487
Fundamentally, implementing OpenID Connect authentication in a Nancy app hosted via OWIN is really not different from implementing it in any MVC/Katana app (the Thinktecture team has a sample for this scenario: https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source/Clients/MVC%20OWIN%20Client)
You basically need 3 things: the cookie middleware, the OpenID Connect middleware and the Nancy middleware:
public class Startup {
public void Configuration(IAppBuilder app) {
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions {
AuthenticationMode = AuthenticationMode.Active,
// Set the address of your OpenID Connect server:
Authority = "http://localhost:54541/"
// Set your client identifier here:
ClientId = "myClient",
// Set the redirect_uri and post_logout_redirect_uri
// corresponding to your application:
RedirectUri = "http://localhost:56765/oidc",
PostLogoutRedirectUri = "http://localhost:56765/"
});
app.UseNancy(options => options.PerformPassThrough = context => context.Response.StatusCode == HttpStatusCode.NotFound);
}
}
If you're looking for a functional demo, you can take a look at https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/tree/dev/samples/Nancy/Nancy.Client (note: it doesn't use IdentityServer3 for the OIDC server part but it shouldn't make any difference for the client app).