AccessReferenceMap的问题

时间:2014-12-13 23:16:10

标签: spring owasp esapi

我正在使用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"/>

EntityAccessMap:

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);
        }
    }
}

AccessMap:

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);
}

HyperlinkMapping:

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);
    }
}

所以,我想要实现的目标:trackAccessMap应该只填充客户的相关ID,而不是整套。如何在客户登录后初始化所有这些bean(并设置customerId会话属性)?

编辑1 :附加代码:

TracksController:

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。或者我可以将它与当前的实现一起使用,我只是忘了一些东西?

0 个答案:

没有答案