一個(gè)Subject也許會與一個(gè)AccessControlContext聯(lián)系在一起,可以通過如下方法返回一個(gè)與AccessControlContext聯(lián)系在一起的subject:
public static Subject getSubject(final AccessControlContext acc);
|
一個(gè)特定的Subject通過doAs方法來執(zhí)行一個(gè)特定的操作(Action),原文如下:
The following static methods may be called to perform an action as a
particular Subject:
public static Object
doAs(final Subject subject,
final java.security.PrivilegedAction action);
|
public static Object
doAs(final Subject subject,
final java.security.PrivilegedExceptionAction action)
throws java.security.PrivilegedActionException;
};
|
|
一個(gè)演示第一個(gè)doAs方法的例子:
假設(shè)有個(gè)用戶叫Bob,他已經(jīng)通過了LoginContext的(登陸)驗(yàn)證,隨后,一個(gè)擁有com.ibm.security.Principal標(biāo)識的subject產(chǎn)生了,這個(gè)Principal被命名為“Bob”。同時(shí)假設(shè)SecurityManager已經(jīng)安裝,并且訪問策略文件(PolicyFile)存在,并定義如下:
// 授予 "BOB"訪問(讀)文件 "foo.txt"的許可
grant Principal com.ibm.security.Principal "BOB" {
permission java.io.FilePermission "foo.txt", "read";
};
|
以下是本應(yīng)用的代碼:
class ExampleAction implements java.security.PrivilegedAction {
public Object run() {
java.io.File f = new java.io.File("foo.txt");
// 以下代碼將會觸發(fā)一個(gè)安全檢測(通過Policy)
if (f.exists()) {
System.out.println("File foo.txt exists");
}
return null;
}
}
public class Example1 {
public static void main(String[] args) {
// 驗(yàn)證并鑒別用戶 "BOB",這個(gè)過程在LoginContext那章中有描述
Subject bob;
// 在驗(yàn)證階段,將bob與此Subject相關(guān)聯(lián)
// 以"BOB"的身份執(zhí)行"ExampleAction"
Subject.doAs(bob, new ExampleAction());
}
}
|
在執(zhí)行過程中,ExampleAction在調(diào)用 f.exists() 時(shí)將遭遇一個(gè)安全檢測。由于執(zhí)行ExampleAction的是BOB,而在策略(Policy)文件中,已經(jīng)賦予了Bob有此操作的相關(guān)權(quán)限,ExampleAction將通過安全檢測。如果策略被改變的話,一個(gè)SecurityException的錯(cuò)誤將被拋出。
|
Principals用于描述Subject的身份,其必須繼承java.security.Principal 和java.io.Serializable 接口
LoginContext提供了4中構(gòu)造器,如下:
public LoginContext(String name) throws LoginException;
public LoginContext(String name, Subject subject) throws
LoginException;
public LoginContext(String name, CallbackHandler callbackHandler)
throws LoginException
public LoginContext(String name, Subject subject,
CallbackHandler callbackHandler) throws LoginException
|
它們都統(tǒng)一有個(gè)參數(shù)name,這個(gè)參數(shù)指定了驗(yàn)證所使用的LoginModul
Jaas配置文件如下:
WorkDesk {
net.joinwork.bpm.workdesk.LoginModule required;
};
|
// 用LoginContext 實(shí)例化一個(gè)新的Subject
LoginContext lc = new LoginContext("WorkDesk");
try {
// 驗(yàn)證這個(gè)Subject
lc.login();
System.out.println("驗(yàn)證成功!");
// 獲得被驗(yàn)證成功的Subject
Subject subject = lc.getSubject();
...
// 辦完事 – 退出
lc.logout();
} catch (LoginException le) {
System.err.println("authentication unsuccessful: " +le.getMessage());
}
|
要配置如下圖所示的區(qū)域,可以編輯pages目錄下的:“folder.metadata”文件,這個(gè)文件控制區(qū)域的內(nèi)容
Portlet規(guī)范明確定義了Portlet應(yīng)用如何使用“用戶屬性”,首先,必須在protlet.xml文件中定義屬性如下:
<portlet-app version="1.0" xmlns="http://java./xml/ns/portlet/portlet-app_1_0.xsd">
<user-attribute>
<description>User Given Name</description>
<name>user.name.given</name>
</user-attribute>
<user-attribute>
<description>User Last Name</description>
<name>user.name.family</name>
</user-attribute>
<user-attribute>
<description>User eMail</description>
<name>user.home-info.online.email</name>
</user-attribute>
...
</portlet-app>
|
一旦屬性如上定義,當(dāng)前的portlet就可以利用PortletRequest 中定義的USER_INFO常量來從登陸用戶處以無法更改的Map數(shù)據(jù)格式來獲得當(dāng)前的值,代碼如下:
Map userInfo = (Map)request.getAttribute(PortletRequest.USER_INFO);
String givenName = (userInfo!=null)? (String)userInfo.get("user.name.given") : "";
String lastName = (userInfo!=null) ? (String)userInfo.get("user.name.family") : "";
String email = (userInfo!=null) ? (String)userInfo.get("user.home-info.online.email") : "";
|
|