史上最简单的Spring Security总结——授权篇

转载自:https://www.jianshu.com/p/cba56572fec5

Spring Security是一款强大的安全认证服务框架,它的原理就是在访问我们的系统前加了一系列的过滤器,可以称为过滤器链。它的两大核心就是认证和授权,本文主要描述的授权篇,认证篇请看https://www.jianshu.com/p/24c6a65c3913。那废话不多说,我们接着认证篇继续开车吧(新手司机,请坐稳!持续更新)

权限表达式

springsecurity是通过权限表达式控制授权,springsecurity的权限表达式及说明如下:

表达式说明
permitAll永远返回true
denyAll永远返回false
anonymous当前用户是anonymous时返回true
rememberMe当前用户是rememberMe用户时返回true
authenticated当前用户不是anonymous时返回true
fullAuthenticated当前用户既不是anonymous也不是rememberMe用户时返回true
hasRole(role)用户拥有指定的角色权限时返回true
hasAnyRole([role1,role2])用户拥有任意一个指定的角色权限时返回true
hasAuthority(authority)用户拥有指定的权限时返回true
hasAnyAuthority([authority1,authority2])用户拥有任意一个指定的权限时返回true
hasIpAddress('192.168.1.0')请求发送的Ip匹配时返回true

接着认证部分的代码,在MySecurityConfig 的configure方法里添加需要的权限表达式:

@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http.httpBasic()
        http.authorizeRequests()
                .antMatchers("/hello.html")
                .permitAll()//注意这里hello.html需要配置成不需要身份认证,否则会报重定向次数过多
                .antMatchers("/user.html")
//              .hasRole("ADMIN")//用hasRole时,在我们返回的UserDetails的Authority需要加Role_ADMIN
//              .hasAuthority("read")//用户自定义的权限,返回的UserDetails的Authority只要与这里匹配就可以,这里不需要加ROLE_
//              .access("hasRole('ADMIN') and hasIpAddress('192.168.0.1')")//指定有ADMIN权限并且匹配相应的IP
                .access("@MyRbacService.findAuthority(request,authentication)")//指定我们自己写的方法控制权限
                .and()
                .formLogin()
                .loginPage("/hello.html")//指定我们自己的登录页面
                .loginProcessingUrl("/admin/login")//指定让UsernamePasswordAuthenticationFilter拦截器拦截的路径
                .defaultSuccessUrl("/index")//默认登录成功后跳转的页面
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated();
        http.csrf().disable();
        http.headers().frameOptions().sameOrigin();
    }
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

在强调一次,用hasRole时,在我们MyUserDetailService 返回的权限集合一定要加ROLE_ADMIN

@Component
public class MyUserDetailService implements UserDetailsService {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
        return new User(name,passwordEncoder.encode("123456"), AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN"));
    }
}

在上面配置类里用到了access,可以拼接我们自己定义的权限表达式,也可以指定我们自己写的控制权限类如.access("@MyRbacService.findAuthority(request,authentication)")
自定义权限控制类之前需要在pom里添加两个依赖

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
</dependency>

对应的Service,参数需要HttpServletRequest 和Authentication ,返回值一定要是boolean:

public interface MyRbacService {
    boolean findAuthority(HttpServletRequest request, Authentication authentication);
}

实现类:

@Component("MyRbacService")
public class MyRbacServiceImpl implements MyRbacService {
    private AntPathMatcher antPathMatcher=new AntPathMatcher();
    @Override
    public boolean findAuthority(HttpServletRequest request, Authentication authentication) {
        boolean authority=false;
        if (authentication.getPrincipal() instanceof UserDetails){
            String username = ((UserDetails) authentication.getPrincipal()).getUsername();
            //根据username去数据库查询对应的url,这里就不查了
            List<String> list =new ArrayList();
            for (String url:list){
                if (antPathMatcher.match(url,request.getRequestURI())){
                    authority=true;
                    break;
                }
            }
            return authority;
        }
        return authority;
    }
}

上面代码需要在数据库创建用户表,权限表,对应url表,然后根据Authentication 里的username信息查找对应有权限的url去与当前请求url匹配,因为认证篇已经讲过,用户认证通过之后会把Authentication存在session里,所以认证过了Authentication 才会有用户信息。这里返回类型一定要是boolean,然后交给springsecurity处理。


转载自:https://www.jianshu.com/p/cba56572fec5

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值