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

原文链接: https://www.jianshu.com/p/cba56572fec5

转载自: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里添加两个依赖


    javax.servlet
    javax.servlet-api


    org.springframework.security
    spring-security-core

对应的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 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

你可能感兴趣的:(spring,springBoot)