2011-07-26 11 views
9

Zacząłem używać JAX-RS do stworzenia prostego interfejsu do mojej aplikacji internetowej. Obecnie jest on używany (tylko do odczytu) przez jednego klienta wewnętrznego, który ma dostęp do wszystkich danych aplikacji i używam uwierzytelniania podstawowego HTTP do uzyskiwania dostępu. Chciałbym zacząć używać go jako część warstwy widoku mojej aplikacji, a niektóre operacje będą dozwolone tylko wtedy, gdy użytkownik zaloguje się za pomocą aplikacji internetowej. Staram się znaleźć wzór, który pozwala mi używać obu form uwierzytelniania w elegancki sposób, bez powtarzania wielu kodów. Oto mniej więcej to, co wymyśliłem:Java Resting Web Services (jax rs) wzorzec uwierzytelniania

Pierwsza klasa użytkowa do ładowania sesji aplikacji, która jest przechowywana w bazie danych.

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

Oto nasz zasób, z jednej metody, która jest dostępna tylko dla użytkownika uwierzytelnionego lub nasza http podstawowy klienta 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... 
    } 
} 

Oto najbardziej podstawowym widoku AppSession, dla celów to pytanie:

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

Ponadto, w przypadku usług, które nie wymagają jakichkolwiek uwierzytelniania, w jaki sposób mogę zapobiec nieupoważnionym osobom trzecim tylko wskazując na URL, a g rabunku danych w ich wolnym czasie?

Odpowiedz

5

Dochodzisz do punktu, w którym warto przyjrzeć się programowaniu zorientowanemu na aspekty, aby podzielić bezpieczeństwo od logiki biznesowej. Jeśli już używasz Springa do montażu elementów aplikacji (co polecam dla złożonych serwerów), to tylko kwestia dodania Spring AOP do wstrzyknięcia logiki bezpieczeństwa. W przeciwnym razie użyj AspectJ bezpośrednio. Faktyczna logika do obsługi wielu trybów logowania będzie prawdopodobnie musiała być niestandardowa, ale przynajmniej możesz zachować ją w kwarantannie.

Jeśli używasz Spring, rozważ użycie Spring Security; który opiera się na Spring AOP i dostarcza Ci znacznie więcej rozwiązania.

+0

gdybyśmy tylko mieli wiosnę. na plus, zawsze chciałem pretekst, aby zajrzeć do aspektj. –