权限管理之Spring Security(二)

权限管理之Spring Security(一)中,可以说完成了一个最简单的可以使用的demo,但是在实际情况中,我们通常希望权限是存储在数据库中的而不是在代码中以注解的方式写死。本文来探讨security基于数据库的动态权限。

首先我们来理解一下如何做到权限控制,在我看来,其实就是判断当前用户是否可以访问这个url,如何来判断呢,实际上就是看用户所谓的权限列表中有没有当前这个url。最根本的权限管理如何做,数据库存储用户能访问的url,当访问链接时,判断当前url是否在用户可访问的列表中,是则允许访问,否则无权限。

security实际上已经帮我们完成了判断的过程,我们只需要提供用户的权限即可,但是security是根据所谓的权限标识来进行判断的(即ROLE),所以我们需要获取所有的url,并为每个url指定一个权限标识,配置代码如下(延用之前的demo):

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(new MyUserDetailsService());
    }

    @Data
    class Permission{
        private String url;
        private String ROLE;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //构造权限
        Set<Permission> set = new HashSet<>();
        Permission permission  = new Permission();
        permission.setUrl("/admin/**");
        permission.setROLE("ADMIN");
        set.add(permission);
        Permission permission1 = new Permission();
        permission1.setUrl("/role");
        permission1.setROLE("USER");
        set.add(permission1);

        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry urlRegistry = http.formLogin().permitAll()
                .and()
                .authorizeRequests()
                .antMatchers("/test/**").permitAll();
        set.forEach(permission2 -> {
                    urlRegistry.antMatchers(permission2.getUrl()).hasRole(permission2.getROLE());
            });
            urlRegistry.anyRequest().authenticated();

    }


    class MyUserDetailsService implements UserDetailsService {

        private Map<String, User> userRepository = new HashMap<String, User>();

        public MyUserDetailsService() {
            List<SimpleGrantedAuthority> authorities = new ArrayList<>();
            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
            User user1 = new User("user1", "password1", authorities);
            userRepository.put("user1", user1);
            User user2 = new User("user2", "password2", authorities);
            userRepository.put("user2", user2);
        }

        @Override
        public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
            User user = userRepository.get(s);
            return user;
        }
    }

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

}

在上面的代码中,我构造了两个url的权限,在实际开发中,这里应该从数据库查出所有的接口权限,同时此处也可以额外添加其他的配置,如限制ip,以及过滤接口等。详见官方文档

security的授权核心是 AccessDecisionManager以及AccessDecisionVoter,但是我并不推荐去自己实现这两个对象来达到数据库动态权限配置的目的,因为那样很麻烦并且存在一定的问题。我写的这种方式是我认为比较合理的,而且不用过多的配置即可完成一整套的功能。当然,可能是我对它的认识还不够准确,有不对的地方敬请指正。最后附上基于AccessDecisionManager以及AccessDecisionVoter实现动态权限配置的链接。

https://www.cnblogs.com/softidea/p/7068149.html

https://www.cnblogs.com/xiaoqi/p/spring-security-rabc.html

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Spring Security是一个用于在Java应用程序中实现身份验证和授权的框架。它提供了一种可靠和灵活的方法来管理应用程序中的权限。通过使用Spring Security,可以轻松地自定义登录授权过程。 首先,我们需要创建一个实现`UserDetailsService`接口的类来处理用户的身份验证。在这个类中,我们可以自定义用户的登录逻辑,例如验证用户名和密码。我们可以使用Spring Security提供的各种验证方法来验证用户的身份。 接下来,我们需要配置Spring Security来处理用户的授权。可以使用`WebSecurityConfigurerAdapter`类扩展一个配置类,并覆盖其中的`configure`方法。在这个方法中,我们可以指定哪些URL需要受到保护,哪些URL可以公开访问。例如,我们可以使用`antMatchers`方法来指定URL模式,然后使用`hasAuthority`或`hasRole`方法来指定用户需要具备的权限或角色。 另外,我们还可以使用`@PreAuthorize`注解来在方法级别上进行授权。可以在需要进行授权的方法上添加该注解,并指定用户需要具备的权限或角色。 最后,我们还可以通过自定义`AuthenticationProvider`来实现更复杂的授权逻辑。可以创建一个实现该接口的类,并在其中实现自定义的身份验证和授权逻辑。然后可以将这个自定义的`AuthenticationProvider`添加到Spring Security的配置中。 通过以上的方法,我们可以灵活地自定义登录授权过程。Spring Security提供了丰富的配置选项和接口来满足各种不同的授权需求。使用Spring Security,我们可以有效地管理应用程序中的权限,并确保只有具备合适权限的用户可以访问受保护的资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值