Apache Shiro: ClassCastException on Realm - apache

Ok, I am officially confused.
In Shiro I have my own realm (DatastoreRealm) that extends AuthorizingRealm. In my DatastoreRealm, I have the method "clearCachedAuthorizationInfo" which allows me to clear the users permissions, etc, (and then re-check) when those permissions change on the fly.
In order to get to that method, I have to get access to my DatastoreRealm object.
I do this in the following way...
private static Realm lookupRealm(String realmName) {
SecurityManager securityManager = SecurityUtils.getSecurityManager();
RealmSecurityManager realmSecurityManager = (RealmSecurityManager) securityManager;
Collection<Realm> realms = realmSecurityManager.getRealms();
for (Realm realm : realms) {
if (realm.getName().equalsIgnoreCase(realmName)) {
log.info("look up realm name is : " + realm.getName());
return realm;
}
}
return null; }
This seems to work fine. It returns me a "DatastoreRealm" object.
Although when I call this method, I am forced to do the following...
DatastoreRealm dsRealm = (DatastoreRealm) lookupRealm("rfRealm");
Which throws a "ClassCastException" telling me...
rf.gae.DatastoreRealm cannot be cast to rf.gae.DatastoreRealm
How/Why is this happening???
If I DON'T cast, and simply use the "Realm" object, the "clearCachedAuthorizationInfo" is not available to me!
Thanks in advance for the help!

Well with a bit more digging, I figured out the problem.
The web framework that I'm using has the ability to "hot reload" classes which prevents having to restart the server on each code change.
The problem with this is that a new classloader loads the edited class, and thus when a cast is attempted, the class in memory cannot be cast to the new class loaded by the classloader!
For classes to be cast, they have to be of the same type and loaded by the same classloader.
Turning this feature off corrected my casting issue.

Related

Unable to create a Role using RoleManager in Blazor Serverside

I had some code using the RoleManager that I had copied from an MVC project to create roles in a Blazor project.
It compiles okay but when I step through the code it gets to that line and then appears to throw and exception, as it doesn't ever go to the next line. I am unable to catch an exception though.
Since my code didn't work I found code on the web and it behaved the same, so I changed how it was injected and I got a different error, so I found a third way of doing it and that too gets to the line that tests to see if there is a role already existing and blows up.
Here is the latest attempt
[Inject]
IServiceProvider services {get;set;}
public async Task Initialize()
{
using (var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>())
{
string proRole = "Pro";
if (!await roleManager.RoleExistsAsync(proRole))
{
var temp = await roleManager.CreateAsync(new IdentityRole { Name = proRole });
}
}
}
And it blows up on the awaited if statement.
Here is the previous code that should work that doesn't.
string proRole = "Pro";
string proClientRole = "ProClient";
if (!await _roleManager.RoleExistsAsync(proRole))
{
var temp = await _roleManager.CreateAsync(new IdentityRole { Name = proRole });
}
which is inside of a method.
I also had it as #{code in the Razor file and after an hour of trying different things there I moved it to a base class because they have been more stable in the past.
It is not the database connection because that is well verified and also because UserManager is called in the same class and it work
I also tried this code (Blazor Role Management Add Role trough UI (Crud)) both suggestions.
This is one bad thing about Blazor for me is it is buggy I never know if it is my bad, or just something wrong with the latest greatest. But I am assuming it is my bad in this case.
Anyway any help would be much appreciated, I am way too many hours on this,
I copy/pasted the same code to the "/" page and it works there.
For some reason it wouldn't work in a component loaded into a component but the standard Role code works as expected in the "/" page.
Most likely I should have restarted my computer as it now works in the original location too.

Permission defaults ignored in Orchard

I try to set permissions for my new module. Otherwise they seem to work, but the defaults are ignored, nothing is checked for role-permission pairs I've set in the code. My code (Permissions.cs) seems OK:
using System.Collections.Generic;
using Orchard.Environment.Extensions.Models;
using Orchard.Security.Permissions;
using Orchard.Environment.Extensions;
using My.Module.Utils;
namespace My.Module
{
public class Permissions : IPermissionProvider {
public static readonly Permission AccessMyModule = new Permission {
Description = Constants.AccessAddon, Name = "AccessMyModule"
};
public virtual Feature Feature { get; set; }
public IEnumerable<Permission> GetPermissions() {
return new[] {
AccessMyModule
};
}
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
return new[] {
new PermissionStereotype {
Name = Constants.MyModuleAdministratorRole,
Permissions = new[] { AccessMyModule }
}
};
}
}
}
I double checked that all the constants stored in Constants and the references for them are valid. The code snippet here is simplified, in fact I have more permissions and more roles in my project, but I confirmed commenting out everything but one permission and one role doesn't fix the problem. The defaults for the other modules in the same solution work fine, though there's no bug reported by IntelliSense and everything else in the module seems to work. So where else could be the root of the problem?
EDIT: I followed #mdameer's comment and confirmed that GetDefaultStereotypes() really runs only after reinstall. However, an error occurred while enabling the module after reinstall, so the defaults were not loaded. I know that the supposed way is to check the role - permission name in the dashboard, but I would like to find another workaround, because
I would like to solve the error that occurred and not to risk it happenning on the production server as well, and I can't delete and reinstall this rather complex module several times just to debug this. It was likely caused by the reinstall process, nowhere in the permission initialization, but I can't know without running the code.
there are tens of roles affected, so relying on someone to click the permissions by hand each time means that there will likely be errors due to human factor.
The GetDefaultStereotypes() method is being called from class DefaultRoleUpdater in Orchard.Roles. It is called automatically from somewhere deep in the Orchard core, so simply mimicking the call and running it on startup isn't that easy. I also tried to mimic the whole function and placed it into my permissions class (or into a custom service), but now I got lost on how to run it. It is not static, but it either is part of or refers to my Permissions class, which doesn't allow for ordinary referencing by default (it has no proper constructor) and I don't want to mess it even more by changing the class to something it is not and shouldn't be.
Just set the default permissions you need in a migration instead of using GetDefaultStereotypes(). Here is a short example:
public class MyMigration: Orchard.Data.Migration.DataMigrationImpl
{
// public
public MyMigration(Orchard.Roles.Services.IRoleService aRoleService)
{
mRoleService = aRoleService;
}
public int Create()
{
//mRoleService.CreateRole("MyRoleName");
//mRoleService.UpdateRole("MyRoleName", MyPermissions)
return 1;
}
// private
Orchard.Roles.Services.IRoleService aRoleService mRoleService;
}

How to enable module in Orchard migration?

I want to enable a specific module in a migration but the module is not enabled immediately.
The issue here seems to be the state of the module, it is set to Rising in table Orchard_Settings_ShellFeatureStateRecord. In this case I cannot enable the module manually in Admin anymore, I need to restart the web server after the migration has been executed to get the module to state Up.
The migration code looks like
public class Migration: Orchard.Data.Migration.DataMigrationImpl
{
// public
public Migration(Orchard.Environment.Features.IFeatureManager aFeatureManager)
{
mFeatureManager = aFeatureManager;
}
...
public int UpdateFrom1()
{
System.Collections.Generic.Dictionary<string, Orchard.Environment.Extensions.Models.FeatureDescriptor> lFeatures =
mFeatureManager.GetAvailableFeatures().ToDictionary(m => m.Id, m => m);
if (lFeatures.ContainsKey("Orchard.Taxonomies"))
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"}, true);
...
}
// private
private readonly Orchard.Environment.Features.IFeatureManager mFeatureManager;
}
I also tried using IModuleManager, did not work. Then I tried enabling another simple feature like Orchard.Alias.UI, did not work either.
Is this intended behavior or what might be wrong in the code?
If your feature has a dependency on taxonomies, enabling it will also enable taxonomies. You don't need to do anything else. That is, unless the dependency is something new that you're adding with the new version. In that case, I'd probably display a warning asking the user to enable it, and I'd make the code resilient to taxonomies not being enabled (which is a good idea no matter what)
Change this line:
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"},true);
to this one:
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"});

Resolving constructor dependency on service used in NancyFX

I have the following bootstrap
public class NancyBootStrapper: DefaultNancyBootstrapper
{
protected override void ConfigureRequestContainer(TinyIoC.TinyIoCContainer container, NancyContext context)
{
base.ConfigureRequestContainer(container, context);
var ravenSession = container.Resolve< IRavenSessionProvider >().GetSession();
container.Register( ravenSession );
}
}
When my Nancy app tries to instantiate BlogService using the following constructor
public BlogService(IDocumentSession documentSession)
{
this.documentSession = documentSession;
}
the application blows up stating that it can't resolve document session, I have also tried the following within my test method (removing the constructor injection).
public void BuildCategories()
{
var container = TinyIoCContainer.Current;
documentSession = container.Resolve< IDocumentSession >();
documentSession.Store(new Category{Title = "test"});
documentSession.Store(new Category{Title = ".net"});
documentSession.SaveChanges();
}
This also blows up, pointing out that it can't resolve documentSession.
Now this is the first time I have used either NancyFX or TinyIoC so I could be doing something fundamentally wrong though I should mention that the documentSession does resolve within a Nancy module..
Can any one offer a fix or some suggestions?
When is the BlogService supposed to be instantiated? -My guess would be once for the application, in which case I believe you are registering the session in the wrong bootstrapper method, and should do it in ConfigureApplicationContainer.
I've been playing & digging into both NancyFx and the TinyIoC code bases and have figured out how to fix this issue... I don't like the fix... but hay it works :)
Basically, I am creating a RavenDB document session in the bootstrapper method configureRequestContainer as it is best practice to use the request as your unit of work scope.
Unfortunately anything that is auto wired by tinyIoC within configureApplicationContainer does not have any constructor injection performed using the child container being used by the Nancy request (this includes those that are marked as MultiInstance or as PerRequestSingleton.
To get around this, you need to re-register any components that depend on your per request components within the same child container.
As I said, I don't like the fix, but it is ultimately a fix :)

How do you set a custom session when unit testing with wicket?

I'm trying to run some unit tests on a wicket page that only allows access after you've logged in. In my JUnit test I cannot start the page or render it without setting the session.
How do you set the session? I'm having problems finding any documentation on how to do this.
WicketTester tester = new WicketTester(new MyApp());
((MyCustomSession)tester.getWicketSession()).setItem(MyFactory.getItem("abc"));
//Fails to start below, no session seems to be set
tester.startPage(General.class);
tester.assertRenderedPage(General.class);
What I frequently do is to provide a fake WebApplication with overrides for things that I want to mock or stub.
Among the things I override is the method
public abstract Session newSession(Request request, Response response);
which allows you to return a fake session setup with anything you want.
This is in Wicket 1.3 - if you're using 1.4, some of this may have changed, and as noted in another response, it may be related to a wicket bug.
But assuming the interface hasn't changed too much, overriding this method may also be another way of working around the issue in WICKET-1215.
You may be running into WICKET-1215. Otherwise what you're doing looks fine. For example, I have a Junit4 setup method that looks like:
#Before
public void createTester() {
tester = new WicketTester( new MyApp() );
// see http://issues.apache.org/jira/browse/WICKET-1215
tester.setupRequestAndResponse();
MyAppSession session = (MyAppSession) tester.getWicketSession();
session.setLocale(Locale.CANADA);
session.setUser(...);
}
Using Wicket 1.4, I use my normal WebApplication and WebSession implementations, called NewtEditor and NewtSession in my app. I override newSession, where I do the same than in the regular app code, except that I sign in right away. I also override newSessionStore for performance reasons, I copied this trick from WicketTesters code.
tester = new WicketTester(new NewtEditor()
{
#Override
public Session newSession(Request request, Response response)
{
NewtSession session = new NewtSession(request);
session.signIn(getTestDao());
return session;
}
#Override
protected ISessionStore newSessionStore()
{
// Copied from WicketTester: Don't use a filestore, or we spawn lots of threads,
// which makes things slow.
return new HttpSessionStore(this);
}
});