Java 按方法和用户的Restlet授权
我对Restlet和REST基本上是新手,希望为正在运行的服务器/数据库实现restfulapi。到目前为止,路由和寻址似乎工作正常,但我需要一些关于如何处理身份验证和授权的提示 情况:有些资源只有一些用户才能以某些方式与之交互。例如,User1可能可以获取资源,但不能放置任何内容,而User2可以同时执行这两项操作,User3甚至可能不读取资源,User4是唯一允许使用DELETE的 当然,MethodAuthorizer听起来很有前途,但它似乎只区分匿名用户和(所有)经过身份验证的用户。另一方面,RoleAuthorizer不会区分GET、PUT或其他请求方法,只会区分资源 我如何授权特定用户只执行特定任务?是否有方法组合授权人,或让他们执行多个测试?我必须写一个自定义授权人吗(我将如何做)Java 按方法和用户的Restlet授权,java,authentication,authorization,restlet,Java,Authentication,Authorization,Restlet,我对Restlet和REST基本上是新手,希望为正在运行的服务器/数据库实现restfulapi。到目前为止,路由和寻址似乎工作正常,但我需要一些关于如何处理身份验证和授权的提示 情况:有些资源只有一些用户才能以某些方式与之交互。例如,User1可能可以获取资源,但不能放置任何内容,而User2可以同时执行这两项操作,User3甚至可能不读取资源,User4是唯一允许使用DELETE的 当然,MethodAuthorizer听起来很有前途,但它似乎只区分匿名用户和(所有)经过身份验证的用户。另一
另外,是否可以在其他地方使用提供给身份验证器的凭据,例如通过将它们作为字符串传播到另一个方法?(如何)获取当前请求的标识符和机密?事实上,我认为您应该利用Restlet的角色支持。事实上,Restlet提供了两个关于安全性的附加元素:
,根据请求中提供的凭据对用户进行实际身份验证验证器
,加载已验证用户的角色Enroler
@Override
public Restlet createInboundRoot() {
Router router = (...)
Verifier verify = new MyVerifier(...);
Enroler enroler = new MyEnroler(...);
ChallengeAuthenticator guard = new ChallengeAuthenticator(getContext(),
ChallengeScheme.HTTP_BASIC, "connector");
guard.setVerifier(verifier);
guard.serEnrole(enroler);
guard.setNext(router);
return guard;
}
验证器的实现如下所示:
public class MyVerifier extends SecretVerifier {
public int verify(String identifier, char[] secret)
throws IllegalArgumentException {
ApplicationUser user = loadUser(identifier);
//user contains both user hints and roles
if (user!=null
&& compare(user.getPassword().toCharArray(), secret)) {
Request request = Request.getCurrent();
request.getClientInfo().setUser(user);
return SecretVerifier.RESULT_VALID;
} else {
return SecretVerifier.RESULT_INVALID;
}
}
}
public class MyEnroler implements Enroler {
public void enrole(ClientInfo clientInfo) {
Request request = Request.getCurrent();
User user = request.getClientInfo().getUser();
if (user!=null) {
List<UserRole> roles = user.getRoles();
if (roles!=null) {
for (UserRole userRole : roles) {
// example of role creation
Role role = new Role(userRole.getName(), "");
clientInfo.getRoles().add(role);
}
}
}
}
}
Router router = (...)
Authorizer authorizer = new MyAuthorizer();
authorizer.setNext(router);
Verifier verify = new MyVerifier(...);
Enroler enroler = new MyEnroler(...);
ChallengeAuthenticator guard = new ChallengeAuthenticator(getContext(),
ChallengeScheme.HTTP_BASIC, "connector");
guard.setVerifier(verifier);
guard.serEnrole(enroler);
guard.setNext(authorizer);
return guard;
}
Enroler
的实现如下所示:
public class MyVerifier extends SecretVerifier {
public int verify(String identifier, char[] secret)
throws IllegalArgumentException {
ApplicationUser user = loadUser(identifier);
//user contains both user hints and roles
if (user!=null
&& compare(user.getPassword().toCharArray(), secret)) {
Request request = Request.getCurrent();
request.getClientInfo().setUser(user);
return SecretVerifier.RESULT_VALID;
} else {
return SecretVerifier.RESULT_INVALID;
}
}
}
public class MyEnroler implements Enroler {
public void enrole(ClientInfo clientInfo) {
Request request = Request.getCurrent();
User user = request.getClientInfo().getUser();
if (user!=null) {
List<UserRole> roles = user.getRoles();
if (roles!=null) {
for (UserRole userRole : roles) {
// example of role creation
Role role = new Role(userRole.getName(), "");
clientInfo.getRoles().add(role);
}
}
}
}
}
Router router = (...)
Authorizer authorizer = new MyAuthorizer();
authorizer.setNext(router);
Verifier verify = new MyVerifier(...);
Enroler enroler = new MyEnroler(...);
ChallengeAuthenticator guard = new ChallengeAuthenticator(getContext(),
ChallengeScheme.HTTP_BASIC, "connector");
guard.setVerifier(verifier);
guard.serEnrole(enroler);
guard.setNext(authorizer);
return guard;
}
这个授权人的实现可以是这样的:
public class MyAuthorizer extends Authorizer {
private String[] getRoles = new String[] { "read"};
private String[] putRoles = new String[] { "update"};
private String[] deleteRoles = new String[] { "delete"};
private boolean hasRoles(String[] expectedRoles) {
List<Role> roles = request.getClientInfo().getRoles();
for (String expectedRole : expectedRoles) {
for (Role role : roles) {
if (role.getName().equals(expectedRole)) {
return true;
}
}
}
return false;
}
private void checkRoles(String[] roles) {
if (!hasRole(roles)) {
throw new ResourceException(
Status.CLIENT_ERROR_FORBIDDEN);
}
}
public boolean authorize(Request request, Response response) {
if (!request.getClientInfo().isAuthenticated()) {
throw new ResourceException(
Status.CLIENT_ERROR_FORBIDDEN);
}
if ("GET".equals(request.getMethod().getName())) {
checkRoles(getRoles);
} else if ("PUT".equals(request.getMethod().getName())) {
checkRoles(putRoles);
} else if ("DELETE".equals(request.getMethod().getName())) {
checkRoles(deleteRoles);
}
return false;
}
}
公共类MyAuthorizer扩展了Authorizer{
私有字符串[]getRoles=新字符串[]{“读取”};
私有字符串[]putRoles=新字符串[]{“更新”};
私有字符串[]删除角色=新字符串[]{“删除”};
私有布尔hasRoles(字符串[]expectedRoles){
列表角色=request.getClientInfo().getRoles();
for(字符串expectedRole:expectedRoles){
for(角色:角色){
if(role.getName().equals(expectedRole)){
返回true;
}
}
}
返回false;
}
私有void checkRoles(字符串[]角色){
如果(!hasRole(角色)){
抛出新的ResourceException(
状态。客户端错误(禁止);
}
}
公共布尔授权(请求、响应、响应){
如果(!request.getClientInfo().isAuthenticated()){
抛出新的ResourceException(
状态。客户端错误(禁止);
}
if(“GET”.equals(request.getMethod().getName())){
checkRoles(getRoles);
}else if(“PUT”.equals(request.getMethod().getName())){
检查角色(putRoles);
}else if(“DELETE”.equals(request.getMethod().getName())){
检查角色(删除角色);
}
返回false;
}
}
希望它能帮助你,
蒂埃里非常感谢,蒂埃里!这让我得到了一个注册者/授权者组合,只允许具有特定角色的用户执行各自的请求。有些事情并没有完全按照写的那样进行。例如,“GET”.equals(request.getMethod())
等为其方法返回false,除非我将其转换为字符串(),或者“request.getAttributes().put”(“currentUser”);必须将´更改为´User=(User)clientInfo.getUser();´. 代码是一个很大的帮助,虽然,这并不难从那里去。也许我只是有一个不同的Restlet版本。