在集成spring curity做接口权限配置时,在给用户配置的权限后,还是一直显示“无权限”或者”权限不足”。
接口
@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() //必须授权才能范围
用户携带权限
经测试,只有用户携带权限的字段为 “role_” + 接口/配置 中的权限字段,才能控制生效,举例:
将上面的用户携带权限改为
<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;...}
和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实现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();}}
实现接口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; }}
实现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实现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 条评论) |