這個問題的解決方案非常簡單。我創建了傑克遜一組視圖類:
@JsonView(SecureViews.Authenticated.class)
public String getPhoneNumber() {
return phoneNumber;
}
什麼上面的規則的意思是:
public class SecureViews {
public static class Public{};
public static class Authenticated extends Public{};
public static class User extends Authenticated{};
public static class Internal extends User {};
}
我然後通過添加以下帶標註的所有每個實體的getter方法我想固定只有在系統內進行身份驗證的用戶才能查看用戶的電話號碼。
或者
@JsonView(SecureViews.User.class)
public List<Event> getEvents() {
return Collections.unmodifiableList(events);
}
然後我創建了一個接口,並實現在我所有的安全實體的接口:
public interface SecurePropertyInterface {
Class<?> getMaxPermissionLevel(Long userID);
}
這裏是方法的實現:
public Class<?> getMaxPermissionLevel(Long userID) {
if (userID != null && userID == uid) {
return SecureViews.User.class;
}
if (SecurityUtils.getSubject().isAuthenticated()) {
return SecureViews.Authenticated.class;
}
return SecureViews.Public.class;
}
現在的魔法。擴展並覆蓋下面的方法:
@Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
Long userID = CTConversionUtils.convertToLong(request.getParameter("id"));
model = (Map<String, Object>) super.filterModel(model);
Class<?> viewClass = SecureViews.Public.class;
if(SecurityUtils.getSubject().isAuthenticated()) {
viewClass = SecureViews.Authenticated.class;
}
for (Entry<String, Object> modelEntry : model.entrySet()) {
if (modelEntry.getValue() instanceof SecurePropertyInterface) {
viewClass = ((SecurePropertyInterface)modelEntry.getValue()).getMaxPermissionLevel(userID);
}
}
objectMapper.viewWriter(viewClass).writeValue(getJsonGenerator(response), model);
}
您也可以覆蓋setObjectMapper
方法來捕獲objectMapper當春天設置您的。
我的Spring配置如下:
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"
p:order="1">
<property name="mediaTypes">
<map>
<entry key="json" value="*/*" />
</map>
</property>
<property name="defaultViews">
<list>
<bean
class="com.bytesizecreations.connecttext.json.SecureMappingJacksonJsonView">
<property name="objectMapper">
<bean
class="org.codehaus.jackson.map.ObjectMapper" />
</property>
</bean>
</list>
</property>
</bean>
那麼,我們現在在這裏?每次需要將響應反序列化爲JSON時,都會調用renderedMergedOutputModel方法。如果用戶的ID在請求中,我們將其存儲。然後,我們可以遍歷模型映射並檢查每個值是否爲SecurePropertyInterface,以及它是否獲得其最大權限級別。
這個策略似乎正確地服務於我的目的。當用戶請求用戶列表時,他們只能獲得已認證的屬性,但當用戶請求自己的詳細信息時,他們只能獲得其私有屬性。
雖然我懷疑這個代碼可以進一步改進,但是我花了太多的時間試圖讓它變得更簡單。
你可以做'Class >',並取消原始類型警告。 – 2011-03-30 06:52:04
謝謝。我已經添加了它。 – 2011-03-30 15:45:42