基于Spring Security URL的授权

时间:2019-02-03 07:26:07

标签: spring spring-mvc spring-security

我想在我的spring mvc项目之一中实现基于URL的授权。在我的spring mvc项目中,我正在使用java配置。我已引用该站点https://www.baeldung.com/role-and-privilege-for-spring-security-registration来实现基于角色和特权的授权。

所以我创建了以下表格以供实施。

这是用户表。

enter image description here

此角色表。

enter image description here

这是角色和特权之间的映射表。

enter image description here

这是特权表。

enter image description here

以下是来自控制器端的代码。

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。所以我无法理解动态权限在这里如何工作?

1 个答案:

答案 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);

这仅用于说明目的。理想情况下,您的应用程序中将有一个屏幕,可让您在运行时创建“组”和“权限”。然后,您可以根据需要在组中分配或删除权限。

请注意,这只是技术方面的一种解决方案。话虽如此,即使它不符合您的需求,它也应指导您提出您的业务需求。

希望这会有所帮助!