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

 







免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM