首页 > 作文

解决Spring Security的权限配置不生效问题

更新时间:2023-04-06 03:20:59 阅读: 评论:0

spring curity权限配置不生效

在集成spring curity做接口权限配置时,在给用户配置的权限后,还是一直显示“无权限”或者”权限不足”。

1、不生效的例子

接口

@requestmapping("/admin")    @responbody    @preauthorize("hasrole('admin')")    public string printadmin() {        return "如果你看见这句话,说明你有role_admin角色";    }    @requestmapping("/ur")    @responbody    @preauthorize("hasrole('ur')")    public string printur() {        return "如果你看见这句话,说明你有role_ur角色";    }

curityconfig

.and()      .authorizerequests()      .antmatchers("/ur").hasanyrole("ur")       .antmatchers("/admin").hasanyrole("admin")      .anyrequest().authenticated() //必须授权才能范围

用户携带权限

2、解决办法

经测试,只有用户携带权限的字段为 “role_” + 接口/配置 中的权限字段,才能控制生效,举例:

将上面的用户携带权限改为

spring curity动态配置权限

导入依赖

<dependency>    <groupid>org.springframework.boot</groupid>    <artifactid>spring-boot-starter-curity</artifactid></dependency><dependency>    <groupid>org.springframework.boot</groupid>    <artifactid>spring-boot-starter-web</artifactid></dependency><dependency>    <groupid>org.mybatis.spring.boot</groupid>    <artifactid>mybatis-spring-boot-starter</artifactid>    <version>2.1.3</version></dependency><dependency>    <groupid>c关于保护环境的手抄报om.alibaba</groupid>    <artifactid>druid-spring-boot-starter</artifactid>    <version>1.1.22</version></dependency><dependency>    <groupid>mysql</groupid>    <artifactid>mysql-connector-java</artifactid>    <scope>runtime</scope>    <version>5.1.46</version></dependency><dependency>    <groupid>org.springframework.boot</groupid>    <artifactid>spring-boot-starter-test</artifactid>    <scope>test</scope>    <exclusions>        <exclusion>            <groupid>org.junit.vintage</groupid>            <artifactid>junit-vintage-engine</artifactid>        </exclusion>    </exclusions></dependency><dependency>    <groupid>org.springframework.curity</groupid>    <artifactid>spring-curity-test</artifactid>    <scope>test</scope></dependency>

相关配置

application.properties

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/javaboy?uunicode=true&characterencoding=utf8&rvertimezone=utcspring.datasource.urname=rootspring.datasource.password=rootspring.datasource.type=com.alibaba.druid.pool.druiddatasource

实体类ur,role,menu

这里要实现urdetails接口,这个接口好比一个规范。防止开发者定义的密码变量名各不相同,从而导致springcurity不知道哪个方法是你的密码

public class ur implements urdetails {    private integer id;    private string urname;    private string password;    private boolean enabled;    private boolean locked;    private list<role> rolelist;    @override    public collection<? extends grantedauthority> getauthorities() {        list<simplegrantedauthority> authorities = new arraylist<>();        for (role role : rolelist) {            authorities.add(new simplegrantedauthority(role.getname()));        }        return authorities;    }    @override    public string getpassword() {        return password;    }    @override    public string geturname() {        return urname;    }    @override    public boolean isaccountnonexpired() {        return true;    }    @override    public boolean isaccountnonlocked() {        return !locked;    }    @override    public boolean iscredentialsnonexpired() {        return true;    }    @override    public boolean inabled() {        return enabled;    }    public integer getid() {        return id;    }    public void tid(integer id) {        this.id = id;    }    public void turname(string urname) {        this.urname = urname;    }    public void tpassword(string password) {        this.password = password;    }    public boolean getenabled() {        return enabled;    }    public void tenabled(boolean enabled) {        this.enabled = enabled;    }    public boolean getlocked() {        return locked;    }    public void tlocked(boolean locked) {        this.locked = locked;    }    public list<role> getrolelist() {        return rolelist;    }    public void trolelist(list<role> rolelist) {        this.rolelist = rolelist;    }}
public class role {    private integer id;    private string name;    private string namezh;...}
public class menu {    private integer id;    private string pattern;    private list<role> roles;...}

创建urmapper类&&urmapper.xml

和menumapper类&&menumapperxml

urmapper

@mapperpublic interface urmapper {  ur geturbyname(string name);  list<role> getrolebyid(integer id);}

urmapper.xml

<?xml version="1.0" encoding="utf-8" ?><!doctype mapper    public "-//mybatis.org//dtd mapper 3.0//en"    "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.qwl.mycuritydy.mapper.urmapper">  <lect id="geturbyname" resulttype="com.qwl.mycuritydy.bean.ur">    lect * from ur where urname= #{name}  </lect>  <lect id="getrolebyid" resulttype="com.qwl.mycuritydy.bean.role">    lect * from role where id in (lect rid from ur_role where uid = #{uid})  </lect></mapper>

menumapper

@mapperpublic interface menumapper {  list<menu> getmenus();}

memumapper.xml

<?xml version="1.0" encoding="utf-8" ?><!doctype mapper    public "-//mybatis.org//dtd mapper 3.0//en"    "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.qwl.mycuritydy.mapper.menumapper">  <resultmap id="menus_map" type="com.qwl.mycuritydy.bean.menu">    <id property="id" column="id"/>    <result property="pattern" column="pattern"/>    <collec朝阳实验小学tion property="roles" oftype="com.qwl.mycuritydy.bean.role">      <id property="id" column="rid"/>      <result property="name" column="rname"/>      <result property="namezh" column="rnamezh"/>    </collection>  </resultmap>  <lect id="getmenus" resultmap="menus_map">    lect m.*,r.id as rid,r.name as rname,r.namezh as rnamezh from menu_role mr left join    menu m on mr.mid = m.id left join role r on mr.rid = r.id  </lect></mapper>

创建urrvice menurvice

创建urrvice实现urrvicedetails接口

@rvicepublic class urrvice implements urdetailsrvice {  @autowired  private urmapper urmapper;  @override  public urdetails lo席上adurbyurname(string urname) throws urnamenotfoundexception {    ur ur = urmapper.geturbyname(urname);    if(ur ==null){      throw new urnamenotfoundexception("用户名不存在");    }    ur.trolelist(urmapper.getrolebyid(ur.getid()));    return ur;  }}

创建menurvice

@rvicepublic class menurvice {  @autowired  private menumapper menumapper;  public list<menu> getmenus() {return menumapper.getmenus();}}

创建customfilterinvocationcuritymetadatasource

实现接口filterinvocationcuritymetadatasource

注:加@comppent注解,把自定义类注册成spring组件

supports返回值设成true表示支持

重写getattributes()方法

invacation 调用 ,求助metadata 元数据
@componentpublic class customfilterinvocationcuritymetadatasource implements filterinvocationcuritymetadatasource {  //ant风格的路径匹配器  antpathmatcher pathmatcher = new antpathmatcher();  @autowired  private menurvice menurvice;  //supports返回值设成true表示支持  @override  public boolean supports(class<?> acl钱学森观后感ass) {    return true;  }  @override  public collection<configattribute> getattributes(object object) throws illegalargumentexception {    //获取当前用户请求的url    string requesturl=((filterinvocation) object).getrequesturl();    //数据库中查询出所有的路径    list<menu> menus =menurvice.getmenus();    for (menu menu : menus) {      //判断用户请求的url和数据库的url是否能匹配的上      if (pathmatcher.match(menu.getpattern(), requesturl)) {        list<role> roles =menu.getroles();        string[] rolestr = new string[roles.size()];        for (int i = 0; i < roles.size(); i++) {          rolestr[i]=roles.get(i).getname();        }        //将筛选的url路径所具备的角色返回回去        return curityconfig.createlist(rolestr);      }    }    //如果没有匹配上就返回一个默认的角色,作用好比作一个标记    return curityconfig.createlist("role_def");  }  @override  public collection<configattribute> getallconfigattributes() {    return null;  }}

创建customaccessdecisionmanager

实现accessdecisionmanager接口 access 通道

注:加@comppent注解,把自定义类注册成spring组件

将两个supports()都设置成true

重写decide()方法

@componentpublic class customaccessdecisionmanager implements accessdecisionmanager {  @override  public void decide(authentication authentication, object o, collection<configattribute> collection) throws accessdeniedexception, insufficientauthenticationexception {    //configattributes里存放着customfilterinvocationcuritymetadatasource过滤出来的角色    for (configattribute configattribute : collection) {      //如果你请求的url在数据库中不具备角色      if ("role_def".equals(configattribute.getattribute())) {        //在判断是不是匿名用户(也就是未登录)        if (authentication instanceof anonymousauthenticationtoken) {          system.out.println(">>>>>>>>>>>>>qq会员申请;>>>匿名用户>>>>>>>>>>>>>>");          throw new accessdeniedexception("权限不足,无法访问");        }el{          //这里面就是已经登录的其他类型用户,直接放行          system.out.println(">>>>>>>>>>>其他类型用户>>>>>>>>>>>");          return;        }      }      //如果你访问的路径在数据库中具有角色就会来到这里      //autherntication这里面存放着登录后的用户所有信息      collection<? extends grantedauthority> authorities = authentication.getauthorities();      for (grantedauthority authority : authorities) {        system.out.println(">>>>>>>authority(账户所拥有的权限):"+authority.getauthority());        system.out.println(">>>>>>>configattribute(路径需要的角色):"+configattribute.getattribute());        //路径需要的角色和账户所拥有的角色作比较        if (authority.getauthority().equals(configattribute.getattribute())) {          system.out.println(">>>>>>>>>>>>>>>>>>进来>>>>>>>>>>>>>>>>>");          return;        }      }    }  }  @override  public boolean supports(configattribute configattribute) {    return true;  }  @override  public boolean supports(class<?> aclass) {    return true;  }}

创建webcurityconfig配置类

webcurityconfig实现webcurityconfigureradapter

注入一会所需要的类

springcurity5.0之后必须密码加密

将数据库查出的账户密码交给springcurity去判断

配置httpcurity

@configurationpublic class webcurityconfig extends webcurityconfigureradapter {  @autowired  private urrvice urrvice;  @autowired  private customfilterinvocationcuritymetadatasource customfilterinvocationcuritymetadatasource;  @autowired  private customaccessdecisionmanager customaccessdecisionmanager;  //springcutity5.0之后必密码加密  @bean  passwordencoder passwordencoder(){    return new bcryptpasswordencoder();  }  //将数据库查出的账户密码交给springcurity去判断  @override  protected void configure(authenticationmanagerbuilder auth) throws exception {    auth.urdetailsrvice(urrvice);  }  //配置httpcurity  @override  protected void configure(httpcurity http) throws exception {    http.authorizerequests()        .withobjectpostprocessor(new objectpostprocessor<filtercurityinterceptor>() {          @override          public <o extends filtercurityinterceptor> o postprocess(o object){            object.tcuritymetadatasource(customfilterinvocationcuritymetadatasource);            object.taccessdecisionmanager(customaccessdecisionmanager);            return object;          }        })        .and()        .formlogin()        .permitall()        .and()        .csrf().disable();  }}

controller

@restcontrollerpublic class hellocontroller {  @getmapping("/hello")  public string hello(){    return "hello";  }  @getmapping("/dba/hello")  public string dba(){    return "hello dba";  }  @getmapping("/admin/hello")  public string admin(){    return "hello admin";  }  @getmapping("/ur/hello")  public string ur(){    return "hello ur";  }}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。

本文发布于:2023-04-06 03:20:57,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/78a7cfe0b264750b54b1808ff098c565.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:解决Spring Security的权限配置不生效问题.doc

本文 PDF 下载地址:解决Spring Security的权限配置不生效问题.pdf

标签:权限   用户   角色   接口
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图