Шаблон аутентификации Java Restful Web Services (jax rs) - PullRequest
9 голосов
/ 26 июля 2011

Я начал использовать JAX-RS для создания простого и удобного интерфейса для моего веб-приложения. В настоящее время он используется (только для чтения) одним внутренним клиентом, который имеет доступ ко всем данным приложения, и я использую для доступа базовую аутентификацию 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 и получать данные в свободное время?

1 Ответ

5 голосов
/ 26 июля 2011

Вы пришли к тому, что стоит использовать аспектно-ориентированное программирование, чтобы отделить аспекты безопасности от вашей бизнес-логики.Если вы уже используете Spring для сборки частей своего приложения (что я рекомендую для сложных серверов), то просто добавьте Spring AOP для внедрения логики безопасности.В противном случае используйте AspectJ напрямую.Фактическая логика для обработки нескольких режимов входа в систему, вероятно, должна быть индивидуальной, но, по крайней мере, вы можете сохранить ее в карантине.

При использовании Spring рассмотрите возможность использования Spring Security;которая основана на Spring AOP и предоставляет вам гораздо больше решений.

...