WEB/Security

Lesson 29 - Using permissions

Tony Lim 2022. 5. 20. 14:28
728x90

permission can provide complex authorization rules

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ProjectConfig extends GlobalMethodSecurityConfiguration {

  @Bean
  public UserDetailsService uds () {
    var uds = new InMemoryUserDetailsManager();

    var u1 =
        User.withUsername("john")
            .password("12345")
            .authorities("read")
        .build();

    var u2 =
        User.withUsername("bill")
            .password("12345")
            .authorities("write")
            .build();

    uds.createUser(u1);
    uds.createUser(u2);

    return uds;
  }

  @Bean
  public PasswordEncoder passwordEncoder() {
    return NoOpPasswordEncoder.getInstance();
  }

  @Override
  protected MethodSecurityExpressionHandler createExpressionHandler() {
    var meh = new DefaultMethodSecurityExpressionHandler();
    meh.setPermissionEvaluator(permissionEvaluator());
    return meh;
  }

  private PermissionEvaluator permissionEvaluator() {
    return new DocumentPermissionEvaluator();
  }
}
public class DocumentPermissionEvaluator implements PermissionEvaluator {

  @Override
  public boolean hasPermission(Authentication authentication,
                               Object targetObject,
                               Object permission) {
    List<Document> returnedList = (List<Document>) targetObject;
    String username = authentication.getName();
    String auth = (String) permission;

    boolean docsBelongToTheAuthUser =returnedList.stream()
        .allMatch(d -> d.getUser().equals(username));

    boolean hasProperAuthority = authentication.getAuthorities().stream()
        .anyMatch(g -> g.getAuthority().equals(auth));

    return docsBelongToTheAuthUser && hasProperAuthority;
  }

  @Override
  public boolean hasPermission(Authentication authentication,
                               Serializable targetID,
                               String type,
                               Object permission) {
    return false;
  }
}
@Service
public class DocumentService {

  @PostAuthorize("hasPermission(returnObject, 'read')")
  public List<Document> findDocuments(String username) {
    var doc = new Document();
    doc.setUser("john");
    doc.setText("TEXT");
    return List.of(doc);
  }
}

if 2 parameter given -> user first overloaded hasPermission method

3 parameter given -> second hasPermission method

 

 

728x90