MVC5, OWIN, and Ninject - GetOwinContext Issues - asp.net-mvc-5

I have an MVC5 project that is doing OwinStartup, and I'm using Ninject.MVC5, Ninject.Web.Common.OwinHost, etc.
I have NinjectWebCommon bootstrapping DI and things were working just fine. Until I started playing with the identity code.
I need to issue a password reset token, which requires a DataProtectionProvider. No problem, the ApplicationUserManager wires that up in the Create method, which is bound to the OwinContext during startup in Startup.Auth.cs:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
...
}
In my NinjectWebCommon I have the following registrations:
kernel.Bind<IDataContext>()
.ToMethod(ctx => HttpContext.Current.GetOwinContext().Get<ApplicationDbContext>())
.InRequestScope();
kernel.Bind<IApplicationUserManager>()
.ToMethod(ctx => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>())
.InRequestScope();
The problem I'm having is that the token isn't being issued. Why isn't that what my question is about? Well, if I get an instance of the ApplicationUserManager using the Create myself and use that, things work flawlessly.
Next on my plate a reported user creation bug. Hyphens aren't working in usernames. In that same ApplicationUserManager.Create method, is the UserValidator code that's overriding the default AllowOnlyAlphanumericUserNames value.
Again, if I use a self created dependency, it works as expected. This seems to indicate Ninject's injected dependency isn't using the ApplicationUserManager.Create'd version.
I'm guessing this has to do with the call to: HttpContext.Current.GetOwinContext??
Is there something I need to do in order to inject something that relies on the owin context or something else I need to do while registering my resolver?
I've seen other questions here showing UseNinjectMiddleware and UseNinjectWebApi. I tried that approach, but didn't have any luck, nothing was being injected in...
Any assistance is greatly appreciated!

Related

How to create a new Authority in jHipster?

I wonder if it is possible to create a new Authority in Jhispter. I tried adding a ROLE_WRITER:
/project/src/main/java/location/security/AuthoritiesConstants.java
package location.security;
/**
* Constants for Spring Security authorities.
*/
public final class AuthoritiesConstants {
public static final String ADMIN = "ROLE_ADMIN";
public static final String USER = "ROLE_USER";
public static final String WRITER = "ROLE_WRITER";
public static final String ANONYMOUS = "ROLE_ANONYMOUS";
private AuthoritiesConstants() {
}
}
When I run the app, it does not crash, but when I tried to change the localhost:9000/#/user-management ROLE in the profile, it did not offer me the option.
So I went to the database and add a new ROLE in the JHI_AUTHORITY Table and now it appears in the user-management, but I have the feeling that i'm getting into trouble if I mess around with the User Entity.
Is there any official way of doing it? (that I am not aware of)
Is there any danger with doing it?
Is there anything else that I should consider?
Thanks
Is there any official way of doing it? (that I am not aware of)
Have you seen src/main/resources/liquibase/authorities.csv? I think that is a right place to add a new authority before production, and when you are in production stage, then it is recommended to add your change(insert into) as liquibase changeset.
Is there any danger with doing it?
AFAIK new role will work like other existing roles in Spring security context. having said that I might misunderstood your question.
Is there anything else that I should consider?
Automation, this type of manual changes will cause dysfunction in production or new installation, so we need to automate this type of changes for both situations.
Although this is already answered, I think it's a good idea to put a link to a related tip posted in the official website of JHipster:
https://www.jhipster.tech/tips/025_tip_create_new_authority.html
I faced the same issue, I added drop-first: true parameter to src/main/resources/config/application-dev.yml:
....
liquibase:
contexts: dev
drop-first: true
....
It seems like it ais a parameter to regenerate the database (for development mode).

Fixing "PrincipalException: PermissionChecker not initialized" the Liferay 7 way

With Liferay 6, using *LocalServiceUtil static calls was common. Starting from Liferay 7, these calls should be avoided in favor of #Referenceing the OSGi service and using it as a private member of the class, if I understood correctly (feel free to correct me).
Problem: When I replace my old *LocalServiceUtil calls with the OSGi-friendly equivalent, I get this exception:
com.liferay.portal.kernel.security.auth.PrincipalException:
PermissionChecker not initialized
at com.liferay.portal.kernel.service.BaseServiceImpl.getPermissionChecker
at com.liferay.portal.service.impl.UserServiceImpl.getUserById
How to fix it?
I could get a random admin via the OSGi equivalent of UserLocalServiceUtil.getRoleUsers(RoleLocalServiceUtil.getRole(company.getCompanyId(),"Administrator").getRoleId()) and use it in the the OSGi equivalent of PermissionThreadLocal.setPermissionChecker(PermissionCheckerFactoryUtil.create(randomAdmin)) but that sounds very hacky, plus it would put the responsibility of my code's actions on the shoulders of this unlucky admin.
My code:
protected void myMethod() {
userService.getUserById(userId);
}
#Reference(unbind = "-")
protected com.liferay.portal.kernel.service.UserService userService;
I think you actually wanted to inject UserLocalService.
In OSGi you should only strip the *Util suffix to receive equivalent functionality.
What you did is moved from LocalService (UserLocalServiceUtil) to remote service (UserService). The local services do not check permissions so there is no permission checker initialisation.
Apart from the above, you should be sure that no mischief can happen when using Local services. It's not recommended to expose this kind of functionality to end users but it's fine for some background processing.

How To Get IAuthenticationManager Implementation Mapped in StructureMap

I'm struggling to use StructureMap and Microsoft AspNet Identity together in that I can't seem to figure out how to get an implementation of IAuthenticationManager mapped. I'm trying to explicitly map this in the DefaultRegistry per the example below.
public class DefaultRegistry : Registry {
public DefaultRegistry() {
Scan(
scan => {
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.With(new ControllerConvention());
});
For<IAuthenticationManager>().Use(() => HttpContext.Current.GetOwinContext().Authentication);
}
}
The main problem is that HttpContext.Current is always null but I'm not even sure this will work even if that isn't null. I'm a big newbie with StructureMap and with AspNet Identity so feel free to call me out on anything silly I'm doing here. Thanks for your help!
That's not really a StructureMap issue per se. HttpContext.Current will only be available inside of an HTTP request in ASP.Net. If you want to use HttpContext within StructureMap, I'd suggest either being sure that you check for the null gracefully or try to switch to using the HttpContextWrapper/HttpContextBase abstraction so that you can run that code outside of ASP.Net in your tests.
Well it seems like the code above is working just fine and I'm not sure why it didn't seem to be working before. I don't know what is protocol to close out the issue but I don't want anyone to think that they can't use the above for reference since it works.

NServiceBus with Azure and XML serializer

I am trying to switch a hosted worker process in Azure to use xml serializer instead of the default json serializer. I have done this by implementing IWantCustomInitialization like this:
public class BusInitialization : IWantCustomInitialization
{
public void Init()
{
Configure.Instance.XmlSerializer();
}
}
However when I start the cloud solution, I get the following error:
Exception when starting endpoint, error has been logged. Reason: Type NServiceBus.Unicast.Transport.CompletionMessage was not registered in the serializer. Check that it appears in the list of configured assemblies/types to scan.
When I use no custom initialization and it goes to JsonSerializer, everything is fine. Does anyone have a suggestion where shall I look to? I use NSB 3.2.8.
thought this was fixed but I just checked, looks like in 3.2.8 the jsonserializer cannot yet be overriden easily. This has already been fixed on the dev branch but didn't get into release yet, it will be in the next one than.
If you can't wait for next release then you can work around this by replacing the AsA_Worker with your own role and role handler similar to this:
3.2.8 version https://github.com/NServiceBus/NServiceBus/blob/master/src/azure/Hosting/NServiceBus.Hosting.Azure/Roles/Handlers/WorkerRoleHandler.cs
develop version https://github.com/NServiceBus/NServiceBus/blob/develop/src/azure/Hosting/NServiceBus.Hosting.Azure/Roles/Handlers/WorkerRoleHandler.cs
Kind regards,
Yves

Add WebRole.cs - and have it called - in an existing ASP.NET MVC site converted to web role

I have an ASP.NET MVC 4 site running perfectly well in an Azure WebRole. The ASP.NET MVC project was started on its own, after which I added an Azure Cloud Service project to the solution and added the ASP.NET project/site as one of the 'roles' of the service (so it shows up in the 'Roles' folder).
My problem is that I would like to have working a WebRole.cs file within the ASP.NET MVC project, but no matter what I've tried to do, it appears that when deployed, it just never gets called. OnStart and the override of Run (which I know, must never leave the loop) -- these just apparently never get called.
But if you startup a new CloudService project and add, at that time from the start, an ASP.NET MVC project, it automatically has a WebRole.cs file in it, so my guess is that I need to configure something somewhere for the WebRole.cs (actually speaking, the WebRole class, which inherits RoleEntryPoint) to get called. What might that be?
using System;
using System.Web;
//using Microsoft.WindowsAzure.StorageClient;
using System.Diagnostics;
using System.Threading;
namespace Us.WebUI
{
public class WebRole : Microsoft.WindowsAzure.ServiceRuntime.RoleEntryPoint
{
public override bool OnStart()
{
return true; //return base.OnStart(); // CALL THIS???
}
public override void Run()
{
while (true) {
Thread.Sleep(TimeSpan.FromSeconds(30));
try {
EmailFuncs.SendEmailToUs("An email from our WebRole?????", "Email me this, email me that.");
}
catch { }
}
}
}
}
UPDATE: Thanks, the question has been answered. But I will add: On doing this, while it clearly was working (fully deployed and in emulator), that suddenly I was having problems doing a full publish of the site. After a azure publish took 3 hours:
Verifying storage account 'xyz'... > Uploading Package... > - Updating... [stayed here for 3 hours], it failed with this error: The server encountered an internal error. Please retry the request. So one thing I was wondering is, did I need to override OnStop in WebRole.cs?
UPDATE 2: Those previous problems were fixed, and had nothing to do with this issue. Actually, I've learned this: If you ever have any warnings generated in your build, Azure often will not work with them even when they don't cause problems locally or in other hosts. Since then, I've been much more studious to tackling build warnings (but critical to this is turning off with warning codes the many warning types you want to ignore!).
Adding a class to your Web Project which inherits from RoleEntryPoint is sufficient, it should just work. Did you try setting a breakpoint in the emulator?
What you might be experiencing is that EmailFuncs.SendEmailToUs requires info from the app/web.config and that this info is not available. You need to know that your WebRole class runs in a different process (not your web application), meaning it's not using your web.config. If you want the WebRole.cs to read info from the configuration file, you'll need to add these settings in WaIISHost.exe.config

Resources