Padrão de autenticação Java Restful Web Services (jax rs)

9

Eu comecei a usar o JAX-RS para criar uma interface simples e tranquila para meu aplicativo da web. Atualmente, ele está sendo usado apenas (somente leitura) por um cliente interno que tem acesso a todos os dados do aplicativo, e estou usando a autenticação básica http para acesso. Gostaria de começar a usá-lo como parte da camada de visualização do meu aplicativo, e determinadas operações só serão permitidas se um usuário estiver conectado por meio do aplicativo da web. Eu estou lutando para encontrar um padrão que me permita usar as duas formas de autenticação de uma maneira elegante, sem repetir muito código. Aqui está mais ou menos o que eu sugeri:

Primeiro, uma classe util para carregar uma sessão de aplicativo, que é armazenada no banco de dados.

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;
    }
}

Este é o nosso recurso, com um método acessível apenas para um usuário autenticado ou nosso cliente de autenticação básica 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...
    }
}

Aqui está a visão mais básica do AppSession, para o propósito desta pergunta:

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;
        }
    }
}

Além disso, para serviços que não exigem nenhum tipo de autenticação, como impedir que terceiros não autorizados apenas apontem para o URL e coloquem os dados em seu próprio ritmo?

    
por Peter Anthony 26.07.2011 в 20:35
fonte

1 resposta

5

Você está chegando ao ponto em que vale a pena investigar o uso de programação orientada a aspectos para dividir o lado da segurança das coisas da sua lógica de negócios. Se você já estiver usando o Spring para montar as partes do seu aplicativo (o que eu recomendo para servidores complexos), então é só uma questão de adicionar o Spring AOP para injetar a lógica de segurança. Caso contrário, use o AspectJ diretamente. A lógica real para lidar com os vários modos de login provavelmente terá que ser personalizada, mas pelo menos você pode mantê-la em quarentena.

Se estiver usando o Spring, considere o uso do Spring Security; que se baseia no Spring AOP e fornece muito mais da solução.

    
por Donal Fellows 26.07.2011 / 21:39
fonte