Pet*_*ony 9 java design-patterns restful-authentication jax-rs
我已经开始使用JAX-RS为我的Web应用程序创建一个简单的restful接口.目前,它只被一个内部客户端使用(只读),该客户端可以访问所有应用程序数据,我使用http基本身份验证进行访问.我想开始使用它作为我的应用程序的视图层的一部分,并且只有当用户通过Web应用程序登录时才允许某些操作.我正在努力寻找一种模式,允许我以优雅的方式使用两种形式的身份验证,而无需重复大量代码.这大致是我提出的:
首先是一个用于加载应用程序会话的util类,它存储在数据库中.
public class RestUtil {
public static AppSession getAuthenticatedSession(HttpServletRequest request) {
AppSession session;
String remoteUser = request.getRemoteUser();
if (remoteUser != null) {
session = SessionRepository.loadSessionByRemoteUser(remoteUser);
} else {
session = SessionRepository.loadSessionById(request.getSession().getId());
}
return session;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我们的资源,只有一个方法只能由经过身份验证的用户访问,或者我们的http基本身份验证客户端:
@Path("/protected/resource")
public class ProtectedResource {
@GET
@Produces(MediaType.TEXT_JSON)
@Path("{userId}")
public String getProtectedResourceJson(@Context HttpServletRequest request, @PathParam("userId") Integer userId) {
// Return Charity List XML
AppSession session = RestUtil.getAuthenticatedSession(request);
if (session.canAccessUser(userId)) //get Json...
}
}
Run Code Online (Sandbox Code Playgroud)
对于这个问题,这是AppSession的最基本视图:
public class AppSession {
User authenticatedUser;
String remoteUser;
public boolean canAccessUser(Integer userId) {
if (remoteUser != null) {
//this client has access to all users
return true;
} else if (authenticatedUser.getId().equals(userId)) {
//this is local client, calling the service from a view
//only has access to authenticatedUser
return true;
} else {
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
此外,对于不需要任何身份验证的服务,如何防止未经授权的第三方指向网址,并在闲暇时抓取数据?
当你值得研究使用面向方面的编程来从业务逻辑中分离安全方面时,你就会发现这一点.如果您已经使用Spring来组装应用程序的部分(我推荐用于复杂的服务器),那么只需添加Spring AOP来注入安全逻辑.否则,直接使用AspectJ.处理多种登录模式的实际逻辑可能必须是自定义的,但至少可以保持隔离状态.
如果使用Spring,请考虑使用Spring Security; 它构建于Spring AOP之上,为您提供更多解决方案.