我正在使用 OWASP 的 AccessReferenceMap 来保护我在 URL 中的 ID。问题是当要混淆的 ID 列表与特定客户相关时。这是我的配置:
<bean id="hyperlinkMapping" class="web.security.HyperlinkMapping" scope="session">
<aop:scoped-proxy />
</bean>
<bean id="tracksAccessMap" class="web.security.EntityAccessMap"
scope="session" factory-method="create">
<constructor-arg index="0" ref="allTrackIdsForCustomer" />
<aop:scoped-proxy/>
</bean>
<bean id="allTrackIdsForCustomer" scope="session"
factory-bean="webTrackDAO"
factory-method="findAllTrackIdsForCustomer">
<aop:scoped-proxy/>
</bean>
<bean id="webTrackDAO" class="web.repository.impl.WebTrackDAOImpl"/>
实体访问地图:
package web.security;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.owasp.esapi.AccessReferenceMap;
import org.owasp.esapi.errors.AccessControlException;
import org.owasp.esapi.reference.RandomAccessReferenceMap;
import org.springframework.stereotype.Component;
import core.domain.Entity;
@Component
public class EntityAccessMap<T extends Entity> implements AccessMap<T> {
private static Logger logger = Logger.getLogger(EntityAccessMap.class);
private static final long serialVersionUID = -436098952674898327L;
private AccessReferenceMap<String> map = new RandomAccessReferenceMap();
public EntityAccessMap() {
}
private EntityAccessMap(final List<T> entities) {
logger.info("Entities size: " + entities.size());
for (final T entity : entities) {
map.addDirectReference(entity);
}
}
public <T extends Entity> AccessMap<T> create(final List<T> entities) {
logger.info("calling create with entities' size " + entities.size() );
return new EntityAccessMap<>(entities);
}
public String getIndirectReference(final T entity) {
for( Iterator it = map.iterator(); it.hasNext(); ) {
logger.info((String)it.next().toString());
}
logger.info("Entity: " + map.getIndirectReference(entity));
return map.getIndirectReference(entity);
}
public T getDirectReference(final String indirectReference) {
try {
return map.getDirectReference(indirectReference);
} catch (AccessControlException e) {
throw new IllegalArgumentException("Indirect Reference is not valid", e);
}
}
}
访问地图:
package web.security;
import java.io.Serializable;
import core.domain.Entity;
public interface AccessMap<T extends Entity> extends Serializable {
String getIndirectReference(final T entity);
T getDirectReference(final String indirectReference);
}
超链接映射:
package web.security;
import java.io.Serializable;
import org.springframework.beans.factory.annotation.Autowired;
import core.domain.track.Track;
public class HyperlinkMapping implements Serializable {
private static final long serialVersionUID = -2011016815710653498L;
@Autowired AccessMap<Track> tracksAccessMap;
public String getTrackId(final Track track) {
return tracksAccessMap.getIndirectReference(track);
}
public Track getTrack(final String indirectId) {
return tracksAccessMap.getDirectReference(indirectId);
}
}
所以,我想要实现的是:tracksAccessMap 应该只填充客户的相关 id,而不是整套。如何在客户登录(并设置 customerId 会话属性)后初始化所有这些 bean?
编辑 1:附加代码:
轨道控制器:
package web.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import core.constants.WebConstants;
import web.service.TrackService;
@Controller
@Secured("ROLE_USER")
@RequestMapping(WebConstants.WEB_MY)
@Scope("session")
public class TracksController {
@Autowired
private TrackService trackService;
@Autowired
private HyperlinkMapping hyperlinkMapping;
@RequestMapping(value=WebConstants.WEB_MYTRACKS, method = RequestMethod.GET, produces = "application/json")
public ModelAndView showTracks( HttpServletRequest request, @RequestParam(value = "pageSize", required = false) Integer pageSize ) {
ModelAndView mv = new ModelAndView();
mv.addObject("pagedListHolder",trackService.getTracksList(request, pageSize == null ? 10 : pageSize ));
mv.addObject("hyperlinkMapping",hyperlinkMapping);
return mv;
}
}
centerColTracks.jsp
<c:forEach items="${pagedListHolder.pageList}" var="item">
<tr>
<td>${item.id}</td>
<td style="color:blue;text-align:right"><a href="<c:url value="${request.getRequestURL()}/my/tracks/${hyperlinkMapping.getTrackId(item)}"/>">${item.name}</a></td>
<td style="color:blue;text-align:right">${item.trackDate}</td>
<td style="color:blue;text-align:right">${item.description}</td>
</tr>
</c:forEach>
hyperlinkMapping.getTrackId(item) 应该只返回与登录的客户相关的 trackId(取自 AccessReferenceMap)。换句话说 - hyperlinkMapping 应该在登录后立即实例化。
我有两个想法如何做到这一点:1.带有返回后建议的AOP,或者2.使用SimpleUrlAuthenticationSuccessHandler,我可以在登录后实例化HyperlinkMapping。或者我可以将它与当前的实现一起使用,而我只是忘记了一些东西?