我想在我的spring mvc项目之一中实现基于URL的授权。在我的spring mvc项目中,我正在使用java配置。我已引用该站点https://www.baeldung.com/role-and-privilege-for-spring-security-registration来实现基于角色和特权的授权。
所以我创建了以下表格以供实施。
这是用户表。
此角色表。
这是角色和特权之间的映射表。
这是特权表。
以下是来自控制器端的代码。
output.out
以下是实现UserDetailService的代码。
@Controller
@RequestMapping(value={"/user"})
public class UserController {
@ResponseBody
@RequestMapping(value={"/userDashboard"},method = RequestMethod.GET)
public String userDashboard(ModelMap model){
return "UserDashboard";
}
@ResponseBody
@RequestMapping(value={"/testUser"},method = RequestMethod.GET)
public String testUser(ModelMap model){
return "TestUser";
}
}
Spring安全配置
@Service("authService")
@Transactional
public class AuthService implements UserDetailsService {
@Autowired
private UserDaoInterface userDaoInterface;
private static final Logger log = Logger.getLogger(AuthService.class);
@Override
public UserDetails loadUserByUsername(String userName) {
User user = null;
try {
user = userDaoInterface.getUserByUserName(userName);
} catch (Exception e) {
log.error("AuthService @loadUserByUsername --Exception while fetching user from username",e);
}
if(user == null) {
throw new UsernameNotFoundException("Username not found");
}
UserDetails userDetails = new org.springframework.security.core.userdetails.User(user.getUsername(),
user.getPassword(),!user.getIsDeleted(),true,true,true,getAuthorities(user.getRole()));
log.info("UserService userDetails " + userDetails);
return userDetails;
}
private Collection<? extends GrantedAuthority> getAuthorities(Role role) {
return getGrantedAuthorities(getPrivileges(role));
}
private List<String> getPrivileges(Role role) {
List<String> privileges = new ArrayList<>();
List<Privilege> collection = new ArrayList<>();
collection.addAll(role.getPrivileges());
for (Privilege item : collection) {
privileges.add(item.getName());
}
return privileges;
}
private List<GrantedAuthority> getGrantedAuthorities(List<String> privileges) {
List<GrantedAuthority> authorities = new ArrayList<>();
for (String privilege : privileges) {
authorities.add(new SimpleGrantedAuthority(privilege));
}
return authorities;
}
}
当我通过存储在用户表中的凭据登录系统并尝试访问http://localhost:8080/RestProject/user/testUser之类的URL时,则用户被授权访问此URL,但根据上述实现,不应允许用户访问此URL。所以我无法理解动态权限在这里如何工作?
答案 0 :(得分:0)
要配置url授权,您需要更改行http.authorizeRequests().anyRequest().authenticated()
到
http.authorizeRequests()
.antMatchers("someurl").hasAuthority("ROLE_SOMEROLE")
.antMatchers("/**").hasAuthority("ROLE_ADMIN").authenticated()
但是,您似乎想要在运行时动态更改这些内容。我不确定春季是否可以让您这样做。但是,可以通过对角色结构的设计进行一些更改来实现类似的行为。
您需要在权限中添加一个分组层,并将这些组设置为用户角色(这些角色将分配给用户)。然后,您授予的权限将是分配给您的角色/分组的权限。这样,您可以动态更改这些组下的权限,而不必更改代码。
角色权限结构示例(伪Java代码):
注意:角色和组可以互换
@Entity
public class Permission {
private String name;
private String description;
... // getters and setters
}
@Entity
public class Role {
private String name;
@ManyToOne
private List<Permission> permissions;
... // getters and setters
}
首先,您需要一个执行某些操作的网址。假设它创建了一个新的员工记录。因此,您需要创建一个新的“ createEmployee”权限,并使该权限能够访问该URL。这里的想法是创建特定于其所保护动作的权限。这样,您以后就不必更改权限。
http.authorizeRequests()
.antMatchers("some-url").hasAuthority("createEmployee")
.antMatchers("/**").hasAuthority("admin").authenticated()
现在,您要做的就是将“ createEmployee”权限分配给角色,该角色的职责包括此操作。例如,假设它是“ hiringManager”角色/分组。
将权限分配给角色/分组:
Role hiringManager = new Role("hiringManager");
Permission createPermission = permissionRepository.findByName("createPermission");
hiringManager.getPermissions().add(createPermission);
这仅用于说明目的。理想情况下,您的应用程序中将有一个屏幕,可让您在运行时创建“组”和“权限”。然后,您可以根据需要在组中分配或删除权限。
请注意,这只是技术方面的一种解决方案。话虽如此,即使它不符合您的需求,它也应指导您提出您的业务需求。
希望这会有所帮助!