Server Side Blazor + Kestrel + Windows Auth = Crash - windows-authentication

I am trying to setup windows Auth using kesterel on blazor server side.I have the progam setup like this:
I am using version 0.6.0 of Blazor server side and latest release of VS 2017.
Using the out of the box blazor temnplate. You can see that I enabled "windows Auth" in BuildWebHost of 'Program.cs". If I comment out options.Authentication.AllowAnonymous line, everything works, of course.
Blazor.Web.server
Program.cs
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseHttpSys(
options =>
{
options.Authentication.Schemes =
AuthenticationSchemes.Negotiate | AuthenticationSchemes.NTLM;
options.Authentication.AllowAnonymous = false;
})
.UseConfiguration(new ConfigurationBuilder()
.AddCommandLine(args)
.Build())
.UseStartup<Startup>()
.Build();
}
Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Since Blazor is running on the server, we can use an application
service
// to read the forecast data.
services.AddSingleton();
}
public void Configure(IBlazorApplicationBuilder app)
{
app.AddComponent("app");
}
}
Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
BlazorWebAssemblyHost.CreateDefaultBuilder()
.UseBlazorStartup<Startup>();
}
public class HttpContextAccessor
{
private readonly IHttpContextAccessor _httpContextAccessor;
public HttpContextAccessor(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public HttpContext Context => _httpContextAccessor.HttpContext;
}
Auth.cshtml
using System.Net.Http
#Inject Blazor.Web.App.HttpContextAccessor HttpContext
#page "/two-way-data-binding"
Logged in User: #HttpContext.Context.User.Identity.Name
I get the following error when navigating to Auth.cshtml
System.ObjectDisposedException
HResult=0x80131622
Message=Safe handle has been closed
Source=System.Private.CoreLib
StackTrace:
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
at Interop.Advapi32.GetTokenInformation(SafeAccessTokenHandle TokenHandle, UInt32 TokenInformationClass, SafeLocalAllocHandle TokenInformation, UInt32 TokenInformationLength, UInt32& ReturnLength)
at System.Security.Principal.WindowsIdentity.GetTokenInformation(SafeAccessTokenHandle tokenHandle, TokenInformationClass tokenInformationClass, Boolean nullOnInvalidParam)
at System.Security.Principal.WindowsIdentity.get_User()
at System.Security.Principal.WindowsIdentity.b__46_0()
at System.Security.Principal.WindowsIdentity.<>c__DisplayClass62_0.b__0(Object )
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Security.Principal.WindowsIdentity.RunImpersonatedInternal(SafeAccessTokenHandle token, Action action)
at System.Security.Principal.WindowsIdentity.RunImpersonated(SafeAccessTokenHandle safeAccessTokenHandle, Action action)
at System.Security.Principal.WindowsIdentity.GetName()
at System.Security.Principal.WindowsIdentity.get_Name()
at Cloud.WebUI.App.Pages.TwoWayDataBinding.BuildRenderTree(RenderTreeBuilder builder)
at Microsoft.AspNetCore.Blazor.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment)
at Microsoft.AspNetCore.Blazor.Rendering.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry)
at Microsoft.AspNetCore.Blazor.Rendering.Renderer.ProcessRenderQueue()
at Microsoft.AspNetCore.Blazor.Rendering.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment)
This is also created as a "issue" # Blazor Issue # 1596

At first, there is no need for your custom class HttpContextAccessor as it does not add any value.
Be sure to add the following line to your ConfigureServices method of the server's Startup.cs
services.AddHttpContextAccessor();
Then you are fine and can use the HttpContextAccessor in your Blazor app the following way:
#inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
User: #HttpContextAccessor.HttpContext.User.Identity.Name
Set windows authentication to true in your server's project web server settings (the last area in debug settings).
I'm using Blazor 0.7.0

Related

Clients.All, Clients.Caller and Clients.Others throwing TypeLoadException

I have a simple Typed Hub setup through an interface. I can successfully connect to the SignalR Hub.
namespace POC.WebSocket
{
public class ApiResultHub : Hub<IApiResultHubClient>
{
public async Task SendMessage(string user, string message)
{
await Clients.All.ReceiveMessage(user, message);
}
public override Task OnConnectedAsync()
{
Clients.Caller.ReceiveMessage("newUser", $"{Context.ConnectionId}");
return base.OnConnectedAsync();
}
}
}
However, when I try invoke a client side hub method it throws the following exception:
Here are my other class files:
Startup.cs
namespace POC.WebSocket
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
{
builder
.AllowAnyMethod()
.AllowAnyHeader()
.WithOrigins("https://localhost:44324", "https://localhost:44326")
.AllowCredentials();
}));
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
{
routes.MapHub<ApiResultHub>("/apiResult");
});
app.UseHttpsRedirection();
app.UseMvc();
}
}
}
IApiResultHubClient`T.cs
namespace POC.Common
{
public interface IApiResultHubClient
{
Task ReceiveMessage(string user, string message);
Task SendApiResponse<T>(ApiResult<T> data);
}
}
Has anyone else seen this issue? I saw few similar issues with being able to connect to the hub itself. However, as mentioned I am able to successfully connect to the hub, just not able to resolve Clients.All, Clients.Caller or Clients.Others.
All libraries updated today:
.Net Core version 2.1.4
.Net SignalR Core version 1.0.3
Edits:
Found details of the exception:
Method 'SendApiResponse' in type
'Microsoft.AspNetCore.SignalR.TypedClientBuilder.IApiResultHubClientImpl'
from assembly 'Microsoft.AspNetCore.SignalR.TypedClientBuilder,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have
an implementation.

EJB not initializing in Wildfly 9.0.0 using #EJB

I'm trying to migrate from EJB2.x to EJB3.x and i'm using Wildfly 9.0.0.
The old EJB2.x is working in JBoss 4.2.2 and this is how it looks like:
public interface WUFFacadeRemote extends EJBObject {
public ClientData getItems(ClientData data);
public ClientData save(ClientData data);
}
public interface WUFFacadeHome extends EJBHome {
public WUFFacadeRemote create();
}
public class WUFFacade {
public ClientData getItems(ClientData data) {
//code here
}
public ClientData save(ClientData data) {
//code here
}
}
public class WUFAction extends HttpServlet implements IAction {
public void doPost(HttpServletRequest request, HttpServletResponse response) {
...
Object objRef = ic.lookup("java:comp/env/wUF");
com.wuf.WUFFacadeHome home = (com.wuf.WUFFacadeHome) PortableRemoteObject.narrow(objRef, com.wuf.WUFFacadeHome.class);
engine = home.create();
//engine gets the reference, and I can use it normally.
...
}
}
I also have the ejb-jar.xml and it's working. Now, the solution I was thinking to EJB3.x and Wildfly 9.0.0 is as below:
#WebServlet(urlPatterns = "windows/wUF.do", loadOnStartup = 1)
public class WUFAction extends HttpServlet implements IAction {
#EJB
private WUFFacadeRemote engine;
public void doPost(HttpServletRequest request, HttpServletResponse response) {
//Here I should be able to use my engine.
//Wildfly starts and I call the page, engine is not null at this moment,
//but after I call the page again, it becomes null and remains null.
}
}
#Stateless
#Remote(WUFFacadeRemote.class)
public class WUFFacade extends RootFacade implements WUFFacadeRemote, Serializable {
public WUFFacade() { }
#EJB
FUFHome home;
public ClientData getItems(ClientData data) {
//code here
}
public ClientData save(ClientData data) {
//code here
}
private Col load(ClientData data,InitialContext ic) {
//here i'm calling home.
// but home is always null. It was supposed to have the #EJB reference initialized.
//But instead I get a null pointer...
home.findByFilter(loader);
}
}
#Remote(FUFHome.class)
public interface FUFHome {
FUF create(FUFValue fUFValue);
FUF findByPrimaryKey(FUFPK pk);
Collection findByFilter(FacadeLoader loader);
}
public interface WUFFacadeRemote{
public ClientData getItems(ClientData data);
public ClientData save(ClientData data);
}
I don't have ejb-jar.xml anymore, the deploy is sucessfully done and Wildfly starts with no errors. Then the first time I call the page in question, it seems that #EJB is working (Debug is "Proxy for remote EJB StatelessEJBLocator for "bus-facade/WUFFacade", view is interface com.wuf.WUFFacadeRemote, affinity is None"), the value is not null, but for all subsequent calls, my variable is null and I got a NullPointerException.
I really don't know what i'm doing wrong (maybe i'm completely lost), but to me, #EJB should be working correctly like that. What am I missing? Thanks.
As i'm using EJB3.x i'm just using annotations now, (this seems to be ok).
JNDIs:
JNDI bindings for session bean named FUF in deployment
java:global/fumo/bus-entities-fumo/FUF!apyon.components.fumo.fuf.FUF
java:app/bus-entities-fumo/FUF!apyon.components.fumo.fuf.FUF
java:module/FUF!apyon.components.fumo.fuf.FUF
java:global/fumo/bus-entities-fumo/FUF
java:app/bus-entities-fumo/FUF
java:module/FUF
JNDI bindings for session bean named WUFFacade
java:global/fumo/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:app/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:module/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:jboss/exported/fumo/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:global/fumo/bus-facade-fumo/WUFFacade
java:app/bus-facade-fumo/WUFFacade
java:module/WUFFacade
I think I found a possible solution to the problem. I'll still try to find another one, but this is good so far.
After changing to a .war and keeping my other projects in .ears it's working. Maybe the problem was because I have a RootController servlet im my main.ear, which is the starting point of the aplication. The context starts there and then it redirects to fumo.ear (now fumo.war).
For some reason, I always was getting a null in my EJB after entering a page. It was always hapening when I first entered a JSP and tried to call the page again. My solution to this is:
#WebServlet(urlPatterns = "windows/wUF.do", loadOnStartup = 1)
public class WUFAction extends HttpServlet {
private WUFFacadeRemote engine;
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
doPost(req, resp);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) {
if(engine == null) {
InitialContext ic;
try {
ic = new InitialContext();
engine = (WUFFacadeRemote) ic.lookup("java:global/fumo/WUFFacade!fumo.wuf.WUFFacadeRemote");
} catch (NamingException e) {
e.printStackTrace();
}
}
//here I always have the context now.
}
}
And as a .war my structure now looks like this:
So other annotations like #Inject and #EJB are now working. Always when i'm being redirect from a JSP calling a Servlet or some action, I first check if the context is not null, otherwise I lookup it. My #Stateless are working and the #PersistenceContext and #Remote are working too.
#Stateless
public class WUFFacade implements WUFFacadeRemote {
#Inject
private FUFRules rules;
#EJB
private FUFHome home;
private Col load(ClientData data, InitialContext ic) throws InterfaceException {
try {
// home here is nor null anymore.
Collection res = (Collection) home.findByFilter(loader);
...
} catch (InterfaceException e) {
e.printStackTrace();
}
...
return data;
}
}
So I'd like to thank everyone who helped in the thread. It was a good way to understand and see the problem or to find a workaround. As I said, I'll still try the .ear in the future, but as a simplified packaging it definitely works.

JWT & Simple Injector. Set connectionstring OnTokenValidated

I am new to this kind of concepts so i am kinda stuck on this (explanation of what i aim for a little bellow).
I have the following code in a rest web api:
UnitOfWorkProvider.cs
public class UnitOfWorkProvider : IUnitOfWorkProvider
{
private readonly Func<AppDbContext> getDbContext;
public UnitOfWorkProvider(Func<AppDbContext> getDbContext)
{
this.getDbContext = getDbContext;
}
public IUnitOfWork Get()
{
return new AppUnitOfWork(this.getDbContext());
}
}
SimpleInjectorConfiguration.cs
internal static void Configure(this Container container, IConfigurationRoot configuration, IApplicationBuilder app, ILoggerFactory loggerFactory, IHttpContextAccessor httpContextAccessor, IMemoryCache memoryCache)
{
InitializeInjectorContainer(container, configuration, app, loggerFactory, httpContextAccessor, memoryCache);
}
private static void InitializeInjectorContainer(Container container, IConfigurationRoot configuration, IApplicationBuilder app, ILoggerFactory loggerFactory, IHttpContextAccessor httpContextAccessor, IMemoryCache memoryCache)
{
container.Register<IUnitOfWorkProvider>(() => new UnitOfWorkProvider(() => new AppDbContext(configuration.GetConnectionString("AppDbContext"))), Lifestyle.Scoped);
...
}
that is called on Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IHttpContextAccessor httpContextAccessor, IMemoryCache memoryCache)
{
// Configure and register Simple Injector
simpleInjectorContainer.Configure(configuration, app, loggerFactory, httpContextAccessor, memoryCache);
...
}
What i am for is register the IUnitOfWorkProvider like this in SimpleInjectorConfiguration.cs:
container.Register<IUnitOfWorkProvider>();
and instantiate it later on JWT OnTokenValidated event when i get the database name from the claims in request:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Events = new JwtBearerEvents()
{
OnTokenValidated = context =>
{
// get database name from claims in request
// something like this to set the context. this doesnt work.
container.GetInstance<IUnitOfWorkProvider>(() => new UnitOfWorkProvider(() => new AppDbContext(SetConnectionString(dbNameFromClaim))), Lifestyle.Scoped);
return Task.CompletedTask;
}
};
});
Many thanks to whom might help me! :)

multiple connection string same context

I need Help configuring an asp.net core 2.0 angular project with entity-framework 2.0, I need help to implement in the controller when user call an API like ChangeDatabase(string databaseConexionString), then all the request made for that user will use the new connection string instead.
[Produces("application/json")]
[Route("api/admin")]
public class AdminController : Controller
{
private readonly DatabaseContext _context;
private readonly IMapper _mapper;
public AdminController(DatabaseContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}
[HttpGet("[action]")]
public IActionResult ChangeDatabase(string databaseConexionString)
{
//change conexion string...
return Ok("changed!");
}
}
My startup.cs file, the configure services is the default
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DatabaseContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
I just want to change between databases and keep the same context class because the tables are the same, the only difference is the data.

Starting Selenium with custom Firefox profile from Eclipse

I'm running Selenium tests from within Eclipse, but I can't load a custom Firefox profile.
Most sources suggest I need to launch the Selenium Server like this:
java -jar selenium-server.jar -firefoxProfileTemplate </path/to/template/>
But when launching my test from within Eclipse it doesn't use that - the tests will run if the Selenium Server isn't running.
This thread suggests that I can set the profile in the DefaultSelenium constructor:
Selenium RC - disabling browser cookie
But the code generated for me by Selenium IDE (Firefox plugin) doesn't use that constructor:
package com.example.tests;
import com.thoughtworks.selenium.*;
import java.util.regex.Pattern;
public class Example extends SeleneseTestCase {
public void setUp() throws Exception {
setUp("http://www.example.com/", "*firefox");
}
public void testExample() throws Exception {
selenium.open("/");
selenium.click("//body");
}
}
Where should I set the DefaultSelenium configuration options? Or is there some other method I can use to load my custom Firefox template?
Thanks!
Stu
I made a SeleniumTestCase that starts/stops the server before/after each test class and starts/stops the Selenium instance before/after each test:
public class SeleniumTestCase {
protected static Selenium selenium;
protected static AppNavUtils appNavUtils;
#BeforeClass
public static void setUpBeforeClass() throws Exception {
SeleniumServerControl.getInstance().startSeleniumServer();
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
SeleniumServerControl.getInstance().stopSeleniumServer();
}
#Before
public void setUp() throws Exception {
// Replace "*chrome" with "*firefox" for Selenium > 1.0
selenium = new DefaultSelenium("localhost", 5444, "*chrome", "http://localhost:8080/");
selenium.start();
appNavUtils = new AppNavUtils(selenium);
}
#After
public void tearDown() throws Exception {
selenium.stop();
}
}
The SeleniumServerControl starts and stops the server:
public class SeleniumServerControl {
private static final SeleniumServerControl instance = new SeleniumServerControl();
public static SeleniumServerControl getInstance()
{
return instance;
}
private SeleniumServer server = null;
protected SeleniumServerControl(){}
public void startSeleniumServer() {
if (server == null) {
RemoteControlConfiguration rcc = new RemoteControlConfiguration();
rcc.setPort(5444);
//rcc.setFirefoxProfileTemplate(newFirefoxProfileTemplate)
server = new SeleniumServer(rcc);
}
server.start();
}
public void stopSeleniumServer()
{
if (server != null) {
server.stop();
server = null;
}
}
}
the version of code you have above assumes that you are running your tests against localhost on port 4444 thats why it is has 2 parameters in the setup.
To set up eclipse to run it you will need to update the run configuration. That is under
Run > Run Configurations
Have a look for the item that has selenium in it and add the config above so that when it runs it will pick it up and run.
I personally just fire up the server when I start working by running a batch file and kill it at the end of the day.