Java 按方法和用户的Restlet授权

Java 按方法和用户的Restlet授权,java,authentication,authorization,restlet,Java,Authentication,Authorization,Restlet,我对Restlet和REST基本上是新手,希望为正在运行的服务器/数据库实现restfulapi。到目前为止,路由和寻址似乎工作正常,但我需要一些关于如何处理身份验证和授权的提示 情况:有些资源只有一些用户才能以某些方式与之交互。例如,User1可能可以获取资源,但不能放置任何内容,而User2可以同时执行这两项操作,User3甚至可能不读取资源,User4是唯一允许使用DELETE的 当然,MethodAuthorizer听起来很有前途,但它似乎只区分匿名用户和(所有)经过身份验证的用户。另一

我对Restlet和REST基本上是新手,希望为正在运行的服务器/数据库实现restfulapi。到目前为止,路由和寻址似乎工作正常,但我需要一些关于如何处理身份验证和授权的提示

情况:有些资源只有一些用户才能以某些方式与之交互。例如,User1可能可以获取资源,但不能放置任何内容,而User2可以同时执行这两项操作,User3甚至可能不读取资源,User4是唯一允许使用DELETE的

当然,MethodAuthorizer听起来很有前途,但它似乎只区分匿名用户和(所有)经过身份验证的用户。另一方面,RoleAuthorizer不会区分GET、PUT或其他请求方法,只会区分资源

我如何授权特定用户只执行特定任务?是否有方法组合授权人,或让他们执行多个测试?我必须写一个自定义授权人吗(我将如何做)


另外,是否可以在其他地方使用提供给身份验证器的凭据,例如通过将它们作为字符串传播到另一个方法?(如何)获取当前请求的标识符和机密?

事实上,我认为您应该利用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版本。