I call a Web-Api from my server blazor app. Some of the API-Calls needed the calling (windows)user. In my development-enviroment (visual studio with iis express) all is fine. On the web-server the calling users is the application-pool-user - and thats the problem.
My question: Is there a way to call the web-api with the credentials of the current windows user?
I tryed to set the credentials of the HttpClient in startup.cs like this:
services.AddHttpClient<ProposalAssistantWebService>(client => { client.BaseAddress = webServiceBaseUri; }).ConfigurePrimaryHttpMessageHandler(() =>
{
return new HttpClientHandler()
{
UseDefaultCredentials = true
};
}); ;
But it doesnt work...
Also this version did not work:
return new HttpClientHandler()
{
UseDefaultCredentials = true,
Credentials=new NetworkCredential("","","")
};
Some ideas?
Sincerly
Peter
Related
Using this or https://nikiforovall.github.io/aspnetcore/dotnet/2022/08/24/dotnet-keycloak-auth.html tutorial I have setup test user and realm. I can call localhost:8080/realms/Test/protocol/openid-connect/token with client secret and user id and password from postman and it gives me access and refresh token. Now I need to call dotnet endpoint and make sure the user is who he is. But I can not find a way to establish this part as I'm always getting 401 unauthorized. Perhaps it is not setup or my authorization bearer string is not formed correctly.
How can I simply call to an endpoint, check authorization and return a response back?
Dotnet Code:
using System.Security.Claims;
using Api;
using Keycloak.AuthServices.Authentication;
using Keycloak.AuthServices.Authorization;
using Keycloak.AuthServices.Sdk.Admin;
var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
var configuration = builder.Configuration;
var host = builder.Host;
host.ConfigureLogger();
services
.AddEndpointsApiExplorer()
.AddSwagger();
var authenticationOptions = configuration
.GetSection(KeycloakAuthenticationOptions.Section)
.Get<KeycloakAuthenticationOptions>();
services.AddKeycloakAuthentication(authenticationOptions);
var authorizationOptions = configuration
.GetSection(KeycloakProtectionClientOptions.Section)
.Get<KeycloakProtectionClientOptions>();
services
.AddAuthorization(o => o.AddPolicy("IsAdmin", b =>
{
b.RequireResourceRoles("default-roles-test");
/*b.RequireRealmRoles("admin");
b.RequireResourceRoles("r-admin");
// TokenValidationParameters.RoleClaimType is overriden
// by KeycloakRolesClaimsTransformation
b.RequireRole("r-admin");*/
})
)
.AddKeycloakAuthorization(authorizationOptions);
var adminClientOptions = configuration
.GetSection(KeycloakAdminClientOptions.Section)
.Get<KeycloakAdminClientOptions>();
services.AddKeycloakAdminHttpClient(adminClientOptions);
var app = builder.Build();
app
.UseSwagger()
.UseSwaggerUI();
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/", (ClaimsPrincipal user) =>
{
// TokenValidationParameters.NameClaimType is overriden based on keycloak specific claim
app.Logger.LogInformation("{#User}", user.Identity.Name);
return "Hello world. "+ user.Identity.Name;
}).RequireAuthorization("IsAdmin");
app.Run();
appsettings.json keycloack config:
"Keycloak": {
"realm": "Test",
"auth-server-url": "http://localhost:8080/",
"ssl-required": "none",
"resource": "test-client",
"verify-token-audience": false,
"client-secret": "P4JgvFhjY0ftGSLDYmYn7diZhjoLnHon",
"confidential-port": 0
}
Request sending to this endpoint from postman (perhaps the issue is here with correct sending format):
I have a chat app that I made with dotnet core, singalR, and react native. My chat is working well when I publish it on a single server. But when I get publish it in multiple servers by docker swarm. I get this error.
Unable to connect to the server with any of the available transports. WebSockets failed: Error: There was an error with the transport.
By this error message, the app is just sometimes working normally. When I leave the page and return back it is not working again.
I am using ubuntu server. I both aligned the versions of signalR on server and client. They are both using 5.0.3. I don't have proxy server in front of the app and I m using load balancing feature of docker swarm.
Configure Service
var tokenKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["TokenKey"]));
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = tokenKey,
ValidateAudience = false,
ValidateIssuer = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
opt.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken))
{
if (path.StartsWithSegments("/chat")
|| path.StartsWithSegments("/dialog"))
{
context.Token = accessToken;
}
}
return Task.CompletedTask;
}
};
});
Configure Void
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<ChatHub>("/chat", opt => { opt.Transports = HttpTransportType.WebSockets; });
endpoints.MapHub<DialogHub>("/dialog", opt => { opt.Transports = HttpTransportType.WebSockets; });
});
When scaling out SignalR to multiple servers, a shared data plane would be needed to manage distributed state, in addition to the network considerations.
As noted in the docs, Microsoft suggests either introducing a Redis backplane or delegating to their managed service, Azure SignalR.
An app that uses SignalR needs to keep track of all its connections,
which creates problems for a server farm. Add a server, and it gets
new connections that the other servers don't know about.
Having used Azure SignalR, it's fairly straightforward to integrate with an ASP.NET Core app. You then have offloaded all the overhead of managing connections from your app.
I have an API app created using asp core. I'm trying to enforce use of client certificates as described here.
I did tell Kestrel to require certificates in Program.cs:
webBuilder.ConfigureKestrel(o =>
{
o.ConfigureHttpsDefaults(o => o.ClientCertificateMode = ClientCertificateMode.RequireCertificate);
});
And I did add event handler in Startup.cs:
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(options =>
{
options.Events = new CertificateAuthenticationEvents
{
OnCertificateValidated = context =>
{
}
};
});
When I debug the API running locally it still doesn't require any certificates. If I provide certificate anyway, the breakpoint in the event handler is never hit.
I'm unable to change the default "access denied" path of Account/AccessDenied when using Azure AD authentication. What settings do I need to configure to override this?
I've looked at several articles including this but no success yet.
My current startup.cs code looks like this -
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options))
.AddCookie(options =>
{
options.AccessDeniedPath = "/Error/AccessDenied";
options.Events = new CookieAuthenticationEvents
{
OnRedirectToAccessDenied = ctx =>
{
var requestPath = ctx.Request.Path;
if (requestPath.StartsWithSegments("/Account"))
{
ctx.Response.Redirect("/Error/AccessDenied?ReturnUrl=" + requestPath + ctx.Request.QueryString);
}
else
{
ctx.Response.Redirect("/Login?ReturnUrl=" + requestPath + ctx.Request.QueryString);
}
return Task.CompletedTask;
}
};
});
This redirect doesn't work and the event is not fired either. I've tried setting cookie options using services.ConfigureApplicationCookie but that doesn't work either (documentation says it's for identity module anyways).
What am I missing?
My asp.net project is using .net core 2.2 and it's template was generated from the Visual Studio template.
I'm using Azure AD with OpenIdConnect and one Reply URL website, but I need connect by LocalHost for test and implement other function.
How can I have more then one Reply URL using UseOpenIdConnectAuthentication and without lost access in both.
My application is configured with Asp.Net Web.Forms (Visual Studio 2015).
Tks.
Vilela
Yes, it is possible to change the Reply URL dynamiclly using the RedirectToIdentityProvider. You can refer the code sample below:
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
RedirectUri = postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error?message=" + context.Exception.Message);
return Task.FromResult(0);
},
RedirectToIdentityProvider=(context)=>
{
context.ProtocolMessage.RedirectUri = "";
return Task.FromResult(0);
}
}
});
However, if the application was already deployed to the web server, change the redirect URL to localhost may not work as you expected since there are two different application server for the web app running.
Yes, it's works but I needed implement others code, for example:
RedirectToIdentityProvider = (context) =>
{
// This ensures that the address used for sign in and sign out is picked up dynamically from the request
// this allows you to deploy your app (to Azure Web Sites, for example)without having to change settings
// Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = appBaseUrl;
context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
return System.Threading.Tasks.Task.FromResult(0);
},
But, I'm have problem with multi tenants. Others users are authentication in my tenants. It is my problems or Azure problems?
Tks,
Vilela