我的web应用程序目前接受REST请求,并通过一些控制器进行处理,控制器调用相应的服务来执行逻辑。
现在,我想在调用服务之前添加一些安全逻辑。这包括检查是否可以访问服务,如果需要,还可以修改请求主体。我在决定应该在哪里和如何添加这个安全层时遇到了困难。
解决方案1是为每个服务创建安全版本,包装原始服务并在每个控制器中替换它们。只公开受保护的服务,并使原始服务成为私有/包保护。这样,我的所有服务都在它们自己的模块中保持分离,并且安全性得到加强。但我还是干脆更新一下服务吧,而不需要额外的层呢?
解决方案2是创建一个单一的安全服务,接收来自控制器的服务请求,进行安全检查,修改请求主体,然后将更新的请求发送给相应的服务。通过这种方式,我可以只有一个安全模块,并且安全性是强制的,但是这个模块必须知道每个服务,才能分派正确的服务。
解决方案3是创建一个单一的安全服务,并让相应的控制器随意使用它。换句话说,单个控制器处理一些安全逻辑。例如,控制器调用安全检查,然后在调用服务之前通过请求体获取修改后的请求。这样,我就可以只有一个安全模块,这个模块不需要知道每个服务,但它并不是保护任何服务,也不像实用程序类。也就是说,没有强制要求新控制器必须通过这个安全逻辑。
是否有一种解决方案可以加强安全性,保留在自己的模块中,并且不依赖于现有的服务?
发布于 2018-11-06 19:23:00
使用过滤器(拦截器模式)并向Servlet添加一个SecurityFilter类.有很多例子..。我会给你一个我的:
import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.turnmarker.next.models.DistributedSessionModel;
import com.turnmarker.next.models.PayloadModel;
@Component
@Order(0)
public class AuthenticationFilterBean extends AbstractBean implements Filter {
/**
*
*/
private static final long serialVersionUID = 8592924875474194043L;
@SuppressWarnings("unused")
private FilterConfig fc;
// TODO: CHANGE THIS SO THAT SESSION's ARE STORED/RETRIEVED FROM A DISTRIBUTED-SESSION-MAP:
@Autowired
private DistributedSessionModel dsm; // = DistributedSessionModel.getInstance();
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// CAST INTO SOMETHING WE CAN MANIPULATE:
HttpServletRequest req = (HttpServletRequest) request;
Map<String, String[]> params = request.getParameterMap();
// SESSION's ARE STORED/RETRIEVED FROM THE DISTRIBUTED-SESSION-MAP:
HttpSession session = req.getSession(false);
if ((null != session) && (dsm.contains(session.getId()))) {
getLogger().warn("I found your session: " + session.getId());
if (params.get("TURN") == null) {
trace("AuthenticationFilterBean::doFilter() --> HttpServletRequest is missing a required parameter.");
// JUST GO-AWAY:
response.reset();
// response.getOutputStream().close();
// INSTANTIATE:
HttpServletResponse res = (HttpServletResponse) response;
// CONFIGURE:
// res.setContentType("application/json");
res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Required headers not specified in the request");
// GOODBYE, CRUEL WORLD:
res.getOutputStream().flush();
// AND CLOSE:
res.getOutputStream().close();
// AND RETURN:
return;
} else {
trace("AuthenticationFilterBean::doFilter() --> Required parameter located on HttpServletRequest.");
}
}
// OTHERWISE:
chain.doFilter(request, response);
}
@Override
public void destroy() {
trace("AuthenticationFilterBean::destroy() --> Method called");
}
@Override
public void init(FilterConfig conf) throws ServletException {
trace("AuthenticationFilterBean::init() --> Method called");
// STORE:
this.fc = conf;
}
// LOGGER IMPLEMENTATION:
protected Logger logger = LoggerFactory.getLogger(PayloadModel.class);
protected Logger getLogger() {
return logger;
}
protected void setLogger(Logger logger) {
this.logger = logger;
}
}https://softwareengineering.stackexchange.com/questions/381046
复制相似问题