Java Restful Web 服务 (jax rs) 身份验证模式
我已经开始使用 JAX-RS 为我的 Web 应用程序创建一个简单的 Restful 界面。目前,它仅由一个有权访问所有应用程序数据的内部客户端使用(只读),并且我使用 http 基本身份验证进行访问。我想开始将它用作我的应用程序视图层的一部分,并且仅当用户通过网络应用程序登录时才允许某些操作。我正在努力寻找一种模式,使我能够以优雅的方式使用两种形式的身份验证,而无需重复大量代码。我大致想到的是:
首先是一个用于加载应用程序会话的 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;
}
}
这是我们的资源,其中有一种方法只能由经过身份验证的用户或我们的 http basic auth 客户端访问:
@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...
}
}
出于此问题的目的,这是 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;
}
}
}
此外,对于不需要任何类型的服务身份验证,如何防止未经授权的第三方仅指向 url,并随意抓取数据?
I have started using JAX-RS to created a simple restful interface to my web application. Currently, it is only being used (read only) by one internal client which has access to all application data, and I am using http basic authentication for access. I would like to start using it as part of the view layer of my app, and certain operations will only be allowed if a user is logged in via the web app. I am struggling to find a pattern that allows me to use both forms of authentication in an elegant way, without repeating a lot of code. Here is roughly what I have come up with:
First a util class for loading an application session, which is stored in the database.
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;
}
}
Here's our resource, with one method that is only accessible to an authenticated user, or our http basic auth client:
@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...
}
}
Here's the most basic view of the AppSession, for the purpose of this question:
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;
}
}
}
Furthermore, for services that do not require any sort of authentication, how do I prevent unauthorized third parties from just pointing at the url, and grabbing the data at their leisure?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您已经到了值得考虑使用面向方面的编程来将事物的安全性与业务逻辑分开的时候了。如果您已经使用 Spring 来组装应用程序的各个部分(我建议将其用于复杂的服务器),那么只需添加 Spring AOP 来注入安全逻辑即可。否则,直接使用AspectJ。处理多种登录模式的实际逻辑可能必须是自定义的,但至少您可以将其隔离。
如果使用 Spring,请考虑使用 Spring Security;它构建在 Spring AOP 之上,并为您提供更多的解决方案。
You're getting to the point when it is worth looking into using aspect-oriented programming to split the security side of things from your business logic. If you're already using Spring to assemble the pieces of your app (which I recommend for complex servers) then it's just a matter of adding in Spring AOP to inject the security logic. Otherwise, use AspectJ directly. The actual logic to handle the multiple login modes will probably have to be custom, but at least you can keep it quarantined.
If using Spring, consider using Spring Security; that builds on top of Spring AOP and supplies you with much more of the solution.