アクセス権は、システム・リソースへのアクセスを表します。アプレット(またはセキュリティ・マネージャとともに実行するアプリケーション)が、リソースへのアクセスを許可されるためには、アクセスを試みるコードに対し、該当するアクセス権を明示的に与える必要があります。
一般に、アクセス権には名前(「ターゲット名」とも呼ばれる)があり、場合によっては、カンマで区切られた1つ以上のアクションのリストを持つこともあります。たとえば、次のコードでは、/tmpディレクトリのabcという名前のファイルへの読取りアクセスを表すFilePermissionオブジェクトを作成します。
perm = new java.io.FilePermission("/tmp/abc", "read");
ここでは、ターゲット名が/tmp/abcで、アクション文字列がreadになります。
重要:
前述の文によって、アクセス権オブジェクトが作成されます。アクセス権オブジェクトは、システム・リソースを表しますが、システム・リソースへのアクセスを許可することはありません。アクセス権オブジェクトは、実効性のあるポリシーに基づいて作成され、コードへ割り当てられ(「付与」され)ます。アクセス権オブジェクトが、あるコードに割り当てられると、そのコードはアクセス権オブジェクトで指定されたシステム・リソースへ、指定された方法でアクセスするアクセス権が付与されます。現在のセキュリティ・マネージャが、アクセス判断を行う際に、アクセス権オブジェクトを作成することもあります。この場合、ターゲットのアクセス権オブジェクトは、要求されたアクセスに基づいて作成されます。さらに、ターゲットのアクセス権オブジェクトは、要求を行うコードに付与され、かつ要求を行うコードが保持する、アクセス権オブジェクトに照らしてチェックされます。Javaアプリケーション環境のポリシーは、Policyオブジェクトにより表現されます。"JavaPolicy" Policy実装では、1つまたは複数のポリシー構成ファイルからポリシーを指定できます。ポリシー・ファイルは、指定したコード・ソースのコードにどのアクセス権を許可するかを指定します。次は、/home/sysadminディレクトリのコードに対して/tmp/abcファイルへの読取りアクセスを許可するサンプル・ポリシー・ファイルのエントリです。
grant codeBase "file:/home/sysadmin/" {
permission java.io.FilePermission "/tmp/abc", "read";
};
ポリシー・ファイルの場所、およびポリシー・ファイルにより付与するアクセス権の詳細は、デフォルトのPolicyの実装とポリシー・ファイルの構文を参照してください。
技術的な観点から言うと、リソースへのアクセスを試みる場合は、実行スレッド上のコードに「特権設定」のマークが付けられていないかぎり、実行スレッドが利用するコードはすべて、そのリソースへのアクセス権を保持する必要があります。付録A: 特権ブロックのためのAPIを参照してください。
次は、組込みのすべてのJDKアクセス権タイプのリストです。各アクセス権タイプのクラスの概要では、各アクセス権を付与した場合のリスクについて説明します。
注意:
FilePermissionパス名の正規化方法における変更に関する重要な情報については、付録A: FilePermissionのパス名の正規化がデフォルトで無効化を参照してください。
次の表は、アクセス権を必要とするメソッドのリストであり、どのSecurityManagerメソッドが呼び出され、どのアクセス権がそのSecurityManagerメソッドのデフォルト実装によってチェックされるかを示します。
注意:
これは完全なリストではなく、アクセス権を必要とするその他のメソッドも存在します。SecurityExceptionをスローするメソッドと必要なアクセス権の詳細は、Java SEおよびJDK API仕様を参照してください。SecurityManagerメソッドのデフォルトの実装では、SecurityManagerメソッド列の対応するエントリで示されているアクセス権が現在有効なポリシーで与えられている場合だけ、メソッド列で示したメソッドを呼び出すことができます。たとえば、次のような表の行があるとします。
| メソッド | 呼び出されるSecurityManagerメソッド | アクセス権 |
|---|---|---|
java.awt.Toolkit
public final EventQueue
getSystemEventQueue()
|
checkPermission | java.awt.AWTPermission "accessEventQueue"; |
この表の行では、java.awt.ToolkitクラスのgetSystemEventQueueメソッドへの呼出しは、SecurityManagerメソッドcheckPermissionへの呼出しになることを指定します。これは、呼出しスタック上のコードに次のアクセス権が与えられている場合にのみ成功します。
java.awt.AWTPermission "accessEventQueue";
表の行は次の形式を持ち、アクセス権名中の文字列{foo}はfooの実行時の値で置き換えらます。
| メソッド | 呼び出されるSecurityManagerメソッド | アクセス権 |
|---|---|---|
some.package.class public static void someMethod(String foo); |
checkXXX | SomePermission "{foo}"; |
次の例を見てください。
| メソッド | 呼び出されるSecurityManagerメソッド | アクセス権 |
|---|---|---|
java.io.FileInputStream FileInputStream(String name) |
checkRead(String) | java.io.FilePermission "{name}", "read"; |
FileInputStreamメソッド(この場合はコンストラクタ)を、次のように引数nameに/test/MyTestFileを指定して呼び出したとします。
FileInputStream("/test/MyTestFile");
この呼出しは、現在のポリシーで次のアクセス権が設定され、/test/MyTestFileファイルへの読取りアクセスが許可されていないと行えません。
java.io.FilePermission "/test/MyTestFile", "read";
より正確には、アクセス権は、このように明示的に設定されているか、次のように、別のアクセス権により暗黙に設定されている必要があります。
java.io.FilePermission "/test/*", "read";
「/test」ディレクトリに含まれる任意のファイルへの読取りアクセスが許可されています。
中カッコで囲まれた項目が、特定のメソッド引数と同一ではなく、関係のある値を表す場合もあります。次はその例です。
| メソッド | 呼び出されるSecurityManagerメソッド | アクセス権 |
|---|---|---|
java.net.DatagramSocket public synchronized void receive(DatagramPacket p); |
checkAccept({host}, {port}) | java.net.SocketPermission "{host}:{port}", "accept"; |
ここでは、適切なホストおよびポートの値がreceiveメソッドにより計算されて、checkAcceptに渡されます。
ほとんどの場合、呼び出されるSecurityManagerメソッドの名前のみが一覧表示されます。メソッドは、複数ある同名のメソッドのいずれかであり、引数の型も一覧表示されます。たとえば、checkRead(String)やcheckRead(FileDescriptor)などがあります。引数が関係するその他の場合にも、引数は一覧表示されます。
次の表は、パッケージ名順になっています。最初にjava.awtパッケージ内のクラスのメソッド、次にjava.beansパッケージ内のクラスのメソッド、という順番です。
表1-6 メソッドおよびそのアクセス権
| メソッド | SecurityManagerメソッド | アクセス権 |
|---|---|---|
java.awt.Graphics2d
public abstract void
setComposite(Composite comp)
|
checkPermission | このGraphics2Dコンテキストが表示画面上のComponentに描画中であり、かつCompositeがAlphaCompositeクラスのインスタンスではなく、カスタム・オブジェクトの場合、java.awt.AWTPermission "readDisplayPixels"。注意: setCompositeメソッドは、実際には抽象であるため、セキュリティ・チェックを呼び出すことはできない。こうした条件下では、メソッドの実際の実装ごとに、java.awt.AWTPermission("readDisplayPixels")アクセス権でjava.lang.SecurityManager checkPermissionメソッドを呼び出す必要がある。 |
java.awt.Robot public Robot() public Robot(GraphicsDevice screen) |
checkPermission | java.awt.AWTPermission "createRobot" |
java.awt.Toolkit
public void addAWTEventListener(
AWTEventListener listener,
long eventMask)
public void removeAWTEventListener(
AWTEventListener listener)
|
checkPermission | java.awt.AWTPermission "listenToAllAWTEvents" |
java.awt.Toolkit
public abstract PrintJob getPrintJob(
Frame frame, String jobtitle,
Properties props)
|
checkPrintJobAccess |
注意: getPrintJobメソッドは、実際には抽象であるため、セキュリティ・チェックを呼び出すことはできない。このメソッドの実際の各実装部分では、java.lang.SecurityManager checkPrintJobAccessメソッドを呼び出す必要があり、これは、アクセス権 |
java.awt.Toolkit
public abstract Clipboard
getSystemClipboard()
|
checkPermission |
注意: getSystemClipboardメソッドは、実際には抽象であるため、セキュリティ・チェックを呼び出すことはできない。このメソッドの実際の各実装部分では、checkPermissionメソッドを呼び出す必要があり、これは、アクセス権 |
java.awt.Toolkit
public final EventQueue
getSystemEventQueue()
|
checkPermission | java.awt.AWTPermission "accessEventQueue" |
java.awt.Window Window() |
checkPermission | java.awt.AWTPermission "showWindowWithoutWarningBanner"が設定されていると、ウィンドウが表示されるときに、そのウィンドウがアプレットによって作成されていることを警告するバナーは表示されない。設定されていない場合は、バナーが表示される。 |
java.beans.Beans
public static void setDesignTime(
boolean isDesignTime)
public static void setGuiAvailable(
boolean isGuiAvailable)
java.beans.Introspector
public static synchronized void
setBeanInfoSearchPath(String path[])
java.beans.PropertyEditorManager
public static void registerEditor(
Class targetType,
Class editorClass)
public static synchronized void
setEditorSearchPath(String path[])
|
checkPropertiesAccess | java.util.PropertyPermission "*", "read,write" |
java.io.File public boolean delete() public void deleteOnExit() |
checkDelete(String) | java.io.FilePermission "{name}", "delete" |
java.io.FileInputStream FileInputStream(FileDescriptor fdObj) |
checkRead(FileDescriptor) | java.lang.RuntimePermission "readFileDescriptor" |
java.io.FileInputStream
FileInputStream(String name)
FileInputStream(File file)
java.io.File
public boolean exists()
public boolean canRead()
public boolean isFile()
public boolean isDirectory()
public boolean isHidden()
public long lastModified()
public long length()
public String[] list()
public String[] list(
FilenameFilter filter)
public File[] listFiles()
public File[] listFiles(
FilenameFilter filter)
public File[] listFiles(
FileFilter filter)
java.io.RandomAccessFile
RandomAccessFile(String name, String mode)
RandomAccessFile(File file, String mode)
(モードは、両方のRandomAccessFileコンストラクタで「r」) |
checkRead(String) | java.io.FilePermission "{name}", "read" |
java.io.FileOutputStream FileOutputStream(FileDescriptor fdObj) |
checkWrite(FileDescriptor) | java.lang.RuntimePermission "writeFileDescriptor" |
java.io.FileOutputStream
FileOutputStream(File file)
FileOutputStream(String name)
FileOutputStream(
String name,
boolean append)
java.io.File
public boolean canWrite()
public boolean createNewFile()
public static File createTempFile(
String prefix, String suffix)
public static File createTempFile(
String prefix,
String suffix,
File directory)
public boolean mkdir()
public boolean mkdirs()
public boolean renameTo(File dest)
public boolean setLastModified(long time)
public boolean setReadOnly()
|
checkWrite(String) | java.io.FilePermission "{name}", "write" |
java.io.ObjectInputStream
protected final boolean
enableResolveObject(boolean enable);
java.io.ObjectOutputStream
protected final boolean
enableReplaceObject(boolean enable)
|
checkPermission | java.io.SerializablePermission "enableSubstitution" |
java.io.ObjectInputStream protected ObjectInputStream() java.io.ObjectOutputStream protected ObjectOutputStream() |
checkPermission | java.io.SerializablePermission "enableSubclassImplementation" |
java.io.RandomAccessFile RandomAccessFile(String name, String mode) (モードは「rw」) |
checkRead(String)およびcheckWrite(String) | java.io.FilePermission "{name}", "read,write" |
java.lang.Class
public static Class forName(
String name,
boolean initialize,
ClassLoader loader)
|
checkPermission | loaderがnullで、呼出し側のクラス・ローダーはnullでない場合、java.lang.RuntimePermission("getClassLoader")になる。 |
java.lang.Class public ClassLoader getClassLoader() |
checkPermission | 呼出し側のクラス・ローダーがnullの場合、あるいは呼出し側のクラス・ローダーが、クラス・ローダーが要求されているクラスのクラス・ローダーと同じかその上位クラスの場合は、アクセス権は必要ない。それ以外の場合は、java.lang.RuntimePermission "getClassLoader"が必要。 |
java.lang.Class
public Class[] getDeclaredClasses()
public Field[] getDeclaredFields()
public Method[] getDeclaredMethods()
public Constructor[]
getDeclaredConstructors()
public Field getDeclaredField(
String name)
public Method getDeclaredMethod(...)
public Constructor
getDeclaredConstructor(...)
|
checkMemberAccess(this, Member.DECLARED)、およびこのクラスがパッケージ内にある場合はcheckPackageAccess({pkgName}) | 「この」クラスのクラス・ローダーが呼出し側のクラス・ローダーと同一である場合は、デフォルトのcheckMemberAccessはどのようなアクセス権も必要としない。同一でない場合は、java.lang.RuntimePermission "accessDeclaredMembers"が必要。このクラスがパッケージ内にある場合、java.lang.RuntimePermission "accessClassInPackage.{pkgName}"も必要。 |
java.lang.Class public Class[] getClasses() public Field[] getFields() public Method[] getMethods() public Constructor[] getConstructors() public Field getField(String name) public Method getMethod(...) public Constructor getConstructor(...) |
checkMemberAccess(this, Member.PUBLIC)、およびこのクラスがパッケージ内にある場合はcheckPackageAccess({pkgName}) | アクセス・タイプがMember.PUBLICの場合、デフォルトのcheckMemberAccessはどのようなアクセス権も必要としない。このクラスがパッケージ内にある場合、java.lang.RuntimePermission "accessClassInPackage.{pkgName}"が必要。 |
java.lang.Class
public ProtectionDomain
getProtectionDomain()
|
checkPermission | java.lang.RuntimePermission "getProtectionDomain" |
java.lang.ClassLoader ClassLoader() ClassLoader(ClassLoader parent) |
checkCreateClassLoader | java.lang.RuntimePermission "createClassLoader" |
java.lang.ClassLoader
public static ClassLoader
getSystemClassLoader()
public ClassLoader getParent()
|
checkPermission | 呼出し側のクラス・ローダーがnullの場合、あるいは呼出し側のクラス・ローダーが、クラス・ローダーが要求されているクラスのクラス・ローダーと同じかその上位クラスの場合は、アクセス権は必要ない。それ以外の場合は、java.lang.RuntimePermission "getClassLoader"が必要。 |
java.lang.Runtime
public Process exec(String command)
public Process exec(
String command,
String envp[])
public Process exec(String cmdarray[])
public Process exec(
String cmdarray[],
String envp[])
|
checkExec | java.io.FilePermission "{command}", "execute" |
java.lang.Runtime
public void exit(int status)
public static void
runFinalizersOnExit(boolean value)
java.lang.System
public static void exit(int status)
public static void
runFinalizersOnExit(boolean value)
|
checkExit(status)。このとき、runFinalizersOnExitに対してstatusは0 | java.lang.RuntimePermission "exitVM.{status}" |
java.lang.Runtime public void addShutdownHook(Thread hook) public boolean removeShutdownHook(Thread hook) |
checkPermission | java.lang.RuntimePermission "shutdownHooks" |
java.lang.Runtime
public void load(String lib)
public void loadLibrary(String lib)
java.lang.System
public static void load(String filename)
public static void loadLibrary(
String libname)
|
checkLink({libName})。ここで、{libName}はlib、filenameまたはlibname引数 | java.lang.RuntimePermission "loadLibrary.{libName}" |
| java.lang.SecurityManagerメソッド |
checkPermission | 表1-7を参照してください。 |
java.lang.System
public static Properties
getProperties()
public static void
setProperties(Properties props)
|
checkPropertiesAccess | java.util.PropertyPermission "*", "read,write" |
java.lang.System
public static String
getProperty(String key)
public static String
getProperty(String key, String def)
|
checkPropertyAccess | java.util.PropertyPermission "{key}", "read" |
java.lang.System public static void setIn(InputStream in) public static void setOut(PrintStream out) public static void setErr(PrintStream err) |
checkPermission | java.lang.RuntimePermission "setIO" |
java.lang.System
public static String
setProperty(String key, String value)
|
checkPermission | java.util.PropertyPermission "{key}", "write" |
java.lang.System
public static synchronized void
setSecurityManager(SecurityManager s)
|
checkPermission | java.lang.RuntimePermission "setSecurityManager" |
java.lang.Thread public ClassLoader getContextClassLoader() |
checkPermission | 呼出し側のクラス・ローダーがnullの場合、あるいは呼出し側のクラス・ローダーが、コンテキスト・クラス・ローダーが要求されているスレッドのコンテキスト・クラス・ローダーと同じかその上位クラスの場合は、アクセス権は必要ない。それ以外の場合は、java.lang.RuntimePermission "getClassLoader"が必要。 |
java.lang.Thread
public void setContextClassLoader(
ClassLoader cl)
|
checkPermission | java.lang.RuntimePermission "setContextClassLoader" |
java.lang.Thread
public final void checkAccess()
public void interrupt()
public final void suspend()
public final void resume()
public final void setPriority(
int newPriority)
public final void setName(
String name)
public final void setDaemon(
boolean on)
|
checkAccess(this) | java.lang.RuntimePermission "modifyThread" |
java.lang.Thread
public static int
enumerate(Thread tarray[])
|
checkAccess({threadGroup}) | java.lang.RuntimePermission "modifyThreadGroup" |
java.lang.Thread public final void stop() |
checkAccess(this)。現在のスレッドが自分以外のスレッドを停止させようとしている場合は、checkPermissionも呼び出される。 | java.lang.RuntimePermission "modifyThread"。現在のスレッドが自分以外のスレッドを停止させようとしている場合、 |
java.lang.Thread
public final synchronized void
stop(Throwable obj)
|
checkAccess(this)。現在のスレッドが自分以外のスレッドを停止させようとしている場合、またはobjがThreadDeathのインスタンスでない場合は、checkPermissionも呼び出される。 | java.lang.RuntimePermission "modifyThread"。 現在のスレッドが自分以外のスレッドを停止させようとしている場合、またはobjがThreadDeathのインスタンスではない場合は、 |
java.lang.Thread
Thread()
Thread(Runnable target)
Thread(String name)
Thread(Runnable target, String name)
java.lang.ThreadGroup
ThreadGroup(String name)
ThreadGroup(
ThreadGroup parent,
String name)
|
checkAccess({parentThreadGroup}) | java.lang.RuntimePermission "modifyThreadGroup" |
java.lang.Thread
Thread(ThreadGroup group, ...)
java.lang.ThreadGroup
public final void checkAccess()
public int enumerate(Thread list[])
public int enumerate(
Thread list[],
boolean recurse)
public int enumerate(ThreadGroup list[])
public int enumerate(
ThreadGroup list[],
boolean recurse)
public final ThreadGroup getParent()
public final void setDaemon(
boolean daemon)
public final void setMaxPriority(int pri)
public final void suspend()
public final void resume()
public final void destroy()
|
ThreadGroupメソッドの場合はcheckAccess(this)、Threadメソッドの場合はcheckAccess(group) | java.lang.RuntimePermission "modifyThreadGroup" |
java.lang.ThreadGroup public final void interrupt() |
checkAccess(this) | java.lang.RuntimePermission "modifyThreadGroup"が必要。スレッド・グループ内とそのすべてのサブグループ内のスレッドごとにjava.lang.Thread interrupt()メソッドが呼び出されるため、java.lang.RuntimePermission "modifyThread"も必要。Thread interrupt()メソッドを参照。 |
java.lang.ThreadGroup public final void stop() |
checkAccess(this) | java.lang.RuntimePermission "modifyThreadGroup"が必要。java.lang.Thread stop()メソッドは、そのスレッド・グループ内およびそのすべてのサブグループ内のスレッドごとに呼び出されるので、java.lang.RuntimePermission "modifyThread"および場合によってはjava.lang.RuntimePermission "stopThread"も必要。Thread stop()メソッドを参照。 |
java.lang.reflect.AccessibleObject public static void setAccessible(...) public void setAccessible(...) |
checkPermission | java.lang.reflect.ReflectPermission "suppressAccessChecks" |
java.net.Authenticator
public static PasswordAuthentication
requestPasswordAuthentication(
InetAddress addr,
int port,
String protocol,
String prompt,
String scheme)
|
checkPermission | java.net.NetPermission "requestPasswordAuthentication" |
java.net.Authenticator
public static void
setDefault(Authenticator a)
|
checkPermission | java.net.NetPermission "setDefaultAuthenticator" |
java.net.MulticastSocket
public void
joinGroup(InetAddress mcastaddr)
public void
leaveGroup(InetAddress mcastaddr)
|
checkMulticast(InetAddress) | java.net.SocketPermission( mcastaddr.getHostAddress(), "accept,connect") |
java.net.DatagramSocket public void send(DatagramPacket p) |
checkMulticast(p.getAddress())またはcheckConnect(p.getAddress().getHostAddress(),p.getPort()) | if (p.getAddress().isMulticastAddress()) {
java.net.SocketPermission(
(p.getAddress()).getHostAddress(),
"accept,connect")
} else {
port = p.getPort();
host = p.getAddress().getHostAddress();
if (port == -1)
java.net.SocketPermission "{host}","resolve";
else
java.net.SocketPermission "{host}:{port}","connect";
}
|
java.net.MulticastSocket
public synchronized void
send(DatagramPacket p, byte ttl)
|
checkMulticast(p.getAddress(), ttl)またはcheckConnect( p.getAddress().getHostAddress(), p.getPort()) | if (p.getAddress().isMulticastAddress()) {
java.net.SocketPermission(
(p.getAddress()).getHostAddress(),
"accept,connect")
} else {
port = p.getPort();
host = p.getAddress().getHostAddress();
if (port == -1)
java.net.SocketPermission "{host}","resolve";
else
java.net.SocketPermission "{host}:{port}","connect"
}
|
java.net.InetAddress
public String getHostName()
public static InetAddress[]
getAllByName(String host)
public static InetAddress getLocalHost()
java.net.DatagramSocket
public InetAddress getLocalAddress()
|
checkConnect({host}, -1) | java.net.SocketPermission "{host}", "resolve" |
java.net.ServerSocket ServerSocket(...) java.net.DatagramSocket DatagramSocket(...) java.net.MulticastSocket MulticastSocket(...) |
checkListen({port}) | java.net.SocketPermission "localhost:{port}","listen"; |
java.net.ServerSocket public Socket accept() protected final void implAccept(Socket s) |
checkAccept({host}, {port}) | java.net.SocketPermission "{host}:{port}", "accept" |
java.net.ServerSocket
public static synchronized void
setSocketFactory(...)
java.net.Socket
public static synchronized void
setSocketImplFactory(...)
java.net.URL
public static synchronized void
setURLStreamHandlerFactory(...)
java.net.URLConnection
public static synchronized void
setContentHandlerFactory(...)
public static void
setFileNameMap(FileNameMap map)
java.net.HttpURLConnection
public static void
setFollowRedirects(boolean set)
java.rmi.activation.ActivationGroup
public static synchronized
ActivationGroup createGroup(...)
public static synchronized void
setSystem(ActivationSystem system)
java.rmi.server.RMISocketFactory
public synchronized static void
setSocketFactory(...)
|
checkSetFactory | java.lang.RuntimePermission "setFactory" |
java.net.Socket Socket(...) |
checkConnect({host}, {port}) | java.net.SocketPermission "{host}:{port}", "connect" |
java.net.DatagramSocket
public synchronized void
receive(DatagramPacket p)
|
checkAccept({host}, {port}) | java.net.SocketPermission "{host}:{port}", "accept" |
java.net.URL URL(...) |
checkPermission | java.net.NetPermission "specifyStreamHandler" |
java.net.URLClassLoader URLClassLoader(...) |
checkCreateClassLoader | java.lang.RuntimePermission "createClassLoader" |
java.security.AccessControlContext
public AccessControlContext(
AccessControlContext acc,
DomainCombiner combiner)
public DomainCombiner getDomainCombiner()
|
checkPermission | java.security.SecurityPermission "createAccessControlContext" |
java.security.Identity public void addCertificate(...) |
checkSecurityAccess("addIdentityCertificate") | java.security.SecurityPermission "addIdentityCertificate" |
java.security.Identity public void removeCertificate(...) |
checkSecurityAccess("removeIdentityCertificate") | java.security.SecurityPermission "removeIdentityCertificate" |
java.security.Identity public void setInfo(String info) |
checkSecurityAccess("setIdentityInfo") | java.security.SecurityPermission "setIdentityInfo" |
java.security.Identity public void setPublicKey(PublicKey key) |
checkSecurityAccess("setIdentityPublicKey") | java.security.SecurityPermission "setIdentityPublicKey" |
java.security.Identity public String toString(...) |
checkSecurityAccess("printIdentity") | java.security.SecurityPermission "printIdentity" |
java.security.IdentityScope protected static void setSystemScope() |
checkSecurityAccess("setSystemScope") | java.security.SecurityPermission "setSystemScope" |
java.security.Permission public void checkGuard(Object object) |
checkPermission(this) | このアクセス権オブジェクトはチェックされたアクセス権である。 |
java.security.Policy public static Policy getPolicy() |
checkPermission | java.security.SecurityPermission "getPolicy" |
java.security.Policy
public static void
setPolicy(Policy policy)
|
checkPermission | java.security.SecurityPermission "setPolicy" |
java.security.Policy
public static Policy
getInstance(
String type,
SpiParameter params)
getInstance(
String type,
SpiParameter params,
String provider)
getInstance(
String type,
SpiParameter params,
Provider provider)
|
checkPermission | java.security.SecurityPermission "createPolicy.{type}" |
java.security.Provider public synchronized void clear() |
checkSecurityAccess(「clearProviderProperties.」+{name}) | java.security.SecurityPermission "clearProviderProperties.{name}" (nameはプロバイダ名)。 |
java.security.Provider
public synchronized Object
put(Object key, Object value)
|
checkSecurityAccess("putProviderProperty."+{name}) | java.security.SecurityPermission "putProviderProperty.{name}" (nameはプロバイダ名)。 |
java.security.Provider
public synchronized Object
remove(Object key)
|
checkSecurityAccess("removeProviderProperty."+{name}) | java.security.SecurityPermission "removeProviderProperty.{name}" (nameはプロバイダ名)。 |
java.security.SecureClassLoader SecureClassLoader(...) |
checkCreateClassLoader | java.lang.RuntimePermission "createClassLoader" |
java.security.Security public static void getProperty(String key) |
checkPermission | java.security.SecurityPermission "getProperty.{key}" |
java.security.Security
public static int
addProvider(Provider provider)
public static int
insertProviderAt(
Provider provider,
int position);
|
checkSecurityAccess("insertProvider."+provider.getName()) | java.security.SecurityPermission "insertProvider.{name}" |
java.security.Security
public static void
removeProvider(String name)
|
checkSecurityAccess("removeProvider."+name) | java.security.SecurityPermission "removeProvider.{name}" |
java.security.Security
public static void
setProperty(String key, String datum)
|
checkSecurityAccess("setProperty."+key) | java.security.SecurityPermission "setProperty.{key}" |
java.security.Signer public PrivateKey getPrivateKey() |
checkSecurityAccess("getSignerPrivateKey") | java.security.SecurityPermission "getSignerPrivateKey" |
java.security.Signer
public final void
setKeyPair(KeyPair pair)
|
checkSecurityAccess("setSignerKeypair") | java.security.SecurityPermission "setSignerKeypair" |
java.sql.DriverManager
public static synchronized void
setLogWriter(PrintWriter out)
|
checkPermission | java.sql.SQLPermission "setLog" |
java.sql.DriverManager
public static synchronized void
setLogStream(PrintWriter out)
|
checkPermission | java.sql.SQLPermission "setLog" |
java.util.Locale
public static synchronized void
setDefault(Locale newLocale)
|
checkPermission | java.util.PropertyPermission "user.language","write" |
java.util.zip.ZipFile ZipFile(String name) |
checkRead | java.io.FilePermission "{name}","read" |
javax.security.auth.Subject
public static Subject getSubject(
final AccessControlContext acc)
|
checkPermission | javax.security.auth.AuthPermission "getSubject" |
javax.security.auth.Subject public void setReadOnly() |
checkPermission | javax.security.auth.AuthPermission "setReadOnly" |
javax.security.auth.Subject
public static Object doAs(
final Subject subject,
final PrivilegedAction action)
|
checkPermission | javax.security.auth.AuthPermission "doAs" |
javax.security.auth.Subject
public static Object doAs(
final Subject subject,
final PrivilegedExceptionAction action)
throws
java.security.PrivilegedActionException
|
checkPermission | javax.security.auth.AuthPermission "doAs" |
javax.security.auth.Subject
public static Object doAsPrivileged(
final Subject subject,
final PrivilegedAction action,
final AccessControlContext acc)
|
checkPermission | javax.security.auth.AuthPermission "doAsPrivileged" |
javax.security.auth.Subject
public static Object doAsPrivileged(
final Subject subject,
final PrivilegedExceptionAction action,
final AccessControlContext acc)
throws
java.security.PrivilegedActionException
|
checkPermission | javax.security.auth.AuthPermission "doAsPrivileged" |
javax.security.auth.SubjectDomainCombiner public Subject getSubject() |
checkPermission | javax.security.auth.AuthPermission "getSubjectFromDomainCombiner" |
javax.security.auth.SubjectDomainCombiner public Subject getSubject() |
checkPermission | javax.security.auth.AuthPermission "getSubjectFromDomainCombiner" |
javax.security.auth.login.LoginContext
public LoginContext(String name)
throws LoginException
|
checkPermission | javax.security.auth.AuthPermission "createLoginContext.{name}" |
javax.security.auth.login.LoginContext
public LoginContext(
String name,
Subject subject)
throws LoginException
|
checkPermission | javax.security.auth.AuthPermission "createLoginContext.{name}" |
javax.security.auth.login.LoginContext
public LoginContext(
String name,
CallbackHandler callbackHandler)
throws LoginException
|
checkPermission | javax.security.auth.AuthPermission "createLoginContext.{name}" |
javax.security.auth.login.LoginContext
public LoginContext(
String name,
Subject subject,
CallbackHandler callbackHandler)
throws LoginException
|
checkPermission | javax.security.auth.AuthPermission "createLoginContext.{name}" |
javax.security.auth.login.Configuration
public static Configuration
getConfiguration()
|
checkPermission | javax.security.auth.AuthPermission "getLoginConfiguration" |
javax.security.auth.login.Configuration
public static void setConfiguration(
Configuration configuration)
|
checkPermission | javax.security.auth.AuthPermission "setLoginConfiguration" |
javax.security.auth.login.Configuration
public static void refresh()
|
checkPermission | javax.security.auth.AuthPermission "refreshLoginConfiguration" |
javax.security.auth.login.Configuration
public static Configuration
getInstance(
String type,
SpiParameter params)
getInstance(
String type,
SpiParameter params,
String provider)
getInstance(String type,
SpiParameter params,
Provider provider)
|
checkPermission | javax.security.auth.AuthPermission "createLoginConfiguration.{type}" |
次の表では、java.lang.SecurityManagerメソッドのデフォルトの実装によってチェックされるアクセス権を示します。
指定された各checkメソッドはSecurityManager checkPermissionメソッドを指定されたアクセス権で呼び出します(コンテキスト引数を取るcheckConnectおよびcheckReadメソッドを除く)。これらのメソッドは、AccessControlContextコンテキストを想定し、コンテキストのcheckPermissionメソッドを指定されたアクセス権で呼び出します。
表1-7 java.lang.SecurityManagerのメソッドおよびアクセス権
| メソッド | アクセス権 |
|---|---|
public void checkAccept(String host, int port); |
java.net.SocketPermission "{host}:{port}", "accept";
|
public void checkAccess(Thread t); |
java.lang.RuntimePermission "modifyThread"; |
public void checkAccess(ThreadGroup g); |
java.lang.RuntimePermission "modifyThreadGroup"; |
public void checkAwtEventQueueAccess(); 注意: このメソッドは非推奨です。かわりにpublic void checkPermission(Permission perm);を使用 |
java.awt.AWTPermission "accessEventQueue"; |
public void checkConnect(String host, int port); |
if (port == -1)
java.net.SocketPermission "{host}","resolve";
else
java.net.SocketPermission "{host}:{port}","connect";
|
public void checkConnect( String host, int port, Object context); |
if (port == -1)
java.net.SocketPermission "{host}","resolve";
else
java.net.SocketPermission "{host}:{port}","connect";
|
public void checkCreateClassLoader(); |
java.lang.RuntimePermission "createClassLoader"; |
public void checkDelete(String file); |
java.io.FilePermission "{file}", "delete";
|
public void checkExec(String cmd); |
cmdが絶対パスの場合: java.io.FilePermission "{cmd}", "execute";
それ以外の場合 java.io.FilePermission "<<ALL_FILES>>", "execute"; |
public void checkExit(int status); |
java.lang.RuntimePermission "exitVM.{status}";
|
public void checkLink(String lib); |
java.lang.RuntimePermission "loadLibrary.{lib}";
|
public void checkListen(int port); |
java.net.SocketPermission "localhost:{port}","listen";
|
public void checkMemberAccess(Class clazz, int which); 注意: このメソッドは非推奨です。かわりにpublic void checkPermission(Permission perm);を使用 |
if (which != Member.PUBLIC) {
if (currentClassLoader() != clazz.getClassLoader()) {
checkPermission(
new java.lang.RuntimePermission(
"accessDeclaredMembers"));
}
}
|
public void checkMulticast(InetAddress maddr); |
java.net.SocketPermission( maddr.getHostAddress(),"accept,connect"); |
public void checkMulticast(InetAddress maddr, byte ttl); 注意: このメソッドは非推奨です。かわりにpublic void checkPermission(Permission perm);を使用 |
java.net.SocketPermission( maddr.getHostAddress(),"accept,connect"); |
public void checkPackageAccess(String pkg); |
java.lang.RuntimePermission "accessClassInPackage.{pkg}";
|
public void checkPackageDefinition(String pkg); |
java.lang.RuntimePermission "defineClassInPackage.{pkg}";
|
public void checkPrintJobAccess(); |
java.lang.RuntimePermission "queuePrintJob"; |
public void checkPropertiesAccess(); |
java.util.PropertyPermission "*", "read,write"; |
public void checkPropertyAccess(String key); |
java.util.PropertyPermission "{key}", "read,write";
|
public void checkRead(FileDescriptor fd); |
java.lang.RuntimePermission "readFileDescriptor"; |
public void checkRead(String file); |
java.io.FilePermission "{file}", "read";
|
public void checkRead(String file, Object context); |
java.io.FilePermission "{file}", "read";
|
public void checkSecurityAccess(String target); |
java.security.SecurityPermission "{target}";
|
public void checkSetFactory(); |
java.lang.RuntimePermission "setFactory"; |
public void checkSystemClipboardAccess(); 注意: このメソッドは非推奨です。かわりにpublic void checkPermission(Permission perm);を使用 |
java.awt.AWTPermission "accessClipboard"; |
public boolean checkTopLevelWindow(Object window); 注意: このメソッドは非推奨です。かわりにpublic void checkPermission(Permission perm);を使用 |
java.awt.AWTPermission "showWindowWithoutWarningBanner"; |
public void checkWrite(FileDescriptor fd); |
java.lang.RuntimePermission "writeFileDescriptor"; |
public void checkWrite(String file); |
java.io.FilePermission "{file}", "write";
|
public SecurityManager(); |
java.lang.RuntimePermission "createSecurityManager"; |
Javaプログラミング言語のアプリケーション環境のポリシーは、様々なソースを出所とするコードがどのようなアクセス権を使用できるかを指定し、様々なプリンシパルとして実行するもので、Policyオブジェクトによって表されます。具体的には、Policyクラス(java.securityパッケージ内)内のabstractメソッドの実装を提供するPolicyサブクラスによって表されます。
Policyオブジェクトが使用するポリシー情報がどこに置かれるかは、Policyの実装によります。Policyのリファレンス実装では、ポリシー情報を静的なポリシー構成ファイルから得ます。
このドキュメントの残りの部分では、Policyのリファレンス実装と、それによって読み取られるポリシー・ファイルで使用する構文について説明します。
Policyのリファレンス実装では、1つまたは複数のポリシー構成ファイルからポリシーを指定できます。ポリシー構成ファイルでは、指定されたコード・ソースからのコードに対してどのようなアクセス権を与え、指定されたプリンシパルとして実行するかを指定します。各構成ファイルは、UTF-8方式でエンコードする必要があります。
デフォルトでは、システム全体のポリシー・ファイルが1つと、ユーザー・ポリシー・ファイル(オプション)が1つ存在します。デフォルトでは、常に、プラットフォーム・クラス・ローダーによってロードされるJDKモジュールまたはその祖先で必要なアクセス権が付与されます。
Policyのリファレンス実装は、そのgetPermissionsメソッドがはじめて呼び出されたとき、あるいは、そのrefreshメソッドが呼び出されたときに初期化されます。初期化時には、ポリシー構成ファイル(ポリシー・ファイルの構文を参照)の解析が行われた後、その情報がPolicyオブジェクトに読み込まれます。
デフォルトでは、システム全体のポリシー・ファイルが1つと、ユーザー・ポリシー・ファイル(オプション)が1つ存在します。Policyが初期化されると、まずシステム・ポリシーがロードされ、次に、ロードされたシステム・ポリシーにユーザー・ポリシーが追加されます。どちらのポリシーも存在しない場合は、組込みポリシーが使われます。この組込みポリシーは、JREとともにインストールしたjava.policyファイルと同じです。
システム・ポリシー・ファイルの場所
デフォルトでは、システム・ポリシー・ファイルは<java-home>/conf/security/java.policyです。
システムのポリシー・ファイルは、システム全体にわたってコードにアクセス権を与えます。JDKに含まれているjava.policyファイルは、すべてのユーザーに動的ポートでの待機を許可し、すべてのコードに、セキュリティにかかわらない特定の標準プロパティ(os.nameプロパティやfile.separatorプロパティなど)の読取りを許可します。
ユーザー・ポリシー・ファイルの場所
デフォルトでは、ユーザー・ポリシー・ファイルは<user-home>/.java.policyです。
ポリシー・ファイルの場所と形式
ポリシー・ファイルの場所は、セキュリティ・プロパティ・ファイル<java-home>/conf/security/java.securityで指定されています。
ポリシー・ファイルの場所は、次のような形式の名前を持つプロパティの値として指定されています。
policy.url.n
ここで、nは数値です。次に示す形式の行で、それぞれのプロパティの値を指定します。
policy.url.n=URL
ここで、URLはURLの指定を表します。たとえば、デフォルトのシステムおよびユーザー・ポリシー・ファイルは、セキュリティ・プロパティ・ファイルに次のように指定されています。:
policy.url.1=file:${java.home}/conf/security/java.policy
policy.url.2=file:${user.home}/.java.policy
(${java.home}を使用してjava.homeプロパティの値を指定するなど、特別な構文でプロパティの値を指定する方法の詳細は、ポリシー・ファイル内のプロパティの展開を参照。)
URLをいくつも指定して(http://形式のものを含む)、該当するポリシー・ファイルをすべてロードすることもできます。また、上に示したポリシー・ファイルの指定のうち、2番目のポリシー・ファイルの指定をコメント・アウトするか、あるいは修正すれば、デフォルト・ユーザー・ポリシー・ファイルの読込みを無効にすることができます。
アルゴリズムは、policy.url.1から処理を開始して、番号を1つずつ増やしながら、URLが見つからなくなるまで処理を続けます。したがって、policy.url.1とpolicy.url.3がある場合、policy.url.3は読み込まれません。
実行時に新しいポリシー・ファイルを指定する
アプリケーションを実行するときに、追加のポリシー・ファイルや別のポリシー・ファイルを指定することもできます。これは、コマンド行引数を使用して-Djava.security.policyjava.security.policyプロパティの値を設定することで実行できます。たとえば、次のコマンドを入力した場合(ここで、someURLはポリシー・ファイルの場所を指定するURL)、指定したポリシー・ファイルが、セキュリティ・プロパティ・ファイルに指定されているすべてのポリシー・ファイルに加えてロードされます。
java-Djava.security.manager-Djava.security.policy=someURL SomeApp
次に示すとおり、URLは通常のURLでも、単純に現在のディレクトリのポリシー・ファイルの名前でもかまいません。:
java -Djava.security.manager -Djava.security.policy=mypolicy SomeApp
-Djava.security.managerオプションによってデフォルト・セキュリティ・マネージャがインストールされるので、このアプリケーションに対してはポリシーのチェックが行われます。アプリケーションSomeAppがセキュリティ・マネージャをインストールする場合は、この引数は必要ありません。
次のコマンドを使用した場合(等号が2つ使用されていることに注意)、指定されたポリシー・ファイルのみが使用され、セキュリティ・プロパティ・ファイルに示されたポリシー・ファイルはすべて無視されます。
java-Djava.security.manager-Djava.security.policy==someURL SomeApp
注意:
セキュリティ・プロパティ・ファイル内のpolicy.allowSystemPropertyプロパティがfalseに設定されている場合、-Djava.security.policyオプションのポリシー・ファイル値は無視されます。デフォルトは、trueです。セキュリティ・プロパティ・ファイル(JDKのconf/securityディレクトリのjava.securityファイル)を編集すれば、Policyのリファレンス実装を変更できます。
新しいポリシー・クラスを作成し、Policyのリファレンス実装クラスと置き換えることもできます。この場合は、Policy抽象クラスのサブクラスを作成し、getPermissionsメソッド(必要に応じてその他のメソッドも)を実装します。
java.securityで設定できるプロパティの例を次に示します。
policy.provider=PolicyClassName
PolicyClassNameには、目的のPolicy実装クラスを完全修飾名で指定します。
デフォルトのセキュリティ・プロパティ・ファイルでは、このプロパティは次のように指定されています。
policy.provider=sun.security.provider.PolicyFile
カスタマイズするには、次のように、このプロパティに別のクラスを指定します。
policy.provider=com.mycom.MyPolicy
インストールしたJDKのポリシー構成ファイルでは、指定されたコード・ソースからのコードに対し、どのようなアクセス権(システム・リソースへのアクセスの種類)を与え、指定したプリンシパルとして実行するかを指定します。
アプレット(またはセキュリティ・マネージャの下で動作しているアプリケーション)が、ファイルの読み書きなど、セキュリティ保護された操作を行うためには、その操作を行うためのアクセス権が与えられている必要があります。Policyのリファレンス実装では、ポリシー構成ファイルの付与エントリによって、そのアクセス権を与える必要があります。詳細は、以降の説明とJavaセキュリティ・アーキテクチャ仕様を参照してください。(ただし、同じ(URLの)場所にあるファイルと、その場所のサブディレクトリにあるファイルの読取りアクセス権は、常に自動的に与えられます。したがって、そのようなアクセス権については、明示的に指定する必要はありません。)
ポリシー構成ファイルは、エントリのリストで構成されます。1つのkeystoreエントリと、0以上のgrantエントリを持たせることができます。
キーストアは、非公開鍵と、対応する公開鍵を認証するX.509証明書チェーンなどのデジタル証明書が格納されたデータベースです。キーストアの作成と管理には、keytoolユーティリティを使用します。ポリシー構成ファイルで指定されているキーストアは、そのファイルのgrantエントリで指定されている署名者の公開鍵を照合するために使用されます。署名者の別名を指定しているgrantエントリがある場合、またはプリンシパルの別名を指定しているgrantエントリがある場合は、ポリシー構成ファイルに必ずkeystoreエントリを置きます。
このとき、ポリシー・ファイル内で有効なkeystore/keystorePasswordURLエントリは1つのみです。最初のエントリ以外の後続エントリは無視されます。このエントリは、ファイルのgrantエントリ外部の任意の場所に配置できます。構文は次のとおりです。
keystore "some_keystore_url", "keystore_type", "keystore_provider"; keystorePasswordURL "some_password_url";
各構成要素は次のとおりです。
注意:
some_keystore_urlからの入力ストリームはKeyStore.loadメソッドに渡されます。
URLとしてNONEが指定されている場合は、nullのストリームがKeyStore.loadメソッドに渡されます。NONEは、キーストアがファイルベースでない場合にURLで指定してください。たとえば、ハードウェア・トークン・デバイスに置かれている場合などです。
URLは、ポリシー・ファイルがある場所からの相対位置を表します。たとえば、セキュリティ・プロパティ・ファイルの中でポリシー・ファイルが次のように指定されているとします。
policy.url.1=http://foo.example.com/fum/some.policy
また、このポリシー・ファイルには、次のエントリがあるとします。
keystore ".keystore";
この場合、キーストアは次の場所からロードされます。
http://foo.example.com/fum/.keystore
URLに絶対位置を指定することもできます。
キーストアのタイプは、キーストア情報の格納形式とデータ形式を定義するとともに、キーストア内の非公開鍵とキーストア自体の整合性を保護するために使われるアルゴリズムを定義します。デフォルトの型は"PKCS12"です。したがって、キーストアのタイプがPKCS12であれば、キーストア・エントリを指定する必要はありません。
実行されるコードは、常に、特定の「コード・ソース」(CodeSource型のオブジェクトによって表される)から来ると考えられます。コード・ソースは、コードの出所を表す場所(URL)だけでなく、コードの署名に使われた非公開鍵に対応する公開鍵を含んだ証明書への参照も含みます。コード・ソース内の証明書は、ユーザーのキーストアからのシンボリックな別名によって参照されます。コードはさらに、特定のプリンシパル(Principal型のオブジェクトによって表される)またはプリンシパルのグループとして実行されると考えられます。
各付与エントリには、オプションのcodeBaseとsignedBy、およびプリンシパルの名前と値のペアのあとに、アクセス権を付与するコードを指定する1つ以上の「アクセス権エントリ」が含まれます。付与エントリの基本形式は、次のとおりです。
grant signedBy "signer_names", codeBase "URL", principal principal_class_name "principal_name", principal principal_class_name "principal_name", ... { permission permission_class_name "target_name", "action", signedBy "signer_names"; permission permission_class_name "target_name", "action", signedBy "signer_names"; ... };
上の形式でイタリック体になっていない項目は、示されているとおりに指定します。ただし、大文字と小文字は区別されず、また、以降で説明するように、いくつかの項目はオプションです。イタリックで示されている項目は、可変の項目です。
付与エントリは、grantで始まります。
signedBy、codeBase、およびprincipalの値はオプションです。また、これらのフィールドの順序は問われません。
signedByの値は、キーストアに格納された証明書の別名を示します。証明書内の公開鍵は、コードのデジタル署名の検証に使われます。別名によって指定されたキーストア・エントリ内の公開鍵に対応する、非公開鍵で署名されたコードに、アクセス権を付与します。
signedByの値には、複数の別名をカンマで区切って指定できます。たとえば、"Adam,Eve,Charles"のように指定できます。この場合は、各要素がORではなくANDで結ばれ、「Adam、EveおよびCharlesによって署名された」という意味になります。より厳密には、「Adamによって署名されたコード」とは、「Adamという別名が付けられたエントリを持つキーストアにある公開鍵証明書に対応する、非公開鍵を使って署名されたJARファイルに含まれている、クラス・ファイル内のコード」という意味です。
signedByフィールドはオプションです。省略した場合は、「任意の署名者」という意味になります。コードに署名が付いているかどうか、だれが署名しているかは問われなくなります。
プリンシパルの値はclass_nameとprincipal_nameのペアを指定します。このペアは、実行中のスレッドのプリンシパル・セット内にある必要があります。プリンシパル・セットは、Subjectによって実行するコードに関連付けられます。
principal_class_nameにワイルドカード値(*)を設定することで、任意のPrincipalクラスに一致させることができます。さらに、principal_nameにワイルドカード値(*)を設定することで、任意のPrincipal名に一致させることができます。principal_class_nameまたはprincipal_nameに*を設定するときは、*を引用符で囲まないでください。また、ワイルドカードのプリンシパル・クラスを指定する場合は、ワイルドカードのプリンシパル名も指定する必要があります。
プリンシパル・フィールドは省略可能です。省略した場合は、「任意のプリンシパル」という意味になります。
プリンシパルclass_name/principal_nameのペアが単一引用符で囲まれた文字列として指定される場合は、キーストアの別名として扱われます。キーストアは別名を経由してX509証明書を調査し、問い合わせます。キーストアがある場合、プリンシパルclass_nameは自動的にjavax.security.auth.x500.X500Principalとして扱われ、principal_nameは自動的に証明書のサブジェクト識別名として扱われます。X509証明書のマッピングが見つからない場合は、grantエントリはすべて無視されます。
codeBaseの値は、コードが置かれる場所を示します。この場所からコードにアクセス権を付与します。codeBaseエントリを省略した場合は、「任意のコード」という意味になり、コードの出所は問われません。
注意:
codeBaseの値はURLであるため、コード・ソースがWindowsシステム上にある場合であっても、ディレクトリのセパレータには、バックスラッシュではなく、必ずスラッシュを使用します。したがって、Windowsシステム上でコードの場所がC:\somepath\api\の場合、codeBaseポリシー・エントリは次のように指定します。 grant codeBase "file:/C:/somepath/api/" {
...
};
codeBase値の正確な意味は、末尾の文字によって異なります。末尾が/のcodeBaseは、指定されたディレクトリ内のすべてのクラス・ファイル(JARファイルを除く)を示します。末尾が/*のcodeBaseは、そのディレクトリ内にあるすべてのファイル(クラス・ファイルとJARファイルの両方)を示します。末尾が/-のcodeBaseは、指定されたディレクトリとその下の全サブディレクトリ内のすべてのファイル(クラス・ファイルとJARファイルの両方)を示します。次の表では、様々なケースを示します。
表1-8 キーストア別名
| ダウンロードされたコードのcodebase URL | ポリシーのcodebase URL | 一致するかどうか |
|---|---|---|
| www.example.com/people/gong/ | www.example.com/people/gong | はい |
| www.example.com/people/gong/ | www.example.com/people/gong/ | はい |
| www.example.com/people/gong/ | www.example.com/people/gong/* | はい |
| www.example.com/people/gong/ | www.example.com/people/gong/- | はい |
| www.example.com/people/gong/appl.jar | www.example.com/people/gong/ | いいえ |
| www.example.com/people/gong/appl.jar | www.example.com/people/gong/- | はい |
| www.example.com/people/gong/appl.jar | www.example.com/people/gong/* | はい |
| www.example.com/people/gong/appl.jar | www.example.com/people/- | はい |
| www.example.com/people/gong/appl.jar | www.example.com/people/* | いいえ |
| www.example.com/people/gong/ | www.example.com/people/- | はい |
| www.example.com/people/gong/ | www.example.com/people/* | いいえ |
アクセス権エントリは、単語permissionで始まります。前述のテンプレートにある単語permission_class_nameは、実際にはjava.io.FilePermissionやjava.lang.RuntimePermissionなどの特定のアクセス権タイプになります。
java.io.FilePermission (どのような種類のファイル・アクセスを許可するかを指定)など、多くのアクセス権タイプでは"action"が必須です。java.lang.RuntimePermissionなどのカテゴリでは不要なため、必須ではありません。permission_class_nameの後の"target_name"値で指定されたアクセス権が与えられるか、アクセス権が与えられないかのどちらかになります。
アクセス権エントリのsignedByの名前と値のペアは省略可能です。この値が存在する場合は、署名付きアクセス権であることを示します。つまり、そのアクセス権を与えられるようにするためには、アクセス権クラスそれ自体が、指定された別名によって署名されていなければなりません。たとえば、次のような付与エントリがあるとします。
grant {
permission Foo "foobar", signedBy "FooSoft";
};
この場合、このアクセス権タイプFooが与えられるのは、あるJARファイルにアクセス権Foo.classが置かれていて、そのJARファイルが、別名FooSoftにより指定された証明書内の公開鍵に対応する非公開鍵によって署名されているときか、Foo.classがシステム・クラスであるときです(システム・クラスはポリシーによる制限を受けないため)。
アクセス権エントリの各項目は、指定された順序(permission、permission_class_name、"target_name"、"action"、およびsignedBy "signer_names")で並んでいる必要があります。各エントリはセミコロンで終わります。
識別子(permission、signedBy、codeBaseなど)では大文字と小文字は区別されませんが、permission_class_nameと、値として引き渡される文字列については大文字と小文字が区別されます。
注意:
FilePermissionパス名の正規化方法における変更に関する重要な情報については、付録A: FilePermissionのパス名の正規化がデフォルトで無効化を参照してください。
java.io.FilePermissionを指定する場合、"target_name"はファイル・パスになります。Windowsシステムでは、ファイル・パスをcodebase URLではなく直接文字列で指定する場合は、パス中のバックスラッシュは、次のように2つ重ねて指定する必要があります
grant {
permission java.io.FilePermission "C:\\users\\cathy\\foo.bat", "read";
};
これは、文字列はトークナイザ(java.io.StreamTokenizer)によって処理され、トークナイザは「\」をエスケープ文字列と解釈するため(たとえば、「\n」は改行を表す)、バックスラッシュそのものを表すには、バックスラッシュを2つ重ねる必要があるからです。トークナイザは、上記のファイル・パス文字列の処理を終えると、二重のバックスラッシュを単一のバックスラッシュに変換し、最終的には次のようになります。
"C:\users\cathy\foo.bat"
次のポリシー構成には、次の2つのエントリがあります。
// If the code is signed by "Duke", grant it read/write access to all
// files in /tmp:
grant signedBy "Duke" {
permission java.io.FilePermission "/tmp/*", "read,write";
};
// Grant everyone the following permission:
grant {
permission java.util.PropertyPermission "java.vendor", "read";
};
次のポリシー構成ファイルは、次の条件を満たすコードのみがSecurityクラス内のメソッドを呼び出して、プロバイダの追加または削除を行ったり、Securityプロパティを設定できることを指定します。
/home/sysadmin/"ディレクトリにある、署名されたJARファイルからコードがロードされた。sysadminによって参照される公開鍵で認証される。 grant signedBy "sysadmin", codeBase "file:/home/sysadmin/*" {
permission java.security.SecurityPermission "Security.insertProvider.*";
permission java.security.SecurityPermission "Security.removeProvider.*";
permission java.security.SecurityPermission "Security.setProperty.*";
};
ポリシー・エントリのいずれか(または両方)を省略可能です。
次は、codeBaseを省略したポリシー構成ファイルです。
grant signedBy "sysadmin" {
permission java.security.SecurityPermission "Security.insertProvider.*";
permission java.security.SecurityPermission "Security.removeProvider.*";
};
このポリシーが有効な場合、"sysadmin"によって署名されたJARファイルに含まれるコードは、JARファイルの出所に関係なく、プロバイダの追加と削除を行えます。
次は、署名者を省略したポリシー構成ファイルです。
grant codeBase "file:/home/sysadmin/-" {
permission java.security.SecurityPermission "Security.insertProvider.*";
permission java.security.SecurityPermission "Security.removeProvider.*";
};
この場合、ローカル・ファイル・システムの"home/sysadmin/"ディレクトリに置かれたコードは、プロバイダの追加と削除を行うことができます。コードに署名は必要ありません。
次は、codeBaseとsignedByを両方とも省略したポリシー構成ファイルです。
grant {
permission java.security.SecurityPermission "Security.insertProvider.*";
permission java.security.SecurityPermission "Security.removeProvider.*";
};
この例では、コード・ソースを指定する要素がどちらも省略されています。したがって、出所がどこか、署名が付いているか、だれの署名が付いているかに関係なく、どのコードでもプロバイダの追加と削除が行えます。
次は、プリンシパルベースのエントリを表しています。
grant principal javax.security.auth.x500.X500Principal "cn=Alice" {
permission java.io.FilePermission "/home/Alice", "read, write";
};
これにより、X500Principalのアクセス権cn=Aliceとして実行するコードは/home/Aliceを読み取ることも書き込むことも可能になります。
次は、ワイルドカード値を含むプリンシパルベースのエントリを表しています。
grant principal javax.security.auth.x500.X500Principal * {
permission java.io.FilePermission "/tmp", "read, write";
};
これにより、X500Principalのアクセス権(識別名に関係なく)として実行するコードは/tmpを読み取ることも書き込むことも可能になります。
次の例は、codesource情報とprincipal情報を持つgrant文を表しています。
grant codebase "http://www.games.example.com",
signedBy "Duke",
principal javax.security.auth.x500.X500Principal "cn=Alice" {
permission java.io.FilePermission "/tmp/games", "read, write";
};
これにより、"Duke"によって署名され、"www.games.example.com"からダウンロードされたコードが"cn=Alice"によって実行されると、"/tmp/games"ディレクトリへの読取り権と書出し権が与えられます。
次の例は、キーストアの別名を置き換えるgrant文を示しています。
keystore "http://foo.example.com/blah/.keystore";
grant principal "alice" {
permission java.io.FilePermission "/tmp/games", "read, write";
};
"alice"は次のように置き換えられます。
javax.security.auth.x500.X500Principal "cn=Alice"
これは、キーストア別名aliceに関連付けられたX.509証明書に、サブジェクトの識別名"cn=Alice"があることが前提となります。これにより、X500Principalのアクセス権"cn=Alice"によって実行されるコードに、"/tmp/games"ディレクトリへの読取り権と書出し権が与えられます。
ポリシー・ファイルとセキュリティ・プロパティ・ファイルでは、プロパティの展開が可能です。
プロパティの展開は、シェルでの変数の展開に似ています。ポリシー・ファイルまたはセキュリティ・プロパティ・ファイルに次のような文字列がある場合、
${some.property}
この文字列はシステム・プロパティの値に展開されます。次に例を示します。
permission java.io.FilePermission "${user.home}", "read";
この場合、"${user.home}"は、システム・プロパティ"user.home"の値に展開されます。そのプロパティの値が"/home/cathy"である場合、上の記述は下の記述と同じになります
permission java.io.FilePermission "/home/cathy", "read";
プラットフォームにより異なるポリシー・ファイルを使いやすくするために、${/}という特殊な表記(${file.separator}の簡略形)も使用できます。この表現を使用して、次のような指定が可能です。
permission java.io.FilePermission "${user.home}${/}*", "read";
user.homeプロパティの値が/home/cathyで、プラットフォームがSolaris、LinuxまたはmacOSである場合、これは次のように変換されます。
permission java.io.FilePermission "/home/cathy/*", "read";
Windowsシステムで、"user.home"の値がC:\users\cathyであれば、次のように変換されます。
permission java.io.FilePermission "C:\users\cathy\*", "read";
特殊なケースとして、コード・ベースのプロパティを次のように記述すると、
grant codeBase "file:${my.libraries}/api/"
ファイル・セパレータ文字は自動的に/文字に変換されます。たとえば、値がmy.librariesである場合はC:\Users\me\libとなります。したがって、Windowsシステムでは次のように変換されます。
grant codeBase "file:C:/Users/me/lib/api/"
したがって、コード・ベース文字列では${/}を使用する必要はありません(使用しないでください)。プロパティの展開は、ポリシー・ファイル内で、二重引用符で囲まれた文字列が使用できる場所であればどこでも行われます。これには、"signer_names"、"URL"、"target_name"、"action"の各フィールドが含まれます。プロパティの展開が許可されるかどうかは、セキュリティ・プロパティ・ファイルの"policy.expandProperties"プロパティの値によって決まります。このプロパティの値がtrue (デフォルト)の場合は、展開が許可されます。
注意:
ネストされたプロパティは使用できません。次に例を示します。
"${user.${foo}}"
この例では、"foo"プロパティが"home"に設定されている場合であっても、エラーになります。これは、プロパティ構文解析プログラムはネストされたプロパティを認識しないためです。プロパティ構文解析プログラムは、最初の${を見つけると、次に最初の}を探し、その結果(この場合は${user.$foo})をプロパティと解釈しようとします。しかし、そのようなプロパティがない場合はエラーになります。
注意:
付与エントリ、アクセス権エントリまたはキーストア・エントリで展開できないプロパティがある場合、そのエントリは無視されます。たとえば、次のようにシステム・プロパティ"foo"が定義されていない場合、
grant codeBase "${foo}" {
permission ...;
permission ...;
};
このgrantエントリ内のpermissionはすべて無視されます。また、次のような場合、
grant {
permission Foo "${foo}";
permission Bar "barTarget";
};
"permission Foo..."エントリだけが無視されます。また、次のように指定されている場合、
keystore "${foo}";
この場合は、keystoreエントリが無視されます。
Windowsシステムでのファイル・パス仕様には、実際の1つバックスラッシュごとに、2つのバックスラッシュを含める必要があります。
Windowsシステムでのファイル・パスの指定で説明したように、Windowsシステムでは、ファイル・パスをcodebase URLではなく直接文字列で指定する場合は、パス内の実際の単一のバックスラッシュごとに、次のように2つのバックスラッシュを含める必要があります
grant {
permission java.io.FilePermission "C:\\users\\cathy\\foo.bat", "read";
};
これは、文字列はトークナイザ(java.io.StreamTokenizer)によって処理され、トークナイザは\をエスケープ文字列と解釈するため(たとえば、\nは改行を表す)、バックスラッシュそのものを表すには、バックスラッシュを2つ重ねる必要があるからです。トークナイザは、上記のファイル・パス文字列の処理を終えると、二重のバックスラッシュを単一のバックスラッシュに変換し、最終的には次のようになります。
"C:\users\cathy\foo.bat"
文字列中のプロパティの展開は、トークナイザがその文字列の処理を完了したあとに行われます。たとえば、次のような文字列があるとします。
"${user.home}\\foo.bat"
トークナイザは、この文字列中の二重のバックスラッシュを単一のバックスラッシュに変換し、結果は次のようになります。
"${user.home}\foo.bat"
次に、${user.home}プロパティが展開されて次のようになります。 "C:\users\cathy\foo.bat"ここでは、"
user.home"の値をC:\users\cathyとしています。もちろん、プラットフォームに依存しないために、明示的にスラッシュを使うのではなく、${/}プロパティを使って次のように指定する方が望ましいと言えます。 "${user.home}${/}foo.bat"
ポリシー・ファイルでは一般化された形式の展開もサポートされています。たとえば、アクセス権名が次の形式の文字列を含んでいるとします。
${{protocol:protocol_data}}
このような文字列がアクセス権名に含まれる場合、protocolの値によって実行される展開のタイプが決まり、protocol_dataは展開を実行するために使用されます。protocol_dataは空にすることもできます。空の場合、前述の文字列は次のような単純な形式になります。
${{protocol}}
デフォルトのポリシー・ファイルの実装では、次の2つのプロトコルがサポートされます。
${{self}}
プロトコルselfは、${{self}}文字列全体を1つ以上のプリンシパル・クラスとプリンシパル名のペアに置き換えることを示します。実際に実行される置換えは、permissionを含むgrant節の内容によって決まります。
grant節にプリンシパルの情報が含まれていない場合は、permissionは無視されます。プリンシパルベースのgrant節のコンテキストでは、ターゲット名に${{self}}を含むpermissionのみが有効です。たとえば、次のgrant節内のBarPermissionは常に無視されます。
grant codebase "www.example.com", signedby "duke" {
permission BarPermission "... ${{self}} ...";
};
grant句にプリンシパル情報が含まれている場合は、${{self}}がそのプリンシパル情報に置き換えられます。たとえば、次のgrant句のBarPermission内の${{self}}は、javax.security.auth.x500.X500Principal "cn=Duke"に置き換えられます。
grant principal javax.security.auth.x500.X500Principal "cn=Duke" {
permission BarPermission "... ${{self}} ...";
};
grant句内にカンマで区切られたプリンシパルのリストがある場合、${{self}}は、そのカンマで区切られたプリンシパルのリストに置き換えられます。grant句内のプリンシパル・クラスとプリンシパル名がどちらもワイルドカードになっている場合、${{self}}は、現在のAccessControlContext内のSubjectに関連付けられたすべてのプリンシパルに置き換えられます。
次の例は、selfとキーストア別名の置換の両方を含むシナリオを示しています。
keystore "http://foo.example.com/blah/.keystore";
grant principal "duke" {
permission BarPermission "... ${{self}} ...";
};
上の例では、最初にdukeがjavax.security.auth.x500.X500Principal "cn=Duke"に展開されます。ただし、KeyStore別名dukeに関連付けられたX.509証明書にサブジェクト識別名cn=Dukeがあることが前提となります。次に、${{self}}が、grant節内で展開されたその同じプリンシパル情報に置き換えられます。javax.security.auth.x500.X500Principal "cn=Duke"
${{alias:alias_name}}
プロトコルaliasは、java.security.KeyStore別名の置換を示します。KeyStoreエントリに指定されたKeyStoreが使用されます。alias_nameは、KeyStoreの別名を表します。${{alias:alias_name}}は、javax.security.auth.x500.X500Principal "DN"に置き換えられます。このDNは、alias_nameに属する証明書のサブジェクト識別名を表します。次に例を示します。
keystore "http://foo.example.com/blah/.keystore";
grant codebase "www.example.com" {
permission BarPermission "... ${{alias:duke}} ...";
};
上の例では、別名dukeに関連付けられているX.509証明書は、KeyStoreのfoo.example.com/blah/.keystoreから取得されます。dukeの証明書がサブジェクト識別名としてo=dukeOrg, cn=dukeを指定し、${{alias:duke}}がjavax.security.auth.x500.X500Principal "o=dukeOrg, cn=duke"で置き換えられるものとします。
次のエラー条件に該当する場合、アクセス権エントリは無視されます。
正規パスは、リンクやショートカットを含まないパスです。FilePermissionオブジェクトでパス名正規化を実行すると、パフォーマンスに悪影響を与える可能性があります。
JDK 9より前は、2つのFilePermissionオブジェクトが比較されるときに、パス名が正規化されました。これにより、プログラムで、ポリシー・ファイル内でFilePermissionオブジェクトに付与されている名前とは異なる名前を使用してファイルにアクセスできました(そのオブジェクトが同じファイルを指している場合)。正規化では、基にあるファイル・システムにアクセスする必要があったため、非常に低速になる場合がありました。
JDK 9では、パス名正規化はデフォルトでは無効になっています。これは、一方が絶対パスを使用し他方が相対パスを使用する場合、一方がシンボリック・リンクを使用し他方がターゲットを使用する場合、または一方がWindowsロング・ネームを使用し他方がDOS形式の8.3ネームを使用する場合は、2つのFilePermissionオブジェクトが互いに等しくないということです。これは、それらすべてがファイル・システム内の同じファイルを指している場合でも当てはまります。
したがって、パス名がポリシー・ファイルのFilePermissionオブジェクトに付与されている場合、プログラムは同じパス名形式を使用してファイルにアクセスする必要もあります。たとえば、ポリシー・ファイル内のパス名でシンボリック・リンクが使用されている場合、プログラムでもそのシンボリック・リンクを使用する必要があります。ターゲット・パス名でファイルにアクセスすると、アクセス権チェックに失敗します。
互換性レイヤー
相対パスのFilePermissionオブジェクトの付与により(逆に)アプリケーションに絶対パスでのファイルへのアクセスが許可されるように、互換性レイヤーが追加されています。これは、デフォルトのPolicyプロバイダおよび制限付きdoPrivileged呼出しで機能します。
たとえば、相対パス名がaのファイル上のFilePermissionオブジェクトは、絶対パス名が/pwd/a (pwdは現在の作業ディレクトリ)の同一ファイル上のFilePermissionオブジェクトを意味するわけではなくなりました。セキュリティ・マネージャが有効になっている場合は、aを読み取るFilePermissionオブジェクトをコードに付与すると、そのコードで/pwd/aも読み取ることができます。
互換性レイヤーは、シンボリック・リンクとターゲット、Windowsロング・ネームとDOS形式8.3ネーム、または同じ名前に正規化できる他の様々な名前形式の間の変換には対応していません。
パス名正規化のカスタマイズ
表1-9のシステム・プロパティは、FilePermissionパス名正規化のカスタマイズに使用できます。java.lang.Systemプロパティの指定方法を参照してください。表1-9 パス名正規化をカスタマイズするシステム・プロパティ
| システム・プロパティ | デフォルト値 | 説明 |
|---|---|---|
jdk.io.permissionsUseCanonicalPath |
false | このシステム・プロパティは、
|
jdk.security.filePermCompat |
false | このシステム・プロパティは、サードパーティのPolicyの実装をサポートするように互換性レイヤーを拡張するために使用できます。
|