Security Manager vs Access Controller

2019-07-03 15:40发布

I'm trying to block certain actions from players but not from my game infrastructure and for that I'm using a security manager. It looks like this

public class GameSecurityManager extends SecurityManager {
@Override
public void checkPackageAccess(String pkg) {
 super.checkPackageAccess(pkg);
 if (isPlayer()) {
  if (pkg.startsWith("ca.hilikus.jrobocom")) {
   if (!"ca.hilikus.jrobocom.player".equals(pkg) && !"ca.hilikus.jrobocom.robot.api".equals(pkg)) {
        throw new SecurityException("No access to game packages");
   }}}
}
}

The documentation on security managers is very sparse and most of it is from the 90s. The AccessController situation is even worse. However, I did find this, section 6.2 where it states

We encourage the use of AccessController in application code, while customization of a security manager (via subclassing) should be the last resort and should be done with extreme care.

do you agree with the statement? Can someone explain why that is? if that is the case, how would I accomplish something similar to the sample code I pasted? I'm trying to block things like reflection, threading and instantiating some objects based on the context (like with isPlayer() above). The only thing the Access Control javadoc discusses is privileged operations inside a special block of code, but it doesn't show how to use the controller to actually block actions

标签: java security
3条回答
聊天终结者
2楼-- · 2019-07-03 16:12

(For the benefit of future users)

The answer to this is that you should provide a Security Policy for the application. If that is not possible to control, then you are simply out of luck.

In the policy, you would grant access to some suitable subset for your "hosted extensions", where as your "game packages" would be granted AllPermissions. Then, you create Permissions for your library and grant suitable access to the "hosted extensions".

Then in your APIs, you would do something like;

public String someMethod( String someArg )
{
    if( System.getSecurityManager() == null )
        return internalSomeMethod( someArg );
    MyPermission required = new MyPermission( "whatever" );
    AccessController.checkPermission( required );
    return AccessController.doPrivileged(new PrivilegedAction<String>()
    {
        public String run()
        {
            return internalSomeMethod( somArg );
        }
    } );
}

private String someInternalMethod( String someArg ){...}

So, even if the "hosted extensions" ONLY have "MyPermission", the game engine can have AllPermissions and allowed to do anything it wants, whereas the "extension" couldn't even read a System Property.

查看更多
别忘想泡老子
3楼-- · 2019-07-03 16:18

You don't need to write your own SecurityManager nor your own AccessController, what you need is a custom Permission. After you write one you only need to boot up a SecurityManager and do a security check in every method you want to protect! You might need to do a priveleged action to avoid to much check propagation. :)

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-07-03 16:19

Quote from section "6.4.9 SecurityManager versus AccessController" of the book Inside Java 2 Platform Security:

Recall from earlier in this chapter the difference, when invoking a security check, between calling checkPermission and calling the other check methods defined in the SecurityManager class. The choice then was contingent on whether you depended on any pre–Java 2 security manager classes. Now you have another choice: calling either the checkPermission method defined in SecurityManager or the one defined in AccessController. These methods differ in two major ways.

First, sometimes no installed SecurityManager exists, so you cannot invoke check or checkPermission methods on it. By contrast, the static methods in AccessController are always available to be called. Recall the following idiom for calling SecurityManager:

SecurityManager sm = System.getSecurityManager();
if (sm != null)
    sm.checkPermission(permission);

But you can always call

AccessController.checkPermission(permission);

Thus, regardless of whether a systemwide SecurityManager has been installed, if you want to ensure that your security check is always invoked, you should call AccessController. Note, however, that some existing applications test whether there is an installed instance of SecurityManager. Then, based on the result of this test, which signifies one or the other security states, these applications take different actions. For the backward compatibility of these applications, calling SecurityManager is more appropriate.

The second difference is that calling SecurityManager does not guarantee a particular access control algorithm; someone might have extended it and installed a custom security manager. By contrast, calling AccessController guarantees that the full access control algorithm specified earlier is used. Thus, if you do not want to delegate your security check to a custom security manager, you should call AccessController directly. Otherwise, call SecurityManager.

Also, be warned that because the SecurityManager class defines a general interface for security checks, it does not provide the privilege mechanism that AccessController has defined. In fact, if you use the privilege mechanism in your code but later call SecurityManager to perform a security check, the privilege status might not be taken into account if the security manager you installed is not the one provided by Java 2 and does not consult AccessController or its equivalent.

You might wonder why we provide these choices. Isn't one way of doing things good enough? These choices are based on experience. A balanced trade-off between generality and consistency is needed. In the long run, we expect that custom security managers will not often be needed and that, even when they are defined, they will be built on existing functionality in AccessController. In particular, they will provide additional functionality rather than promote incompatible behavior. Nevertheless, in a special environment in which a vastly different sort of security policy must be enforced, a customized security manager conceivably might not be able to use the algorithms implemented by AccessController.

You can also take a look at SecurityManager versus AccessController section in Oracle's Java Platform, Standard Edition Security Developer’s Guide.

查看更多
登录 后发表回答