6

Benim API'mdaki ana veri bilgileri ve bilgileri bir projeyle (Varlık) ilişkilendirilir, Şifre akışı için iyi yaklaşım nedir: Bir projeyle bağlantılı belirli bir izni yönetmek için bahar güvenliği ve OAuth2?Oauth2/Parola akış/belirli bir varlık için kontrol iznine

  • UAA microservice: Bu uygulamada

    Eğer 5 mikro hizmetini sahip yetkilendirme sunucusu
  • Katalog microservice
  • Sipariş microservice
  • Fatura microservice
  • Müşteri microservice

Yakınlaştırma izni:

UUAMICROSERVICE

Her kullanıcı birçok projeyi olabilir ve her proje için izin olabilir:

  • CAN_MANAGE_CATALOG
  • CAN_VIEW_CATALOG
  • CAN_MANAGE_ORDER
  • CAN_VIEW_ORDER
  • CAN_MANAGE_INVOICE
  • CAN_VIEW_INVOICE
  • ...

Birçok fikrim yok ama ben iyi bir yaklaşım olmasa eminim:

KULLANIMI DURUM: Ben son nokta SECURISE istiyorum:

http://catalog-service/{project_key}/catalogs 
projesi {project_key} için izin VIEW_CATALOG VEYA MANAGE_CATALOG var

Sadece KULLANICI can Projenin

tüm katalog mevcut listelemek Benim ilk fikir: KULLANIM ProjectAccessExpression ön provizyon

CatalogController.java

@Controller 
public class CatalogController { 
    @PreAuthorize("@projectAccessExpression.hasPermission(#projectKey, 'manageCatalog', principal)" + 
     " or @projectAccessExpression.hasPermission(#projectKey, 'viewCatalog', principal)") 
    @RequestMapping(
      value = "/{projectKey}/catalogs", 
      method = RequestMethod.GET, 
      produces = MediaType.APPLICATION_JSON_VALUE 
    ) 
    public @ResponseBody List<Catalog> findByProject(@PathVariable("projectKey") String projectKey) { 
     return catalogService.find(); 
    } 
} 

ProjectAccessExpression ile.java

@Component 
public class ProjectAccessExpression { 

     private RestTemplate restTemplate; 
     public boolean havePermission(String projectKey, String permission , String username) { 
      Boolean havePermission = restTemplate.getForObject(String.format("http://uaa-service/permission/check?project=%1&permission=%2&username=%3", 
        projectKey, permission, username 
        ), Boolean.class); 
      return havePermission; 
     } 
} 

sakıncalı: Her zaman

İkinci bir fikir için UAA telefon etmek zorunda olduğunu: USER_ROLE

  • kullanıcı adı ile KULLANIM USER_ROLE

    | role

  • mylogin1 | SHOP1 .CAN_MANAGE_CATALOG
  • mylogin1 | SHOP1 .CAN_VIEW_CATALOG
  • mylogin1 | SHOP2 .CAN_MANAGE_CATALOG
  • mylogin1 | SHOP2 .CAN_VIEW_CATALOG
  • mylogin1 | SHOP2 .CAN_MANAGE_ORDER
  • mylogin1 | .CAN_VIEW_ORDER SHOP2
  • ...

SHOP1SHOP2 sakıncalı projectKey

olduğu i emin değilim ancak kullanıcı değişikliği izni varsa, ben bütün belirteç ortağa iptal gerekir

Üçüncü fikir: kimlik doğrulama bloğundaki belirli izni ekle

ben depolamak için nasıl bilmiyorum ...

Ve denetleyici bir açıklama

:

@PreAuthorize("@ProjectAccessExpression.hasPermission(authentication, 'manageCatalog||viewCatalog', #projectKey) 

sakıncalı: İkinci fikri aynı sakıncalı

cevap

0

i kullanmak Bu çözelti (Açıkçası kendi kullanım alanına ayarları yapılandırmak gerekir) ve çalışma ince

** 1 - kullanıcı işareti **

Bu örnek veritabanında inat rolü ile kullanıcı bulmak ve tüm rol bağlı projeyi eklerken İş Mantığı Security yükleyin. Ameliyattan sonra ben GrantedAuthority doğrulama işaretini vardır: ROLE_USER, ROLE_MANAGE_CATALOG: project1, ROLE_VIEW_PROFILE: project1, ROLE_MANAGE_PROJECT: Project2, ...

@Service 
public class CustomUserDetailsService implements UserDetailsService { 
@Override 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
     Optional<User> user = userService.findByLogin(username); 

     if (!user.isPresent()) { 
      Object args[] = {username}; 
      throw new UsernameNotFoundException(
      messageSource.getMessage("user.notexist", args, "User {0} doesn't not exist", LocaleContextHolder.getLocale()) 
      ); 
     } 
     if (!user.get().isActivated()) { 
      //throw new UserNotActivatedException(String.format("User %s was not activated!", username)); 
      Object args[] = {username}; 
      throw new UserNotActivatedException(
        messageSource.getMessage("user.notactivated", args, "User {0} was not activated", LocaleContextHolder.getLocale())); 
     } 
     //Here implement your proper logic 
     //Add busness logic security Roles 
     // eg ROLE_MANAGE_PROJECT:{project_key}, ROLE_MANAGE_CATALOG:{project_key} 
     List<Role> bRoles = projectService.getRolesForUser(username) 
     user.get().getRoles().addAll(
      bRoles 
      ); 

     UserRepositoryUserDetails userDetails = new UserRepositoryUserDetails(user.get()); 
     return userDetails; 
    } 
} 

** 2 çek ön provizyon ifadesiyle güvenlik **

yılında

  1. ROLE_ADMIN VEYA
  2. ROLE_MANAGE_PROJECT: {proj bu izne sahip sadece kullanıcı bu örnek bu işlemi yapabilirsiniz ectKey}

    @PreAuthorize ("@ oauthUserAccess.hasPermission (kimlik doğrulama, ' "+ Constants.PP_MANAGE_PROJECT +"', #projectKey)") @ RequestMapping ( değeri = "/ projeler/{projectKey}", yöntem = RequestMethod.PUT, = üretir MediaType.APPLICATION_JSON_VALUE ) kamu ResponseEntity updateProject (@PathVariable ("projectKey") dize projectKey, @ geçerlidir @RequestBody Projesi projesi)

OauthUserAccess sınıfı:

@Component("oauthUserAccess") 
public class OauthUserAccess { 

    /** 
    * Check if it is the administrator of the application IMASTER 
    * @param authentication 
    * @param projectKey 
    * @return 
    */ 
    public boolean hasAdminPermission(OAuth2Authentication authentication, String projectKey) { 
     if(authentication.getOAuth2Request().getAuthorities().contains("ROLE_ADMIN")) return true; 
     return false; 
    } 
    /** 
    * 
    * @param authentication 
    * @param permissionType 
    * @param projectKey 
    * @return 
    */ 
    public boolean hasPermission(OAuth2Authentication authentication, String permissionType, String projectKey) { 
     if (!ProjectPermissionType.exist(permissionType) || 
       projectKey.isEmpty() || 
       !projectKey.matches(Constants.PROJECT_REGEX)) 
      return false; 
     if (authentication.isClientOnly()) { 
      //TODO check scope permission 
      if(authentication.getOAuth2Request().getScope().contains(permissionType+":"+projectKey)) return true; 
     } 
     if (hasAdminPermission(authentication, projectKey)) return true; 
     String projectPermission = "ROLE_" + permissionType + ":" + projectKey; 
     String projectPermissionManage = "ROLE_" + permissionType.replace("VIEW", "MANAGE") + ":" + projectKey; 
     String manageProject = "ROLE_" + Constants.PP_MANAGE_PROJECT + ":" + projectKey; 
     Predicate<GrantedAuthority> p = r -> r.getAuthority().equals(projectPermission) || r.getAuthority().equals(projectPermissionManage) || r.getAuthority().equals(manageProject); 

     if (authentication.getAuthorities().stream().anyMatch(p)) { 
      return true; 
     }; 
     return false; 
    } 

} 

3 - Avantaj/dezavantaj

Avantaj

iş mantığı izni o microservice mimarisi için güçlü bir çözümdür yalnızca kullanıcı uygulamasına giriş değil, her zaman bu kadar yüklenir.

Dezavantaj

İhtiyaç belirteç kimlik güncelleme veya belirteci kaldırmayı zaman başka izni değişiklik kullanıcı için izin, çıkış ve giriş için gerekli kullanıcı güncellemek.Ancak, bu güvenlik mantığı olmadan aynı sorun var, örneğin, kullanıcı devre dışı bırakıldığında veya etkinleştirildiğinde.

i bir denetleyici örneğin kullanmak

Çözümümün:

newAuthorities = projectService.getRolesForUser(username); 
UsernamePasswordAuthenticationToken newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), newAuthorities); 
     OAuth2Authentication authentication = (OAuth2Authentication)SecurityContextHolder.getContext().getAuthentication(); 
     Collection<OAuth2AccessToken> accessTokens = tokenStore.findTokensByUserName(principal.getName()); 
     OAuth2Authentication auth2 = new OAuth2Authentication(authentication.getOAuth2Request(), newAuth); 

     accessTokens.forEach(token -> { 
      if (!token.isExpired()) { 
       tokenStore.storeAccessToken(token, auth2); 
      } 
     }); 
0

Temelde benziyor senin Sadece projeniz için OAuth 2.0 ile rolleri kullanmaya çalışıyorum. İşte OAuth bazı bahar belgelerin bir alıntı Kapsamları için 2.0

Haritalama Kullanıcı Rolleri geçerli:http://projects.spring.io/spring-security-oauth/docs/oauth2.html

O müşteriye atanan kapsamları ile sadece jeton kapsamını sınırlamak için bazen yararlı olur, ama aynı zamanda kullanıcının kendi izinlerine göre. AuthorizationEndpoint DefaultOAuth2RequestFactory'u kullanırsanız, izin verilen kapsamları yalnızca kullanıcının rolleriyle eşleşenlerle sınırlamak için checkUserScopes = true işaretini ayarlayabilirsiniz. Ayrıca TokenEndpoint içine OAuth2RequestFactory enjekte edebilir ama bu sadece çalışır (yani şifre hibe ile birlikte) bir de TokenEndpointAuthenticationFilter yüklerseniz - sadece HTTP BasicAuthenticationFilter bundan sonra filtre eklemek gerekir.Elbette, kapsamları rollere eşlemek için kendi kurallarınızı uygulayabilir ve OAuth2RequestFactory'un kendi sürümünü yükleyebilirsiniz. AuthorizationServerEndpointsConfigurer bunu size @EnableAuthorizationServer kullanırsanız bir fabrika kurmak için bu özelliği kullanabilirsiniz özel OAuth2RequestFactory enjekte sağlar.

Tüm bunlar temel olarak aşağı doğru uzanır, çünkü kapsamları kendi özel rollerinizle eşleştirerek uç noktalarınızı farklı kapsamlarla koruyabilirsiniz. Bu, güvenliğinizle gerçekten iyi bir şekilde tanışmanızı sağlayacaktır.

Sana bir referans olarak kullanabilir oldukça iyi bir yürüyüş yoluyla bulundu:

https://raymondhlee.wordpress.com/2014/12/21/implementing-oauth2-with-spring-security/

+0

Merhaba Matta, her şeyden önce Cevabınız için teşekkür ama bağlantı veya bölüm yaklaşımını bilmek nasıl yardımcı olabileceğini biliyor ya bu gidermezse "Kullanıcı Rollerini Kapsamlara Eşleme" sorusu https://raymondhlee.wordpress.com/2014/12/21/implementing-oauth2-with-spring-security/. Sen kullanma vaktin var mı? – timactive

+0

Burada gerçek hile, uygulamanızın farklı alanları üzerinde ince taneli güvenlik istersiniz. Böylece, her uygulama alanı için özel kapsamlar ayarlayabilir ve ardından farklı kullanıcı rollerini farklı kapsamlara eşleyebilirsiniz. Bu, temel olarak sonsuz seviyedeki kombinasyonları kurabildiğiniz ve bunları farklı uygulama alanlarına uygulayabileceğiniz için çok ince taneli kontrol sağlayacaktır. "kapsamları rollere eşleme için kendi kurallarınızı uygulayın" –

+0

Ok Matthew, sadece temel bir şema olduğunu düşünüyorum ve bu örnek, problemli olarak belirli bir yetkilendirmeyi dinamik olarak nasıl tanımlayacağımı göstermiyor. Örnek ROLE_MANAGEPRODUCT_ {PROJECTKEY}, proje anahtarı kullanıcı tarafından sonra oluşturulur. – timactive

İlgili konular