2017-08-14 4 views
0

スプリングセキュリティを使用して、特定のエンティティプロパティの更新をセキュリティで保護することは可能ですか?たとえば、私がユーザーエンティティを持っている場合、ROLE_USERによって更新可能なアクティブな列以外のすべてのユーザーのプロパティを変更または更新できるようにします。特定のエンティティ変数のスプリングセキュリティ

+0

はい、それは可能であるが、PreAuthorize' @と 'PostAuthorize' @'使用方法を見てみましょう。 – akuma8

+0

あなたは例を提供することができます – ArslanAnjum

+0

ここ:https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#method-security-expressions – akuma8

答えて

0

私はSpring Securityによって厳密には提供されていない解決策を見つけませんでした。

後、私のページングやソートのリポジトリである: - - を:しかし、私は、エンティティの変数にカスタム注釈@SecureUpdateを()を使用して、次のように望んでいたものを達成している

@Transactional("jpaTXManager") 
public interface ScreenRepo extends PagingAndSortingRepository<Screen, Integer>{ 

    @Override 
    @PreAuthorize("@patchSecurityService.canUpdate(#screen)") 
    Screen save(@Param("screen")Screen screen); 
} 

PatchSecurityService.java

@Service("patchSecurityService") 
public class PatchSecurityService { 

    public boolean canUpdate(Object obj){ 

     List<GrantedAuthority> authorities = 
       (List<GrantedAuthority>) SecurityContextHolder 
     .getContext() 
     .getAuthentication() 
     .getAuthorities(); 

     if (obj instanceof OEntity){ 
      OEntity oEntity = (OEntity) obj; 
      return oEntity.canUpdate(authorities); 
     }else{ 
      return true; 
     } 
    } 
} 

OEntity.java

@MappedSuperclass 
public class OEntity<T> { 

    @Transient 
    T originalObj; 

    @Transient 
    public T getOriginalObj(){ 
     return this.originalObj; 
    } 

    @PostLoad 
    public void onLoad(){ 
     ObjectMapper mapper = new ObjectMapper(); 
     try { 
      String serialized = mapper.writeValueAsString(this); 
      this.originalObj = (T) mapper.readValue(serialized, this.getClass()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public boolean canUpdate(List<GrantedAuthority> authorities){ 
     for (Field field : this.getClass().getDeclaredFields()){ 
      SecureUpdate secureUpdate = field.getAnnotation(SecureUpdate.class); 
      if (secureUpdate != null){ 
       try{ 
        field.setAccessible(true); 

        Object persistedField = field.get(this); 
        Object originalField = field.get(originalObj); 

        String[] allowedRoles = secureUpdate.value(); 
        if (!persistedField.equals(originalField)){ 
         boolean canUpdate = false; 
         for (String role : allowedRoles){ 
          for (GrantedAuthority authority : authorities){ 
           if (authority.getAuthority().equalsIgnoreCase(role)){ 
            return true; 
           } 
          } 
         } 
         return false; 
        } 
       }catch(Exception e){ 
        System.out.println(e.getMessage()); 
       } 
      } 
     } 

     return true; 
    } 
} 

@SecureUpdate

@Documented 
@Target(FIELD) 
@Retention(RUNTIME) 
public @interface SecureUpdate { 
    String[] value(); 
} 

、最終的にはエンティティクラス(Screen.class)

@Entity 
@Table(name="screen",schema="public") 
@JsonIgnoreProperties(ignoreUnknown=true) 
public class Screen extends OEntity<Screen>{ 

    Integer screenId; 
    String screenName; 

    @SecureUpdate({"ROLE_CLIENT"}) 
    String address; 

    ScreenType screenType; 

    @SecureUpdate({"ROLE_ADMIN"}) 
    ScreenSize screenSize; 

    BigDecimal latitude; 
    BigDecimal longitude; 
    Boolean active; 
    AppUser appUser; 

    .......Constructor, Getters and Setters... 
} 
関連する問題