Permission based access control in spring
im trying to secure my endpoints with role based access control. I have implemented the whole structure as well as CustomUserDetailService, however im not sure how should i enforce these rules on enpoints, i was looking for some nice annotation based evaluation like @PreAuthorize(hasRole('role'))
. My structure looks follwoing:
Permission:
@Entity
public class Permission implements GrantedAuthority {
@Id
private Long id;
@Column(name = "NAME")
private String name;
@ManyToMany(mappedBy = "permissions", fetch = FetchType.LAZY)
private Collection<Role> roles;
@Override
public String getAuthority() {
return name;
}
Role:
@Entity
public class Role implements GrantedAuthority {
@Id @Column(name="ID" )
private Long id;
@Column(name="NAME", nullable=false , unique=false)
private String name;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "role_x_permission",
joinColumns = @JoinColumn(
name = "role_id"),
inverseJoinColumns = @JoinColumn(
name = "permission_id"))
private List<Permission> permissions;
@Override
public String getAuthority() {
return name;
}
User:
@Entity(name = "User")
@Table(name = "USERS")
@Data
public class User {
@Id
private Long id;
@Column(name="LOGIN" , nullable=true , unique=false)
private String login;
@Column(name="PASSWORD" , nullable=false , unique=false)
private String password;
@ManyToMany( fetch = FetchType.LAZY)
@JoinTable(name = "USER_ROLES",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
Now i have defined my CustomUserDetailsService:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User applicationUser = userRepository.findByUsername(username);
if (applicationUser.getId() == null) {
throw new UsernameNotFoundException(username);
}
return new org.springframework.security.core.userdetails.User(applicationUser.getLogin(), applicationUser.getPassword(),
getAuthorities(applicationUser.getRoles()));
}
@Transactional
public Collection<? extends GrantedAuthority> getUserAuthorities(String username) {
User user = userRepository.findByUsername(username);
return getAuthorities(user.getRoles());
}
private Collection<? extends GrantedAuthority> getAuthorities(
Collection<Role> roles) {
return getGrantedAuthorities(getPermissions(roles));
}
private List<String> getPermissions(Collection<Role> roles) {
List<String> permissions = new ArrayList<>();
List<Permission> collection = new ArrayList<>();
for (Role role : roles) {
collection.addAll(role.getPermissions());
}
for (Permission item : collection) {
permissions.add(item.getName());
}
return permissions;
}
private List<GrantedAuthority> getGrantedAuthorities(List<String> permissions) {
List<GrantedAuthority> authorities = new ArrayList<>();
for (String permission : permissions) {
authorities.add(new SimpleGrantedAuthority(permission));
}
return authorities;
}
}
Then i'm trying to annotate my endpoint with @PreAuthorize
@PostMapping("/doSomething")
@PreAuthorize("hasRole('doSomething')")
public SomeEntity createComment(@RequestBody SomeEntity something) {
...
}
I have user with role of USER
, this role doesn't have permission to doSomething
, however it seems like @PreAuthorize("hasRole('doSomething')")
is not working. I'm not sure what i have done wrong, coule you please point my mistake?
Also, since im using RBAC
this hasRole
is very missleading since access is permission based, not role based.
What would be correct way to authorize access to endpoint with RBAC
approach?
java spring spring-security rbac
add a comment |
im trying to secure my endpoints with role based access control. I have implemented the whole structure as well as CustomUserDetailService, however im not sure how should i enforce these rules on enpoints, i was looking for some nice annotation based evaluation like @PreAuthorize(hasRole('role'))
. My structure looks follwoing:
Permission:
@Entity
public class Permission implements GrantedAuthority {
@Id
private Long id;
@Column(name = "NAME")
private String name;
@ManyToMany(mappedBy = "permissions", fetch = FetchType.LAZY)
private Collection<Role> roles;
@Override
public String getAuthority() {
return name;
}
Role:
@Entity
public class Role implements GrantedAuthority {
@Id @Column(name="ID" )
private Long id;
@Column(name="NAME", nullable=false , unique=false)
private String name;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "role_x_permission",
joinColumns = @JoinColumn(
name = "role_id"),
inverseJoinColumns = @JoinColumn(
name = "permission_id"))
private List<Permission> permissions;
@Override
public String getAuthority() {
return name;
}
User:
@Entity(name = "User")
@Table(name = "USERS")
@Data
public class User {
@Id
private Long id;
@Column(name="LOGIN" , nullable=true , unique=false)
private String login;
@Column(name="PASSWORD" , nullable=false , unique=false)
private String password;
@ManyToMany( fetch = FetchType.LAZY)
@JoinTable(name = "USER_ROLES",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
Now i have defined my CustomUserDetailsService:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User applicationUser = userRepository.findByUsername(username);
if (applicationUser.getId() == null) {
throw new UsernameNotFoundException(username);
}
return new org.springframework.security.core.userdetails.User(applicationUser.getLogin(), applicationUser.getPassword(),
getAuthorities(applicationUser.getRoles()));
}
@Transactional
public Collection<? extends GrantedAuthority> getUserAuthorities(String username) {
User user = userRepository.findByUsername(username);
return getAuthorities(user.getRoles());
}
private Collection<? extends GrantedAuthority> getAuthorities(
Collection<Role> roles) {
return getGrantedAuthorities(getPermissions(roles));
}
private List<String> getPermissions(Collection<Role> roles) {
List<String> permissions = new ArrayList<>();
List<Permission> collection = new ArrayList<>();
for (Role role : roles) {
collection.addAll(role.getPermissions());
}
for (Permission item : collection) {
permissions.add(item.getName());
}
return permissions;
}
private List<GrantedAuthority> getGrantedAuthorities(List<String> permissions) {
List<GrantedAuthority> authorities = new ArrayList<>();
for (String permission : permissions) {
authorities.add(new SimpleGrantedAuthority(permission));
}
return authorities;
}
}
Then i'm trying to annotate my endpoint with @PreAuthorize
@PostMapping("/doSomething")
@PreAuthorize("hasRole('doSomething')")
public SomeEntity createComment(@RequestBody SomeEntity something) {
...
}
I have user with role of USER
, this role doesn't have permission to doSomething
, however it seems like @PreAuthorize("hasRole('doSomething')")
is not working. I'm not sure what i have done wrong, coule you please point my mistake?
Also, since im using RBAC
this hasRole
is very missleading since access is permission based, not role based.
What would be correct way to authorize access to endpoint with RBAC
approach?
java spring spring-security rbac
Also, since im using RBAC this hasRole is very missleading since access is permission based, not role based. That is confusing, because RBAC means Role Based Access Control andhasRole
is the right way to implement it. However, you also not using permissions, because permissions (Spring wording) is part of ACL.
– dur
Nov 22 '18 at 12:30
@dur lets assume that for now that Permission is only for RBAC in my case. If i understood RBAC properly, each enpoint can have a permission, and the a role has set of permissions. Then hasRole needs to refer to permission correct?
– Akka Jaworek
Nov 22 '18 at 13:00
Possible duplicate of stackoverflow.com/questions/44004977/…
– dur
Nov 22 '18 at 20:49
add a comment |
im trying to secure my endpoints with role based access control. I have implemented the whole structure as well as CustomUserDetailService, however im not sure how should i enforce these rules on enpoints, i was looking for some nice annotation based evaluation like @PreAuthorize(hasRole('role'))
. My structure looks follwoing:
Permission:
@Entity
public class Permission implements GrantedAuthority {
@Id
private Long id;
@Column(name = "NAME")
private String name;
@ManyToMany(mappedBy = "permissions", fetch = FetchType.LAZY)
private Collection<Role> roles;
@Override
public String getAuthority() {
return name;
}
Role:
@Entity
public class Role implements GrantedAuthority {
@Id @Column(name="ID" )
private Long id;
@Column(name="NAME", nullable=false , unique=false)
private String name;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "role_x_permission",
joinColumns = @JoinColumn(
name = "role_id"),
inverseJoinColumns = @JoinColumn(
name = "permission_id"))
private List<Permission> permissions;
@Override
public String getAuthority() {
return name;
}
User:
@Entity(name = "User")
@Table(name = "USERS")
@Data
public class User {
@Id
private Long id;
@Column(name="LOGIN" , nullable=true , unique=false)
private String login;
@Column(name="PASSWORD" , nullable=false , unique=false)
private String password;
@ManyToMany( fetch = FetchType.LAZY)
@JoinTable(name = "USER_ROLES",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
Now i have defined my CustomUserDetailsService:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User applicationUser = userRepository.findByUsername(username);
if (applicationUser.getId() == null) {
throw new UsernameNotFoundException(username);
}
return new org.springframework.security.core.userdetails.User(applicationUser.getLogin(), applicationUser.getPassword(),
getAuthorities(applicationUser.getRoles()));
}
@Transactional
public Collection<? extends GrantedAuthority> getUserAuthorities(String username) {
User user = userRepository.findByUsername(username);
return getAuthorities(user.getRoles());
}
private Collection<? extends GrantedAuthority> getAuthorities(
Collection<Role> roles) {
return getGrantedAuthorities(getPermissions(roles));
}
private List<String> getPermissions(Collection<Role> roles) {
List<String> permissions = new ArrayList<>();
List<Permission> collection = new ArrayList<>();
for (Role role : roles) {
collection.addAll(role.getPermissions());
}
for (Permission item : collection) {
permissions.add(item.getName());
}
return permissions;
}
private List<GrantedAuthority> getGrantedAuthorities(List<String> permissions) {
List<GrantedAuthority> authorities = new ArrayList<>();
for (String permission : permissions) {
authorities.add(new SimpleGrantedAuthority(permission));
}
return authorities;
}
}
Then i'm trying to annotate my endpoint with @PreAuthorize
@PostMapping("/doSomething")
@PreAuthorize("hasRole('doSomething')")
public SomeEntity createComment(@RequestBody SomeEntity something) {
...
}
I have user with role of USER
, this role doesn't have permission to doSomething
, however it seems like @PreAuthorize("hasRole('doSomething')")
is not working. I'm not sure what i have done wrong, coule you please point my mistake?
Also, since im using RBAC
this hasRole
is very missleading since access is permission based, not role based.
What would be correct way to authorize access to endpoint with RBAC
approach?
java spring spring-security rbac
im trying to secure my endpoints with role based access control. I have implemented the whole structure as well as CustomUserDetailService, however im not sure how should i enforce these rules on enpoints, i was looking for some nice annotation based evaluation like @PreAuthorize(hasRole('role'))
. My structure looks follwoing:
Permission:
@Entity
public class Permission implements GrantedAuthority {
@Id
private Long id;
@Column(name = "NAME")
private String name;
@ManyToMany(mappedBy = "permissions", fetch = FetchType.LAZY)
private Collection<Role> roles;
@Override
public String getAuthority() {
return name;
}
Role:
@Entity
public class Role implements GrantedAuthority {
@Id @Column(name="ID" )
private Long id;
@Column(name="NAME", nullable=false , unique=false)
private String name;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "role_x_permission",
joinColumns = @JoinColumn(
name = "role_id"),
inverseJoinColumns = @JoinColumn(
name = "permission_id"))
private List<Permission> permissions;
@Override
public String getAuthority() {
return name;
}
User:
@Entity(name = "User")
@Table(name = "USERS")
@Data
public class User {
@Id
private Long id;
@Column(name="LOGIN" , nullable=true , unique=false)
private String login;
@Column(name="PASSWORD" , nullable=false , unique=false)
private String password;
@ManyToMany( fetch = FetchType.LAZY)
@JoinTable(name = "USER_ROLES",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
Now i have defined my CustomUserDetailsService:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User applicationUser = userRepository.findByUsername(username);
if (applicationUser.getId() == null) {
throw new UsernameNotFoundException(username);
}
return new org.springframework.security.core.userdetails.User(applicationUser.getLogin(), applicationUser.getPassword(),
getAuthorities(applicationUser.getRoles()));
}
@Transactional
public Collection<? extends GrantedAuthority> getUserAuthorities(String username) {
User user = userRepository.findByUsername(username);
return getAuthorities(user.getRoles());
}
private Collection<? extends GrantedAuthority> getAuthorities(
Collection<Role> roles) {
return getGrantedAuthorities(getPermissions(roles));
}
private List<String> getPermissions(Collection<Role> roles) {
List<String> permissions = new ArrayList<>();
List<Permission> collection = new ArrayList<>();
for (Role role : roles) {
collection.addAll(role.getPermissions());
}
for (Permission item : collection) {
permissions.add(item.getName());
}
return permissions;
}
private List<GrantedAuthority> getGrantedAuthorities(List<String> permissions) {
List<GrantedAuthority> authorities = new ArrayList<>();
for (String permission : permissions) {
authorities.add(new SimpleGrantedAuthority(permission));
}
return authorities;
}
}
Then i'm trying to annotate my endpoint with @PreAuthorize
@PostMapping("/doSomething")
@PreAuthorize("hasRole('doSomething')")
public SomeEntity createComment(@RequestBody SomeEntity something) {
...
}
I have user with role of USER
, this role doesn't have permission to doSomething
, however it seems like @PreAuthorize("hasRole('doSomething')")
is not working. I'm not sure what i have done wrong, coule you please point my mistake?
Also, since im using RBAC
this hasRole
is very missleading since access is permission based, not role based.
What would be correct way to authorize access to endpoint with RBAC
approach?
java spring spring-security rbac
java spring spring-security rbac
edited Nov 22 '18 at 9:34
CS_noob
4091311
4091311
asked Nov 22 '18 at 9:25
Akka JaworekAkka Jaworek
4482418
4482418
Also, since im using RBAC this hasRole is very missleading since access is permission based, not role based. That is confusing, because RBAC means Role Based Access Control andhasRole
is the right way to implement it. However, you also not using permissions, because permissions (Spring wording) is part of ACL.
– dur
Nov 22 '18 at 12:30
@dur lets assume that for now that Permission is only for RBAC in my case. If i understood RBAC properly, each enpoint can have a permission, and the a role has set of permissions. Then hasRole needs to refer to permission correct?
– Akka Jaworek
Nov 22 '18 at 13:00
Possible duplicate of stackoverflow.com/questions/44004977/…
– dur
Nov 22 '18 at 20:49
add a comment |
Also, since im using RBAC this hasRole is very missleading since access is permission based, not role based. That is confusing, because RBAC means Role Based Access Control andhasRole
is the right way to implement it. However, you also not using permissions, because permissions (Spring wording) is part of ACL.
– dur
Nov 22 '18 at 12:30
@dur lets assume that for now that Permission is only for RBAC in my case. If i understood RBAC properly, each enpoint can have a permission, and the a role has set of permissions. Then hasRole needs to refer to permission correct?
– Akka Jaworek
Nov 22 '18 at 13:00
Possible duplicate of stackoverflow.com/questions/44004977/…
– dur
Nov 22 '18 at 20:49
Also, since im using RBAC this hasRole is very missleading since access is permission based, not role based. That is confusing, because RBAC means Role Based Access Control and
hasRole
is the right way to implement it. However, you also not using permissions, because permissions (Spring wording) is part of ACL.– dur
Nov 22 '18 at 12:30
Also, since im using RBAC this hasRole is very missleading since access is permission based, not role based. That is confusing, because RBAC means Role Based Access Control and
hasRole
is the right way to implement it. However, you also not using permissions, because permissions (Spring wording) is part of ACL.– dur
Nov 22 '18 at 12:30
@dur lets assume that for now that Permission is only for RBAC in my case. If i understood RBAC properly, each enpoint can have a permission, and the a role has set of permissions. Then hasRole needs to refer to permission correct?
– Akka Jaworek
Nov 22 '18 at 13:00
@dur lets assume that for now that Permission is only for RBAC in my case. If i understood RBAC properly, each enpoint can have a permission, and the a role has set of permissions. Then hasRole needs to refer to permission correct?
– Akka Jaworek
Nov 22 '18 at 13:00
Possible duplicate of stackoverflow.com/questions/44004977/…
– dur
Nov 22 '18 at 20:49
Possible duplicate of stackoverflow.com/questions/44004977/…
– dur
Nov 22 '18 at 20:49
add a comment |
1 Answer
1
active
oldest
votes
You should use hasAuthority('doSomething')
instead of hasRole('doSomething')
.
Role is just a permission with a prefix Role_
.
So hasRole('XXX')
is same as hasAuthority('ROLE_XXX')
this did not solve the problem, user is still able todoSomrthing
– Akka Jaworek
Nov 22 '18 at 12:38
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53427611%2fpermission-based-access-control-in-spring%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You should use hasAuthority('doSomething')
instead of hasRole('doSomething')
.
Role is just a permission with a prefix Role_
.
So hasRole('XXX')
is same as hasAuthority('ROLE_XXX')
this did not solve the problem, user is still able todoSomrthing
– Akka Jaworek
Nov 22 '18 at 12:38
add a comment |
You should use hasAuthority('doSomething')
instead of hasRole('doSomething')
.
Role is just a permission with a prefix Role_
.
So hasRole('XXX')
is same as hasAuthority('ROLE_XXX')
this did not solve the problem, user is still able todoSomrthing
– Akka Jaworek
Nov 22 '18 at 12:38
add a comment |
You should use hasAuthority('doSomething')
instead of hasRole('doSomething')
.
Role is just a permission with a prefix Role_
.
So hasRole('XXX')
is same as hasAuthority('ROLE_XXX')
You should use hasAuthority('doSomething')
instead of hasRole('doSomething')
.
Role is just a permission with a prefix Role_
.
So hasRole('XXX')
is same as hasAuthority('ROLE_XXX')
edited Nov 22 '18 at 11:52
answered Nov 22 '18 at 11:47
chaoluochaoluo
1,5481916
1,5481916
this did not solve the problem, user is still able todoSomrthing
– Akka Jaworek
Nov 22 '18 at 12:38
add a comment |
this did not solve the problem, user is still able todoSomrthing
– Akka Jaworek
Nov 22 '18 at 12:38
this did not solve the problem, user is still able to
doSomrthing
– Akka Jaworek
Nov 22 '18 at 12:38
this did not solve the problem, user is still able to
doSomrthing
– Akka Jaworek
Nov 22 '18 at 12:38
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53427611%2fpermission-based-access-control-in-spring%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Also, since im using RBAC this hasRole is very missleading since access is permission based, not role based. That is confusing, because RBAC means Role Based Access Control and
hasRole
is the right way to implement it. However, you also not using permissions, because permissions (Spring wording) is part of ACL.– dur
Nov 22 '18 at 12:30
@dur lets assume that for now that Permission is only for RBAC in my case. If i understood RBAC properly, each enpoint can have a permission, and the a role has set of permissions. Then hasRole needs to refer to permission correct?
– Akka Jaworek
Nov 22 '18 at 13:00
Possible duplicate of stackoverflow.com/questions/44004977/…
– dur
Nov 22 '18 at 20:49