springboot+thymeleaf+shiro标签的实例
程序员文章站
2022-03-08 15:29:33
目录1、pom中加入依赖2、用户-角色-权限的表关系3、编写shiro核心类4、登录控制器5、thymeleaf页面权限控制6、标签说明1、pom中加入依赖<...
1、pom中加入依赖
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-thymeleaf</artifactid> <version>1.5.6.release</version> </dependency> <!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf --> <dependency> <groupid>org.thymeleaf</groupid> <artifactid>thymeleaf</artifactid> <version>${thymeleaf.version}</version> </dependency> <!-- shiro安全框架 --> <dependency> <groupid>org.apache.shiro</groupid> <artifactid>shiro-spring</artifactid> <version>1.4.0</version> </dependency> <!--thymeleaf-shiro-extras--> <dependency> <groupid>com.github.theborakompanioni</groupid> <artifactid>thymeleaf-extras-shiro</artifactid> <version>1.2.1</version> </dependency>
2、用户-角色-权限的表关系
//用户表 public class user { private integer userid; private string username; private set<role> roles = new hashset<>(); } //角色表 public class user { private integer id; private string role; private set<module> modules = new hashset<>(); private set<user> users = new hashset<>(); } //权限表 public class module { private integer mid; private string mname; private set<role> roles = new hashset<>(); } //用户查询 <resultmap id="baseresultmap" type="com.lanyu.common.model.user" > <id column="user_id" property="userid" jdbctype="integer" /> <result column="user_name" property="username" jdbctype="varchar" /> <!-- 多对多关联映射:collection --> <collection property="roles" oftype="role"> <id property="id" column="c_id" /> <result property="role" column="role" /> <collection property="modules" oftype="module"> <id property="mid" column="mid"/> <result property="mname" column="mname"/> </collection> </collection> </resultmap> //查询用户信息,返回结果会自动分组,得到用户信息 <select id="selectbyphone" resultmap="baseresultmap" parametertype="java.lang.string" > select u.*, r.*, m.* from sys_user u inner join sys_user_role ur on ur.userid = u.user_id inner join sys_role r on r.rid = ur.roleid inner join sys_role_module mr on mr.rid = r.rid inner join sys_module m on mr.mid = m.mid where u.user_name=#{username} or u.phone=#{username}; </select>
3、编写shiro核心类
@configuration public class shiroconfiguration { //用于thymeleaf模板使用shiro标签 @bean public shirodialect shirodialect() { return new shirodialect(); } @bean(name="shirofilter") public shirofilterfactorybean shirofilter(@qualifier("securitymanager") securitymanager manager) { shirofilterfactorybean bean=new shirofilterfactorybean(); bean.setsecuritymanager(manager); //配置登录的url和登录成功的url bean.setloginurl("/loginpage"); bean.setsuccessurl("/indexpage"); //配置访问权限 linkedhashmap<string, string> filterchaindefinitionmap=new linkedhashmap<>(); // filterchaindefinitionmap.put("/loginpage*", "anon"); //表示可以匿名访问 filterchaindefinitionmap.put("/admin/*", "authc");//表示需要认证才可以访问 filterchaindefinitionmap.put("/logout*","anon"); filterchaindefinitionmap.put("/img/**","anon"); filterchaindefinitionmap.put("/js/**","anon"); filterchaindefinitionmap.put("/css/**","anon"); filterchaindefinitionmap.put("/fomts/**","anon"); filterchaindefinitionmap.put("/**", "anon"); bean.setfilterchaindefinitionmap(filterchaindefinitionmap); return bean; } //配置核心安全事务管理器 @bean(name="securitymanager") public securitymanager securitymanager(@qualifier("authrealm") authrealm authrealm) { system.err.println("--------------shiro已经加载----------------"); defaultwebsecuritymanager manager=new defaultwebsecuritymanager(); manager.setrealm(authrealm); return manager; } //配置自定义的权限登录器 @bean(name="authrealm") public authrealm authrealm(@qualifier("credentialsmatcher") credentialsmatcher matcher) { authrealm authrealm=new authrealm(); authrealm.setcredentialsmatcher(matcher); return authrealm; } //配置自定义的密码比较器 @bean(name="credentialsmatcher") public credentialsmatcher credentialsmatcher() { return new credentialsmatcher(); } @bean public lifecyclebeanpostprocessor lifecyclebeanpostprocessor(){ return new lifecyclebeanpostprocessor(); } @bean public defaultadvisorautoproxycreator defaultadvisorautoproxycreator(){ defaultadvisorautoproxycreator creator=new defaultadvisorautoproxycreator(); creator.setproxytargetclass(true); return creator; } @bean public authorizationattributesourceadvisor authorizationattributesourceadvisor(@qualifier("securitymanager") securitymanager manager) { authorizationattributesourceadvisor advisor=new authorizationattributesourceadvisor(); advisor.setsecuritymanager(manager); return advisor; } } — - - -- - -- - -- - -- - - -- - - - -- public class authrealm extends authorizingrealm { @autowired private userservice userservice; //认证.登录 @override protected authenticationinfo dogetauthenticationinfo(authenticationtoken token) throws authenticationexception { usernamepasswordtoken utoken=(usernamepasswordtoken) token;//获取用户输入的token string username = utoken.getusername(); user user = userservice.selectbyphone(username); return new simpleauthenticationinfo(user, user.getpassword(),this.getclass().getname());//放入shiro.调用credentialsmatcher检验密码 } //授权 @override protected authorizationinfo dogetauthorizationinfo(principalcollection principal) { user user=(user) principal.fromrealm(this.getclass().getname()).iterator().next();//获取session中的用户 list<string> permissions=new arraylist<>(); set<role> roles = user.getrolelist(); simpleauthorizationinfo info=new simpleauthorizationinfo(); list<string> listrole = new arraylist<>(); if(roles.size()>0) { for(role role : roles) { if(!listrole.contains(role.getrole())){ listrole.add(role.getrole()); } set<module> modules = role.getmodules(); if(modules.size()>0) { for(module module : modules) { permissions.add(module.getmname()); } } } } info.addroles(listrole); //将角色放入shiro中. info.addstringpermissions(permissions); //将权限放入shiro中. return info; } } //自定义密码比较器 public class credentialsmatcher extends simplecredentialsmatcher { private logger logger = logger.getlogger(credentialsmatcher.class); @override public boolean docredentialsmatch(authenticationtoken token, authenticationinfo info) { usernamepasswordtoken utoken=(usernamepasswordtoken) token; //所需加密的参数 即 用户输入的密码 string source = string.valueof(utoken.getpassword()); //[盐] 一般为用户名 或 随机数 string salt = utoken.getusername(); //加密次数 int hashiterations = 50; simplehash sh = new simplehash("md5", source, salt, hashiterations); string strsh =sh.tohex(); //打印最终结果 logger.info("正确密码为:"+strsh); //获得数据库中的密码 string dbpassword= (string) getcredentials(info); logger.info("数据库密码为:"+dbpassword); //进行密码的比对 return this.equals(strsh, dbpassword); } }
4、登录控制器
@requestmapping("/loginuser") public string loginuser(string username,string password,httpsession session) { usernamepasswordtoken usernamepasswordtoken=new usernamepasswordtoken(username,password); subject subject = securityutils.getsubject(); map map=new hashmap(); try { subject.login(usernamepasswordtoken); //完成登录 user user=(user) subject.getprincipal(); session.setattribute("user", user); return "index"; } catch (incorrectcredentialsexception e) { map.put("msg", "密码错误"); } catch (lockedaccountexception e) { map.put("msg", "登录失败,该用户已被冻结"); } catch (authenticationexception e) { map.put("msg", "该用户不存在"); } catch (exception e) { return "login";//返回登录页面 } return map.tostring(); }
5、thymeleaf页面权限控制
<html lang="zh_cn" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> //作为属性控制 <button type="button" shiro:authenticated="true" class="btn btn-outline btn-default"> <i class="glyphicon glyphicon-plus" aria-hidden="true"></i> </button> //作为标签 <shiro:hasrole name="admin"> <button type="button" class="btn btn-outline btn-default"> <i class="glyphicon glyphicon-heart" aria-hidden="true"></i> </button> </shiro:hasrole>
6、标签说明
guest标签 <shiro:guest> </shiro:guest> 用户没有身份验证时显示相应信息,即游客访问信息。 user标签 <shiro:user> </shiro:user> 用户已经身份验证/记住我登录后显示相应的信息。 authenticated标签 <shiro:authenticated> </shiro:authenticated> 用户已经身份验证通过,即subject.login登录成功,不是记住我登录的。 notauthenticated标签 <shiro:notauthenticated> </shiro:notauthenticated> 用户已经身份验证通过,即没有调用subject.login进行登录,包括记住我自动登录的也属于未进行身份验证。 principal标签 <shiro: principal/> <shiro:principal property="username"/> 相当于((user)subject.getprincipals()).getusername()。 lackspermission标签 <shiro:lackspermission name="org:create"> </shiro:lackspermission> 如果当前subject没有权限将显示body体内容。 hasrole标签 <shiro:hasrole name="admin"> </shiro:hasrole> 如果当前subject有角色将显示body体内容。 hasanyroles标签 <shiro:hasanyroles name="admin,user"> </shiro:hasanyroles> 如果当前subject有任意一个角色(或的关系)将显示body体内容。 lacksrole标签 <shiro:lacksrole name="abc"> </shiro:lacksrole> 如果当前subject没有角色将显示body体内容。 haspermission标签 <shiro:haspermission name="user:create"> </shiro:haspermission> 如果当前subject有权限将显示body体内容
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
上一篇: 大臣妻子怒骂朱温,朱温什么反应?
下一篇: C++入门