SpringSecurity权限管理框架--基于springBoot实现授权功能

springSecurity授权方式有三种,分别是配置授权,注解授权,标签授权

这里使用 注解授权

配置类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
//配置开启注解式授权
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private BzAdminServiceImpl bzAdminService;
    /**
     * Authentication 认证的意思
     * 在shiro和SpringSecurity中 所有以Authen开头的单词都和认证业务有关系
     *
     * 定义数据源 定义要不要使用数据库的数据 或者使用假数据
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(bzAdminService).passwordEncoder(bCryptPasswordEncoder());

// 内存测试数据
//    auth.inMemoryAuthentication().withUser("lisi")
// .password("{noop}123456") // .authorities("ROLE_admin","banner:delete","admin:delete") // .and() // .withUser("zhangsan") // .password("{noop}123456") // .authorities("ROLE_superadmin","banner:delete","category:select") // ; } @Bean public BCryptPasswordEncoder bCryptPasswordEncoder(){ return new BCryptPasswordEncoder(); } /** * HttpSecurity 配置拦截规则 跳转 和 自定义登录页面 * */ @Override protected void configure(HttpSecurity http) throws Exception { /** * authorizition 授权 * 在shiro和SpringSecurity中 所有以Author开头的单词都和授权业务有关系 * authorizeRequests 配置拦截规则 * antMatchers 配置路径 * permitAll 不拦截 */ http.authorizeRequests() // 配置不拦截 .antMatchers("/admin/**", "/img/**", "/css/**", "/js/**", "/ztree/**", "/login.jsp", "/login", "/layui/**") .permitAll() //.antMatchers("/pmsCategory/getZtreeCategory").hasAnyRole("ADMIN") // .antMatchers("/pmsCategory/getZtreeCategory").hasAuthority("category:select") // 拦截所有 配置一般不会使用/** 而是独立配置 // anyRequest 代表所有路径 .anyRequest() .authenticated(); //formLogin() 代表表单登录 http.formLogin() // loginPage 自定义登录页面 .loginPage("/login.jsp") //successForwardUrl 登录成功后的地址 .successForwardUrl("/admin/successForwardUrl") // failureForwardUrl 登录失败后的地址 .failureForwardUrl("/error.jsp") //loginProcessingUrl 定义登录方法的地址 /login就是SpringSecurity中的认证方法 .loginProcessingUrl("/login") .and() .csrf() .disable() ; // html iframe标签引用二级页面 会被默认拦截 // 可以配置不拦截 http.headers().frameOptions().disable(); } }

 业务类

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
public class BzAdminServiceImpl  implements BzAdminService, UserDetailsService {
    @Autowired
    private BzAdminMapper bzAdminMapper;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private BzRoleService bzRoleService;

    //该方法是springSecurity 预留的查询数据库方法,需要我们自己写实现
    //形参是 用户名
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

        String oldCode =(String) request.getSession().getAttribute("oldCode");
        String code = request.getParameter("code");
        if (!oldCode.equalsIgnoreCase(code)){
           threadLocal.set("验证码错误");
           throw new UsernameNotFoundException("验证码错误");
        }

        BzAdmin username = getOne(new QueryWrapper<BzAdmin>().eq("username", s));
        if (username==null){
            throw new UsernameNotFoundException(s+"不存在");
        }
        //权限
        Set<String> permissionsByUsername = bzRoleService.getPermissionsByUsername(s);

        permissionsByUsername.remove("null");

        List<GrantedAuthority> list1 = permissionsByUsername.stream()
                .filter(new Predicate<String>() {
                    @Override
                    public boolean test(String s) {
                        return s!=null;
                    }
                })
                .map((Function<String, GrantedAuthority>) permissions -> {

            SimpleGrantedAuthority simpleGrantedAuthority = null;
            if (permissions!=null){
                simpleGrantedAuthority = new SimpleGrantedAuthority(permissions);
            }
            return simpleGrantedAuthority;
        }).collect(Collectors.toList());


//        角色
        Set<String> rolesByUsername = bzRoleService.getRolesByUsername(s);

        List<GrantedAuthority> list = rolesByUsername.stream().map(new Function<String, GrantedAuthority>() {
            @Override
            public GrantedAuthority apply(String role) {

                return new SimpleGrantedAuthority("ROLE_" + role);
            }
        }).collect(Collectors.toList());

        list.addAll(list1);

        //放入权限 角色 集合
        username.setAuthorityList(list);
        return username;
    }
}

实体类

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;

@Data
public class BzAdmin implements Serializable, UserDetails {

    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
 
    private String username;


    private String password;

  
    private String mima;

   

    @TableLogic(value = "0",delval = "1")
    private Integer status = 0;

    //封装角色信息和授权信息 必须是GrantedAuthority接口的实现类
    @TableField(exist = false)
    private List<GrantedAuthority> authorityList;


    //封装授权信息
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorityList;
    }

    //账号失效
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    //账户锁定
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    //凭证信息失效
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    //账号可用性
    @Override
    public boolean isEnabled() {
        return true;
    }
}

测试

在需要权限的方法上添加注解

@PreAuthorize("hasAnyRole('vip')") //校检角色
@PreAuthorize("hasAuthority('admin:select')")  //校检权限

常见的权限字符串的写法

权限字符串的语法

权限字符串的规则是:“资源类型:操作(增删改查):资源实例(id)”,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例 的分割符

权限的汉语描述 权限字符串 资源类型:操作:实例
展示轮播图 banner:select
展示id为10的轮播图 banner:show:10
删除轮播图 banner:delete
删除商品 product:delete

 






原文地址:https://www.cnblogs.com/huahualove/p/13956649.html