Last active
September 15, 2015 01:50
-
-
Save seraphy/f85581b2ec7b50035caa to your computer and use it in GitHub Desktop.
JAASによる対話的なログインと、Principalの設定をもつPolicyのセキュリティマネージャを有効にした場合のユーザーによる権限の切り替えの実装例.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Login Configuration for the JAAS Sample Application **/ | |
Sample { | |
jp.seraphyware.jaasexample.SampleLoginModule required debug=true; | |
//com.sun.security.auth.module.NTLoginModule optional debug=true; | |
//com.sun.security.auth.module.Krb5LoginModule required debug=true; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.seraphyware.jaasexample; | |
import java.awt.BorderLayout; | |
import java.awt.Container; | |
import java.awt.Dimension; | |
import java.awt.GridBagConstraints; | |
import java.awt.GridBagLayout; | |
import java.awt.event.ActionEvent; | |
import java.awt.event.WindowAdapter; | |
import java.awt.event.WindowEvent; | |
import java.io.IOException; | |
import java.net.URL; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.Paths; | |
import java.security.CodeSource; | |
import java.security.GeneralSecurityException; | |
import java.security.Policy; | |
import java.security.Principal; | |
import java.security.PrivilegedAction; | |
import java.security.ProtectionDomain; | |
import java.sql.Timestamp; | |
import java.util.ArrayList; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
import javax.security.auth.Subject; | |
import javax.security.auth.callback.Callback; | |
import javax.security.auth.callback.CallbackHandler; | |
import javax.security.auth.callback.NameCallback; | |
import javax.security.auth.callback.PasswordCallback; | |
import javax.security.auth.callback.TextOutputCallback; | |
import javax.security.auth.callback.UnsupportedCallbackException; | |
import javax.security.auth.login.LoginContext; | |
import javax.security.auth.login.LoginException; | |
import javax.swing.AbstractAction; | |
import javax.swing.Box; | |
import javax.swing.JButton; | |
import javax.swing.JFrame; | |
import javax.swing.JLabel; | |
import javax.swing.JOptionPane; | |
import javax.swing.JPanel; | |
import javax.swing.JPasswordField; | |
import javax.swing.JScrollPane; | |
import javax.swing.JTextArea; | |
import javax.swing.JTextField; | |
import javax.swing.SwingUtilities; | |
import javax.swing.UIManager; | |
/** | |
* JAASを使いログイン、ログアウトと、ログイン状態での権限の行使などのサンプル.<br> | |
*/ | |
public class Main extends JFrame { | |
/** | |
* ロガー | |
*/ | |
private static final Logger logger = Logger.getLogger(Main.class.getName()); | |
/** | |
* ログイン情報を表示したりユーザーと対話的に入力するためのコールバック | |
*/ | |
private class MyCallbackHandler implements CallbackHandler { | |
/** | |
* Invoke an array of Callbacks. | |
* | |
* <p> | |
* | |
* @param callbacks | |
* an array of <code>Callback</code> objects which contain | |
* the information requested by an underlying security | |
* service to be retrieved or displayed. | |
* | |
* @exception java.io.IOException | |
* if an input or output error occurs. | |
* <p> | |
* | |
* @exception UnsupportedCallbackException | |
* if the implementation of this method does not support | |
* one or more of the Callbacks specified in the | |
* <code>callbacks</code> parameter. | |
*/ | |
public void handle(Callback[] callbacks) throws IOException, | |
UnsupportedCallbackException { | |
NameCallback nc = null; | |
PasswordCallback pc = null; | |
for (Callback callback : callbacks) { | |
if (callback instanceof TextOutputCallback) { | |
int dlgType = 0; | |
String title = ""; | |
TextOutputCallback toc = (TextOutputCallback) callback; | |
switch (toc.getMessageType()) { | |
case TextOutputCallback.INFORMATION: | |
dlgType = JOptionPane.INFORMATION_MESSAGE; | |
title = "INFORMATION"; | |
break; | |
case TextOutputCallback.ERROR: | |
dlgType = JOptionPane.ERROR_MESSAGE; | |
title = "ERROR"; | |
break; | |
case TextOutputCallback.WARNING: | |
dlgType = JOptionPane.WARNING_MESSAGE; | |
title = "WARNING"; | |
break; | |
default: | |
throw new IOException("Unsupported message type: " | |
+ toc.getMessageType()); | |
} | |
JOptionPane.showMessageDialog(Main.this, toc.getMessage(), | |
title, dlgType); | |
} else if (callback instanceof NameCallback) { | |
nc = (NameCallback) callback; | |
} else if (callback instanceof PasswordCallback) { | |
pc = (PasswordCallback) callback; | |
} else { | |
throw new UnsupportedCallbackException(callback, | |
"Unrecognized Callback"); | |
} | |
} | |
if (nc != null || pc != null) { | |
JPanel pnl = new JPanel(new GridBagLayout()); | |
GridBagConstraints gbc = new GridBagConstraints(); | |
int y = 0; | |
JTextField txtUserName = null; | |
if (nc != null) { | |
gbc.gridx = 0; | |
gbc.gridy = y; | |
gbc.ipadx = 5; | |
gbc.weightx = 0; | |
pnl.add(new JLabel("User Name"), gbc); | |
txtUserName = new JTextField(); | |
Dimension dimUserName = txtUserName.getPreferredSize(); | |
dimUserName.width = 150; | |
txtUserName.setPreferredSize(dimUserName); | |
if (nc != null) { | |
txtUserName.setText(nc.getDefaultName()); | |
} | |
gbc.gridx = 1; | |
gbc.gridy = y; | |
gbc.weightx = 1.; | |
pnl.add(txtUserName, gbc); | |
y++; | |
} | |
JPasswordField txtPassword = null; | |
if (pc != null) { | |
gbc.gridx = 0; | |
gbc.gridy = y; | |
gbc.weightx = 0; | |
pnl.add(new JLabel("Password"), gbc); | |
txtPassword = new JPasswordField(); | |
Dimension dimPassword = txtPassword.getPreferredSize(); | |
dimPassword.width = 150; | |
txtPassword.setPreferredSize(dimPassword); | |
gbc.gridx = 1; | |
gbc.gridy = y; | |
gbc.weightx = 1.; | |
pnl.add(txtPassword, gbc); | |
y++; | |
} | |
int ret = JOptionPane.showConfirmDialog(Main.this, pnl, | |
"Login", JOptionPane.OK_CANCEL_OPTION); | |
if (ret == JOptionPane.OK_OPTION) { | |
if (nc != null) { | |
nc.setName(txtUserName.getText()); | |
} | |
if (pc != null) { | |
pc.setPassword(txtPassword.getPassword()); | |
} | |
} | |
} | |
} | |
} | |
/** | |
* ログインコンテキスト | |
*/ | |
private LoginContext lc = null; | |
/** | |
* サブジェクト | |
*/ | |
private Subject subject = new Subject(); | |
public Main() { | |
try { | |
setTitle("JAAS Example"); | |
setSize(300, 300); | |
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); | |
addWindowListener(new WindowAdapter() { | |
@Override | |
public void windowClosing(WindowEvent e) { | |
onClose(); | |
} | |
@Override | |
public void windowActivated(WindowEvent e) { | |
onActivate(); | |
} | |
}); | |
setLayout(new BorderLayout()); | |
AbstractAction actLogin = new AbstractAction("Login") { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
onLogin(); | |
} | |
}; | |
AbstractAction actShowLoginInfo = new AbstractAction("Info") { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
onShowLoginInfo(); | |
} | |
}; | |
AbstractAction actDoAs = new AbstractAction("doAs(read)") { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
onDoAs(); | |
} | |
}; | |
AbstractAction actDoAs2 = new AbstractAction("doAs(write)") { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
onDoAs2(); | |
} | |
}; | |
AbstractAction actLogout = new AbstractAction("Logout") { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
onLogout(); | |
} | |
}; | |
JButton btnLogin = new JButton(actLogin); | |
JButton btnShowLoginInfo = new JButton(actShowLoginInfo); | |
JButton btnDoAs = new JButton(actDoAs); | |
JButton btnDoAs2 = new JButton(actDoAs2); | |
JButton btnLogout = new JButton(actLogout); | |
Box box = Box.createHorizontalBox(); | |
box.add(btnLogin); | |
box.add(btnShowLoginInfo); | |
box.add(btnDoAs); | |
box.add(btnDoAs2); | |
box.add(btnLogout); | |
JTextArea txtArea = new JTextArea(); | |
txtArea.setText( | |
"ユーザー名が「user」で始まるものを\r\n" + | |
"読み込み可能な有効なユーザーとする.\r\n\r\n" + | |
"「user123」は書き込み権限をもつ。\r\n\r\n" + | |
"パスワードはユーザー名と同じ.\r\n\r\n" + | |
"テスト用ファイルは\r\n" + | |
EXAMPLE_FILE_NAME + "に作成される。"); | |
Container contentPane = getContentPane(); | |
contentPane.add(box, BorderLayout.NORTH); | |
contentPane.add(new JScrollPane(txtArea), BorderLayout.CENTER); | |
} catch (RuntimeException ex) { | |
dispose(); | |
throw ex; | |
} | |
} | |
protected void onClose() { | |
dispose(); | |
} | |
protected void onLogin() { | |
try { | |
lc.login(); | |
JOptionPane.showMessageDialog(this, "logged on!"); | |
} catch (LoginException le) { | |
String msg = "Authentication failed: " + le; | |
logger.log(Level.WARNING, msg, le); | |
JOptionPane.showMessageDialog(this, msg, "ERROR", | |
JOptionPane.WARNING_MESSAGE); | |
} | |
} | |
protected void onLogout() { | |
try { | |
// attempt authentication | |
lc.logout(); | |
JOptionPane.showMessageDialog(this, "logged out!"); | |
} catch (LoginException le) { | |
String msg = "Logout failed: " + le; | |
logger.log(Level.WARNING, msg, le); | |
JOptionPane.showMessageDialog(this, msg, "ERROR", | |
JOptionPane.WARNING_MESSAGE); | |
} | |
} | |
protected void onShowLoginInfo() { | |
StringBuilder buf = new StringBuilder(); | |
for (Principal p : subject.getPrincipals()) { | |
String name = p.getName(); | |
buf.append(p.getClass()).append("\r\n").append(p.toString()) | |
.append("\r\n").append("name=").append(name) | |
.append("\r\n"); | |
} | |
JOptionPane.showMessageDialog(this, buf.toString()); | |
} | |
private static final String EXAMPLE_FILE_NAME = "C:\\temp\\jaasexample.txt"; | |
protected void onDoAs() { | |
try { | |
String ret = Subject.doAsPrivileged(subject, | |
new PrivilegedAction<String>() { | |
@Override | |
public String run() { | |
try{ | |
return String.join("\r\n", Files.readAllLines(Paths | |
.get(EXAMPLE_FILE_NAME))); | |
} catch (IOException ex) { | |
throw new RuntimeException(ex); | |
} | |
} | |
}, null); | |
JOptionPane.showMessageDialog(this, ret); | |
} catch (Exception ex) { | |
ex.printStackTrace(); | |
JOptionPane.showMessageDialog(this, ex.toString(), "ERROR", | |
JOptionPane.ERROR_MESSAGE); | |
} | |
} | |
protected void onDoAs2() { | |
try { | |
String ret = Subject.doAsPrivileged(subject, | |
new PrivilegedAction<String>() { | |
@Override | |
public String run() { | |
try{ | |
Path path = Paths.get(EXAMPLE_FILE_NAME); | |
ArrayList<String> lines = new ArrayList<>(); | |
String msg = new Timestamp(System.currentTimeMillis()).toString(); | |
lines.add(msg); | |
Files.write(path, lines); | |
return msg; | |
} catch (IOException ex) { | |
throw new RuntimeException(ex); | |
} | |
} | |
}, null); | |
JOptionPane.showMessageDialog(this, ret); | |
} catch (Exception ex) { | |
ex.printStackTrace(); | |
JOptionPane.showMessageDialog(this, ex.toString(), "ERROR", | |
JOptionPane.ERROR_MESSAGE); | |
} | |
} | |
protected void onActivate() { | |
// ユーザの認証には、まず javax.security.auth.login.LoginContextが必要です。 | |
// JAASログイン構成ファイル内で「サンプル」という名前のエントリで | |
// 指定されたLoginModuleの実装を使用すると、 | |
// 指定したCallbackHandlerを使用するように指示します。 | |
if (lc == null) { | |
try { | |
lc = new LoginContext("Sample", subject, new MyCallbackHandler()); | |
} catch (LoginException | SecurityException le) { | |
String msg = "Cannot create LoginContext. " + le; | |
logger.log(Level.SEVERE, msg, le); | |
JOptionPane.showMessageDialog(this, msg, "ERROR", | |
JOptionPane.ERROR_MESSAGE); | |
dispose(); | |
} | |
} | |
} | |
/** | |
* エントリポイント | |
*/ | |
public static void main(String[] args) throws GeneralSecurityException { | |
// jaas.configファイルのURLを設定する. | |
URL configURL = Main.class.getResource("jaas.config"); | |
System.setProperty("java.security.auth.login.config", | |
"=" + configURL.toExternalForm()); // 先頭に=をつけると既定値は無視される。 | |
// もしくは | |
// java.security.Security.setProperty("login.config.url.1", "xxx"); | |
// セキュリティマネージャとポリシーファイルの有効化 | |
enableSecurityManagerByPolicyFile(); | |
try { | |
UIManager.setLookAndFeel(UIManager | |
.getCrossPlatformLookAndFeelClassName()); | |
} catch (Exception ex) { | |
logger.log(Level.INFO, ex.toString(), ex); | |
} | |
SwingUtilities.invokeLater(() -> { | |
Main main = new Main(); | |
main.setLocationByPlatform(true); | |
main.setVisible(true); | |
}); | |
} | |
/** | |
* アプリケーション用のポリシーファイルに従いセキュリティポリシーを構成し、 | |
* セキュリティマネージャを有効とする.<br> | |
*/ | |
public static void enableSecurityManagerByPolicyFile() { | |
// リソースからポリシーファイルの取得 | |
URL policyURL = Main.class.getResource("security.policy"); | |
if (policyURL == null) { | |
throw new SecurityException("ポリシーファイルがみつかりません"); | |
} | |
// このクラスのあるプロテクションドメインのコードソースを取得する. | |
// ポリシーファイル中の"app.codebase"変数で展開するもの. | |
ProtectionDomain pd = Main.class.getProtectionDomain(); | |
CodeSource cs = pd.getCodeSource(); | |
URL loc = cs.getLocation(); | |
// ポリシーファイルのURLをシステムプロパティに設定する | |
// 先頭にイコールがある場合はデフォルトのセキュリティポリシーを無視する. | |
// http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html | |
System.setProperty("java.security.policy", "=" + policyURL.toExternalForm()); | |
// システムプロパティにセットする | |
System.setProperty("app.codebase", loc.toExternalForm()); | |
// セキュリティマネージャを有効にする. | |
// 明示的にポリシーファイルが指定されているので、 | |
// アプリ用のポリシーファイルが読み込まれる. | |
System.setSecurityManager(new SecurityManager()); | |
Policy policy = Policy.getPolicy(); | |
System.out.println("policy=" + policy); | |
// policy=sun.security.provider.PolicyFile@28d93b30 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.seraphyware.jaasexample; | |
import java.util.Arrays; | |
import java.util.Map; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
import javax.security.auth.Subject; | |
import javax.security.auth.callback.Callback; | |
import javax.security.auth.callback.CallbackHandler; | |
import javax.security.auth.callback.NameCallback; | |
import javax.security.auth.callback.PasswordCallback; | |
import javax.security.auth.callback.UnsupportedCallbackException; | |
import javax.security.auth.login.FailedLoginException; | |
import javax.security.auth.login.LoginException; | |
import javax.security.auth.spi.LoginModule; | |
public class SampleLoginModule implements LoginModule { | |
private static final Logger logger = Logger | |
.getLogger(SampleLoginModule.class.getName()); | |
private Subject subject; | |
private SamplePrincipal userPrincipal; | |
private SamplePrincipal userPrincipal2; | |
private CallbackHandler callbackHandler; | |
private Map<String, ?> sharedState; | |
private Map<String, ?> options; | |
// configurable option | |
private boolean debug = false; | |
// the authentication status | |
private boolean succeeded = false; | |
// username and password | |
private String username; | |
/** | |
* Initialize this <code>LoginModule</code>. | |
* | |
* <p> | |
* | |
* @param subject | |
* 認証を受ける Subject | |
* | |
* @param callbackHandler | |
* エンドユーザーとの通信 (ユーザー名とパスワードの入力など) に使用される CallbackHandler | |
* | |
* @param sharedState | |
* 構成されたほかの LoginModule と共有する状態 | |
* | |
* @param options | |
* この特定のLoginModule用ログインConfigurationで指定されたオプション。 | |
*/ | |
@Override | |
public void initialize( | |
Subject subject, | |
CallbackHandler callbackHandler, | |
Map<String, ?> sharedState, | |
Map<String, ?> options) { | |
this.subject = subject; | |
this.callbackHandler = callbackHandler; | |
this.sharedState = sharedState; | |
this.options = options; | |
debug = Boolean.parseBoolean((String) options.get("debug")); | |
logger.log(Level.FINE, "sharedState=" + this.sharedState); | |
logger.log(Level.FINE, "options=" + this.options); | |
} | |
/** | |
* Authenticate the user by prompting for a user name and password. | |
* | |
* <p> | |
* | |
* @return true in all cases since this <code>LoginModule</code> should not | |
* be ignored. | |
* | |
* @exception FailedLoginException | |
* if the authentication fails. | |
* <p> | |
* | |
* @exception LoginException | |
* if this <code>LoginModule</code> is unable to perform the | |
* authentication. | |
*/ | |
@Override | |
public boolean login() throws LoginException { | |
// prompt for a user name and password | |
if (callbackHandler == null) { | |
throw new LoginException("Error: no CallbackHandler available " | |
+ "to garner authentication information from the user"); | |
} | |
NameCallback nc = new NameCallback("user name: "); | |
PasswordCallback pc = new PasswordCallback("password: ", false); | |
Callback[] callbacks = {nc, pc}; | |
char password[]; | |
try { | |
callbackHandler.handle(callbacks); | |
username = nc.getName(); | |
char[] tmpPassword = pc.getPassword(); | |
if (username == null) { | |
username = ""; | |
} | |
if (tmpPassword == null) { | |
tmpPassword = new char[0]; | |
} | |
password = new char[tmpPassword.length]; | |
System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length); | |
pc.clearPassword(); | |
} catch (java.io.IOException ioe) { | |
throw new LoginException(ioe.toString()); | |
} catch (UnsupportedCallbackException uce) { | |
throw new LoginException("Error: " + uce.getCallback().toString() | |
+ " not available to garner authentication information " | |
+ "from the user"); | |
} | |
// print debugging information | |
if (debug) { | |
logger.log(Level.INFO, | |
"[SampleLoginModule] user entered user name: " + username); | |
} | |
// パスワードの確認 | |
char[] verifyPassword = username.toCharArray(); | |
succeeded = (username.startsWith("user") && Arrays.equals( | |
verifyPassword, password)); | |
// パスワードのメモリ上からのクリア. | |
Arrays.fill(verifyPassword, ' '); | |
Arrays.fill(password, ' '); | |
// 失敗させる場合は例外、無視する場合はfalseを返す. | |
if (!succeeded) { | |
throw new FailedLoginException("User Name Incorrect"); | |
} | |
return succeeded; | |
} | |
/** | |
* <p> | |
* This method is called if the LoginContext's overall authentication | |
* succeeded (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL | |
* LoginModules succeeded). | |
* | |
* <p> | |
* If this LoginModule's own authentication attempt succeeded (checked by | |
* retrieving the private state saved by the <code>login</code> method), | |
* then this method associates a <code>SamplePrincipal</code> with the | |
* <code>Subject</code> located in the <code>LoginModule</code>. If this | |
* LoginModule's own authentication attempted failed, then this method | |
* removes any state that was originally saved. | |
* | |
* <p> | |
* | |
* @exception LoginException | |
* if the commit fails. | |
* | |
* @return true if this LoginModule's own login and commit attempts | |
* succeeded, or false otherwise. | |
*/ | |
@Override | |
public boolean commit() throws LoginException { | |
if (succeeded == false) { | |
return false; | |
} | |
userPrincipal2 = null; | |
if (username.equals("user123")) { | |
userPrincipal2 = new SamplePrincipal("powerusers"); | |
if (!subject.getPrincipals().contains(userPrincipal2)) { | |
subject.getPrincipals().add(userPrincipal2); | |
} | |
} | |
userPrincipal = new SamplePrincipal("users"); | |
if (!subject.getPrincipals().contains(userPrincipal)) { | |
subject.getPrincipals().add(userPrincipal); | |
} | |
if (debug) { | |
logger.log(Level.INFO, | |
"[SampleLoginModule] added SamplePrincipal to Subject"); | |
} | |
username = null; | |
return true; | |
} | |
/** | |
* <p> | |
* This method is called if the LoginContext's overall authentication | |
* failed. (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL | |
* LoginModules did not succeed). | |
* | |
* <p> | |
* If this LoginModule's own authentication attempt succeeded (checked by | |
* retrieving the private state saved by the <code>login</code> and | |
* <code>commit</code> methods), then this method cleans up any state that | |
* was originally saved. | |
* | |
* <p> | |
* | |
* @exception LoginException | |
* if the abort fails. | |
* | |
* @return false if this LoginModule's own login and/or commit attempts | |
* failed, and true otherwise. | |
*/ | |
@Override | |
public boolean abort() throws LoginException { | |
if (succeeded == false) { | |
return false; | |
} | |
logout(); | |
return true; | |
} | |
/** | |
* Logout the user. | |
* | |
* <p> | |
* This method removes the <code>SamplePrincipal</code> that was added by | |
* the <code>commit</code> method. | |
* | |
* <p> | |
* | |
* @exception LoginException | |
* if the logout fails. | |
* | |
* @return true in all cases since this <code>LoginModule</code> should not | |
* be ignored. | |
*/ | |
@Override | |
public boolean logout() throws LoginException { | |
subject.getPrincipals().remove(userPrincipal); | |
if (userPrincipal2 != null) { | |
subject.getPrincipals().remove(userPrincipal2); | |
} | |
succeeded = false; | |
username = null; | |
userPrincipal = null; | |
userPrincipal2 = null; | |
return true; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.seraphyware.jaasexample; | |
import java.security.Principal; | |
public class SamplePrincipal implements Principal, java.io.Serializable { | |
/** | |
* @serial | |
*/ | |
private String name; | |
/** | |
* Create a SamplePrincipal with a Sample username. | |
* | |
* <p> | |
* | |
* @param name | |
* the Sample username for this user. | |
* | |
* @exception NullPointerException | |
* if the <code>name</code> is <code>null</code>. | |
*/ | |
public SamplePrincipal(String name) { | |
if (name == null) { | |
throw new NullPointerException("illegal null input"); | |
} | |
System.out.println("**Create SamplePrincipal: " + name); | |
this.name = name; | |
} | |
/** | |
* Return the Sample username for this <code>SamplePrincipal</code>. | |
* | |
* <p> | |
* | |
* @return the Sample username for this <code>SamplePrincipal</code> | |
*/ | |
public String getName() { | |
return name; | |
} | |
/** | |
* Return a string representation of this <code>SamplePrincipal</code>. | |
* | |
* <p> | |
* | |
* @return a string representation of this <code>SamplePrincipal</code>. | |
*/ | |
public String toString() { | |
return ("SamplePrincipal: " + name); | |
} | |
/** | |
* Compares the specified Object with this <code>SamplePrincipal</code> for | |
* equality. Returns true if the given object is also a | |
* <code>SamplePrincipal</code> and the two SamplePrincipals have the same | |
* username. | |
* | |
* <p> | |
* | |
* @param o | |
* Object to be compared for equality with this | |
* <code>SamplePrincipal</code>. | |
* | |
* @return true if the specified Object is equal equal to this | |
* <code>SamplePrincipal</code>. | |
*/ | |
public boolean equals(Object o) { | |
if (o == null) | |
return false; | |
if (this == o) | |
return true; | |
if (!(o instanceof SamplePrincipal)) | |
return false; | |
SamplePrincipal that = (SamplePrincipal) o; | |
if (this.getName().equals(that.getName())) | |
return true; | |
return false; | |
} | |
/** | |
* Return a hash code for this <code>SamplePrincipal</code>. | |
* | |
* <p> | |
* | |
* @return a hash code for this <code>SamplePrincipal</code>. | |
*/ | |
public int hashCode() { | |
return name.hashCode(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// jre/lib/ext上のライブラリ群 | |
grant codeBase "file:${{java.ext.dirs}}/*" { | |
permission java.security.AllPermission; | |
}; | |
// アプリケーション自身 | |
grant codeBase "${app.codebase}" { | |
permission javax.security.auth.AuthPermission "createLoginContext.Sample"; | |
permission javax.security.auth.AuthPermission "doAsPrivileged"; | |
permission javax.security.auth.AuthPermission "modifyPrincipals"; | |
permission java.security.SecurityPermission "getPolicy"; | |
permission java.security.SecurityPermission "createAccessControlContext"; | |
}; | |
// usersの場合に許可されるパーミッション | |
grant codebase "${app.codebase}", | |
principal jp.seraphyware.jaasexample.SamplePrincipal "users" { | |
permission java.io.FilePermission "C:\\temp\\*", "read"; | |
}; | |
// power-usersの場合に許可されるパーミッション | |
grant codebase "${app.codebase}", | |
principal jp.seraphyware.jaasexample.SamplePrincipal "powerusers" { | |
permission java.io.FilePermission "C:\\temp\\*", "read, write, delete"; | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment