简体   繁体   中英

Spring Security Role - user can change only own data?

I start to use Spring Security. For now I seting that user must login if they wont create table. Or, for example, in the ControllerClass I configured to only user with role ROLE_USER can delete a table.

My question is, in which way I can set that, when user login and he create some table and create teamPlayers , that the table or players can only edit or delete user who did create the table and the players.

for example , I have in Controller method for delete table ...

@RestController
@RequestMapping(value="/api/tables")
public class ApiTableController {

@Autowired
TableService tableService;
@Autowired
TableConverter tableConverter;

@PreAuthorize("hasRole('ROLE_USER')")    
@RequestMapping(value="/{id}", method=RequestMethod.DELETE)
public ResponseEntity<TableDTO> deleteTable(@PathVariable Long id) {
    Table table = tableService.findOne(id);
    if (table != null) {
        TableDTO tableDTO = tableConverter.table2TableDTO(table);
        tableService.remove(id);
        return new ResponseEntity<>(tableDTO, HttpStatus.OK);
    } else {
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
}

In this case, all users with role ROLE_USER can delete all table , but I wont to can delete table only user how created table ... Is there any rule how it works or standard code? Like a profil on StackOwerflow . Everyone can see what we write ,Everyone can create profil and only I can edit my profil or my quastions which I wrote on the site. How I can do somthing like that with Spring security?

this is class User

@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue
@NotNull
@Column(name = "user_id")
private Long id;
@Column(name = "username")
private String name;
@Column(name = "password")
private String password;
@Column(name = "email")
private String email;
@Column(name = "country")
private String country;
@Column(name = "city")
private String city;
@Column(name = "dateCreated")
private Date dateCreated;
@Column(name = "enabled")
private boolean active;
@JoinTable(name = "user_security_role", joinColumns = { @JoinColumn(name = "user_id", 
referencedColumnName = "user_id") }, inverseJoinColumns = { 
@JoinColumn(name = "security_role_id", referencedColumnName = "id") })
@ManyToMany
private Set<SecurityRoleUser> securityRoleCollection;


@Override
public int hashCode() {

    int hash = 0;

    hash += (id != null ? id.hashCode() : 0);

    return hash;

}

@Override
public boolean equals(Object object) {

    if (!(object instanceof User)) {

        return false;

    }

    User other = (User) object;

    if ((this.id == null && other.id != null)
            || (this.id != null && !this.id.equals(other.id))) {

        return false;

    }

    return true;

}

And this is class Table ...

@Entity
@javax.persistence.Table(name="tblTable")
public class Table {
@Id
@GeneratedValue
@Column(name="table_id")
private Long id;
@Column(name="name", nullable=true)
private String name;
@Column(name="sport", nullable=true)
private String sport;
@Column(name="typeTable", nullable=true)
private String TypeTable;
@Column(name="dateCreated", nullable=true)
private Date dateCreated;
@Column(name="changed", nullable=true)
private Date changed;
@Column(name="description", nullable=true)
private String description;

I use hibernate, maven, RESTFull web server, backbone.js....

Not really an detailed answer but allready too long for a comment.

Spring security comes with a feature that is exactly what you need : Domain Object Security or ACLs

It's a rather advanced feature because if needs to add a set of tables to represents the authorizations of users on every secured domain object. One for the object classes, one for the objects themselves (only primary key is stored) and others for actual authorizations. In fact, it can be seen as the authorizations on a shared filesystem.

You normaly use then method security with @PreAuthorize annotation that allows to use an expression containing the actual parameters of the method. You directly allow a user to modify, or delete each and every domain object.

In addition to the Spring Security Reference Manual already cited above, you can find a complete tutorial on ACLs on krams::: Spring Security 3: Full ACL Tutorial .

My advice : try and experiment and ask questions here if you get stuck on some specific problems.

You can use @PreRemove/ @PreUpdate / @PrePersist in your entity and implements you own logic.

  @PreRemove
    private void preventUnAuthorizedRemove() {

       String name = SecurityContextHolder.getContext().getAuthentication().getName();

      if(!name.equals(this.username)){
          throw new NotAuthorizedException("User can only delete himself ");
      }

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM