这篇文章主要讲解了“Java安全框架Shiro怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java安全框架Shiro怎么使用”吧!

Shiro简介

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理

三个核心组件:Subject, SecurityManager 和 Realms

Subject代表了当前用户的安全操作

SecurityManager管理所有用户的安全操作,是Shiro框架的核心,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。

Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。

Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。

Shiro快速入门

导入依赖

<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.7.1</version></dependency><!--configurelogging--><!--https://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j--><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>2.0.0-alpha1</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>2.0.0-alpha1</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>

配置log4j.properties

log4j.rootLogger=INFO,stdoutlog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d%p[%c]-%m%n#GeneralApachelibrarieslog4j.logger.org.apache=WARN#Springlog4j.logger.org.springframework=WARN#DefaultShirologginglog4j.logger.org.apache.shiro=INFO#Disableverboselogginglog4j.logger.org.apache.shiro.util.ThreadContext=WARNlog4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN

配置Shiro.ini(在IDEA中需要导入ini插件)

[users]#user'root'withpassword'secret'andthe'admin'roleroot=secret,admin#user'guest'withthepassword'guest'andthe'guest'roleguest=guest,guest#user'presidentskroob'withpassword'12345'("That'sthesamecombinationon#myluggage!!!";)),androle'president'presidentskroob=12345,president#user'darkhelmet'withpassword'ludicrousspeed'androles'darklord'and'schwartz'darkhelmet=ludicrousspeed,darklord,schwartz#user'lonestarr'withpassword'vespa'androles'goodguy'and'schwartz'lonestarr=vespa,goodguy,schwartz#-----------------------------------------------------------------------------#Roleswithassignedpermissions##Eachlineconformstotheformatdefinedinthe#org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitionsJavaDoc#-----------------------------------------------------------------------------[roles]#'admin'rolehasallpermissions,indicatedbythewildcard'*'admin=*#The'schwartz'rolecandoanything(*)withanylightsaber:schwartz=lightsaber:*#The'goodguy'roleisallowedto'drive'(action)thewinnebago(type)with#licenseplate'eagle5'(instancespecificid)goodguy=winnebago:drive:eagle5

快速入门实现类 quickStart.java

importorg.apache.shiro.SecurityUtils;importorg.apache.shiro.authc.*;importorg.apache.shiro.config.IniSecurityManagerFactory;importorg.apache.shiro.mgt.DefaultSecurityManager;importorg.apache.shiro.realm.text.IniRealm;importorg.apache.shiro.session.Session;importorg.apache.shiro.subject.Subject;importorg.apache.shiro.util.Factory;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;publicclassquickStart{privatestaticfinaltransientLoggerlog=LoggerFactory.getLogger(quickStart.class);/*Shiro三大对象:Subject:用户SecurityManager:管理所有用户Realm:连接数据*/publicstaticvoidmain(String[]args){//创建带有配置的ShiroSecurityManager的最简单方法//realms,users,rolesandpermissions是使用简单的INI配置。//我们将使用可以提取.ini文件的工厂来完成此操作,//返回一个SecurityManager实例://在类路径的根目录下使用shiro.ini文件//(file:和url:前缀分别从文件和url加载)://Factory<SecurityManager>factory=newIniSecurityManagerFactory("classpath:shiro.ini");//SecurityManagersecurityManager=factory.getInstance();DefaultSecurityManagersecurityManager=newDefaultSecurityManager();IniRealminiRealm=newIniRealm("classpath:shiro.ini");securityManager.setRealm(iniRealm);//对于这个简单的示例快速入门,请使SecurityManager//可作为JVM单例访问。大多数应用程序都不会这样做//而是依靠其容器配置或web.xml进行//webapps。这超出了此简单快速入门的范围,因此//我们只做最低限度的工作,这样您就可以继续感受事物.SecurityUtils.setSecurityManager(securityManager);//现在已经建立了一个简单的Shiro环境,让我们看看您可以做什么://获取当前用户对象SubjectSubjectcurrentUser=SecurityUtils.getSubject();//使用Session做一些事情(不需要Web或EJB容器!!!Sessionsession=currentUser.getSession();//通过当前用户拿到Sessionsession.setAttribute("someKey","aValue");Stringvalue=(String)session.getAttribute("someKey");if(value.equals("aValue")){log.info("Retrievedthecorrectvalue!["+value+"]");}//判断当前用户是否被认证if(!currentUser.isAuthenticated()){//token:令牌,没有获取,随机UsernamePasswordTokentoken=newUsernamePasswordToken("lonestarr","vespa");token.setRememberMe(true);//设置记住我try{currentUser.login(token);//执行登陆操作}catch(UnknownAccountExceptionuae){//打印出用户名log.info("Thereisnouserwithusernameof"+token.getPrincipal());}catch(IncorrectCredentialsExceptionice){//打印出密码log.info("Passwordforaccount"+token.getPrincipal()+"wasincorrect!");}catch(LockedAccountExceptionlae){log.info("Theaccountforusername"+token.getPrincipal()+"islocked."+"Pleasecontactyouradministratortounlockit.");}//...在此处捕获更多异常(也许是针对您的应用程序的自定义异常?catch(AuthenticationExceptionae){//unexpectedcondition?error?}}//saywhotheyare://printtheiridentifyingprincipal(inthiscase,ausername):log.info("User["+currentUser.getPrincipal()+"]loggedinsuccessfully.");//testarole:if(currentUser.hasRole("schwartz")){log.info("MaytheSchwartzbewithyou!");}else{log.info("Hello,meremortal.");}//testatypedpermission(notinstance-level)if(currentUser.isPermitted("lightsaber:wield")){log.info("Youmayusealightsaberring.Useitwisely.");}else{log.info("Sorry,lightsaberringsareforschwartzmastersonly.");}//a(verypowerful)InstanceLevelpermission:if(currentUser.isPermitted("winnebago:drive:eagle5")){log.info("Youarepermittedto'drive'thewinnebagowithlicenseplate(id)'eagle5'."+"Herearethekeys-havefun!");}else{log.info("Sorry,youaren'tallowedtodrivethe'eagle5'winnebago!");}//alldone-logout!currentUser.logout();//注销System.exit(0);//退出}}

启动测试

SpringBoot-Shiro整合(最后会附上完整代码)

前期工作

导入shiro-spring整合包依赖

<!--shiro-spring整合包--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.7.1</version></dependency>

跳转的页面
index.html

<htmllang="en"xmlns:th="http://www.w3.org/1999/xhtml"><head><metacharset="UTF-8"><title>首页</title></head><body><h2>首页</h2><pth:text="${msg}"></p><ath:href="@{/user/add}"rel="externalnofollow"rel="externalnofollow"rel="externalnofollow">add</a>|<ath:href="@{/user/update}"rel="externalnofollow"rel="externalnofollow"rel="externalnofollow">update</a></body></html>

add.html

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>add</title></head><body><p>add</p></body></html>

update.html

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>update</title></head><body><p>update</p></body></html>

编写shiro的配置类ShiroConfig.java

packagecom.example.config;importorg.apache.shiro.spring.web.ShiroFilterFactoryBean;importorg.apache.shiro.web.mgt.DefaultWebSecurityManager;importorg.springframework.beans.factory.annotation.Qualifier;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjava.util.LinkedHashMap;importjava.util.Map;@ConfigurationpublicclassShiroConfig{//3.ShiroFilterFactoryBean@BeanpublicShiroFilterFactoryBeangetshiroFilterFactoryBean(@Qualifier("SecurityManager")DefaultWebSecurityManagerdefaultWebSecurityManager){ShiroFilterFactoryBeanfactoryBean=newShiroFilterFactoryBean();//设置安全管理器factoryBean.setSecurityManager(defaultWebSecurityManager);returnfactoryBean;}//2.创建DefaultWebSecurityManager@Bean(name="SecurityManager")publicDefaultWebSecurityManagergetDefaultWebSecurityManager(@Qualifier("userRealm")UserRealmuserRealm){DefaultWebSecurityManagerSecurityManager=newDefaultWebSecurityManager();//3.关联RealmSecurityManager.setRealm(userRealm);returnSecurityManager;}//1.创建Realm对象@Bean(name="userRealm")publicUserRealmuserRealm(){returnnewUserRealm();}}

编写UserRealm.java

packagecom.example.config;importorg.apache.shiro.authc.AuthenticationException;importorg.apache.shiro.authc.AuthenticationInfo;importorg.apache.shiro.authc.AuthenticationToken;importorg.apache.shiro.authz.AuthorizationInfo;importorg.apache.shiro.realm.AuthorizingRealm;importorg.apache.shiro.subject.PrincipalCollection;publicclassUserRealmextendsAuthorizingRealm{@OverrideprotectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipalCollection){System.out.println("授权");returnnull;}@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthenticationToken)throwsAuthenticationException{System.out.println("认证");returnnull;}}

编写controller测试环境是否搭建好

packagecom.example.controller;importorg.springframework.stereotype.Controller;importorg.springframework.ui.Model;importorg.springframework.web.bind.annotation.RequestMapping;@ControllerpublicclassMyController{@RequestMapping({"/","/index"})publicStringindex(Modelmodel){model.addAttribute("msg","hello,shiro");return"index";}@RequestMapping("/user/add")publicStringadd(){return"user/add";}@RequestMapping("/user/update")publicStringupdate(){return"user/update";}}


实现登录拦截

在ShiroConfig.java文件中添加拦截

Map<String,String>filterMap=newLinkedHashMap<>();//对/user/*下的文件只有拥有authc权限的才能访问filterMap.put("/user/*","authc");//将Map存放到ShiroFilterFactoryBean中factoryBean.setFilterChainDefinitionMap(filterMap);

这样,代码跑起来,你点击add或者update就会出现404错误,这时候,我们再继续添加,让它跳转到我们自定义的登录页

添加登录拦截到登录页

//需进行权限认证时跳转到toLoginfactoryBean.setLoginUrl("/toLogin");//权限认证失败时跳转到unauthorizedfactoryBean.setUnauthorizedUrl("/unauthorized");

login.html

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>登录</title></head><body><formaction="">用户名:<inputtype="text"name="username"><br>密码:<inputtype="text"name="password"><br><inputtype="submit"></form></body></html>

视图跳转添加一个login页面跳转

@RequestMapping("/toLogin")publicStringlogin(){return"login";}

上面,我们已经成功拦截了,现在我们来实现用户认证

首先,我们需要一个登录页面

login.html

<!DOCTYPEhtml><htmllang="en"xmlns:th="http://www.w3.org/1999/xhtml"><head><metacharset="UTF-8"><title>登录</title></head><body><pth:text="${msg}"></p><formth:action="@{/login}">用户名:<inputtype="text"name="username"><br>密码:<inputtype="text"name="password"><br><inputtype="submit"></form></body></html>

其次,去controller编写跳转到登录页面

@RequestMapping("/login")publicStringlogin(Stringusername,Stringpassword,Modelmodel){//获得当前的用户Subjectsubject=SecurityUtils.getSubject();//封装用户数据UsernamePasswordTokentaken=newUsernamePasswordToken(username,password);try{//执行登陆操作,没有发生异常就说明登陆成功subject.login(taken);return"index";}catch(UnknownAccountExceptione){model.addAttribute("msg","用户名错误");return"login";}catch(IncorrectCredentialsExceptione){model.addAttribute("msg","密码错误");return"login";}}

最后去UserRealm.java配置认证

//认证@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthenticationToken)throwsAuthenticationException{System.out.println("认证");Stringname="root";Stringpassword="123456";UsernamePasswordTokenuserToken=(UsernamePasswordToken)authenticationToken;if(!userToken.getUsername().equals(name)){returnnull;//抛出异常用户名错误那个异常}//密码认证,shiro自己做returnnewSimpleAuthenticationInfo("",password,"");}

运行测试,成功!!!

附上最后的完整代码

pom.xml引入的依赖

pom.xml

<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.4</version><relativePath/><!--lookupparentfromrepository--></parent><groupId>com.example</groupId><artifactId>springboot-08-shiro</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-08-shiro</name><description>DemoprojectforSpringBoot</description><properties><java.version>1.8</java.version></properties><dependencies><!--shiro-spring整合包--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.7.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

静态资源

index.html

<htmllang="en"xmlns:th="http://www.w3.org/1999/xhtml"><head><metacharset="UTF-8"><title>首页</title></head><body><h2>首页</h2><pth:text="${msg}"></p><ath:href="@{/user/add}"rel="externalnofollow"rel="externalnofollow"rel="externalnofollow">add</a>|<ath:href="@{/user/update}"rel="externalnofollow"rel="externalnofollow"rel="externalnofollow">update</a></body></html>

login.html

<!DOCTYPEhtml><htmllang="en"xmlns:th="http://www.w3.org/1999/xhtml"><head><metacharset="UTF-8"><title>登录</title></head><body><pth:text="${msg}"></p><formth:action="@{/login}">用户名:<inputtype="text"name="username"><br>密码:<inputtype="text"name="password"><br><inputtype="submit"></form></body></html>

add.html

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>add</title></head><body><p>add</p></body></html>

update.html

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>update</title></head><body><p>update</p></body></html>

controller层

MyController.java

packagecom.example.controller;importorg.apache.shiro.SecurityUtils;importorg.apache.shiro.authc.IncorrectCredentialsException;importorg.apache.shiro.authc.UnknownAccountException;importorg.apache.shiro.authc.UsernamePasswordToken;importorg.apache.shiro.subject.Subject;importorg.springframework.stereotype.Controller;importorg.springframework.ui.Model;importorg.springframework.web.bind.annotation.RequestMapping;@ControllerpublicclassMyController{@RequestMapping({"/","/index"})publicStringindex(Modelmodel){model.addAttribute("msg","hello,shiro");return"index";}@RequestMapping("/user/add")publicStringadd(){return"user/add";}@RequestMapping("/user/update")publicStringupdate(){return"user/update";}@RequestMapping("/toLogin")publicStringtoLogin(){return"login";}@RequestMapping("/login")publicStringlogin(Stringusername,Stringpassword,Modelmodel){//获得当前的用户Subjectsubject=SecurityUtils.getSubject();//封装用户数据UsernamePasswordTokentaken=newUsernamePasswordToken(username,password);try{//执行登陆操作,没有发生异常就说明登陆成功subject.login(taken);return"index";}catch(UnknownAccountExceptione){model.addAttribute("msg","用户名错误");return"login";}catch(IncorrectCredentialsExceptione){model.addAttribute("msg","密码错误");return"login";}}}

config文件

ShiroConfig.java

packagecom.example.config;importorg.apache.shiro.spring.web.ShiroFilterFactoryBean;importorg.apache.shiro.web.mgt.DefaultWebSecurityManager;importorg.springframework.beans.factory.annotation.Qualifier;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjava.util.LinkedHashMap;importjava.util.Map;@ConfigurationpublicclassShiroConfig{//4.ShiroFilterFactoryBean@BeanpublicShiroFilterFactoryBeangetshiroFilterFactoryBean(@Qualifier("SecurityManager")DefaultWebSecurityManagerdefaultWebSecurityManager){ShiroFilterFactoryBeanfactoryBean=newShiroFilterFactoryBean();//5.设置安全管理器factoryBean.setSecurityManager(defaultWebSecurityManager);/*shiro内置过滤器anon无需授权、登录就可以访问,所有人可访。authc需要登录授权才能访问。authcBasicBasicHTTP身份验证拦截器logout退出拦截器。退出成功后,会redirect到设置的/URInoSessionCreation不创建会话连接器perms授权拦截器,拥有对某个资源的权限才可访问port端口拦截器restrest风格拦截器roles角色拦截器,拥有某个角色的权限才可访问sslssl拦截器。通过https协议才能通过user用户拦截器,需要有rememberme功能方可使用*/Map<String,String>filterMap=newLinkedHashMap<>();//对/user/*下的文件只有拥有authc权限的才能访问filterMap.put("/user/*","authc");//将Map存放到ShiroFilterFactoryBean中factoryBean.setFilterChainDefinitionMap(filterMap);//需进行权限认证时跳转到toLoginfactoryBean.setLoginUrl("/toLogin");//权限认证失败时跳转到unauthorizedfactoryBean.setUnauthorizedUrl("/unauthorized");returnfactoryBean;}//2.创建DefaultWebSecurityManager@Bean(name="SecurityManager")publicDefaultWebSecurityManagergetDefaultWebSecurityManager(@Qualifier("userRealm")UserRealmuserRealm){DefaultWebSecurityManagerSecurityManager=newDefaultWebSecurityManager();//3.关联RealmSecurityManager.setRealm(userRealm);returnSecurityManager;}//1.创建Realm对象@Bean(name="userRealm")publicUserRealmuserRealm(){returnnewUserRealm();}}

UserRealm.java

packagecom.example.config;importorg.apache.shiro.authc.*;importorg.apache.shiro.authz.AuthorizationInfo;importorg.apache.shiro.realm.AuthorizingRealm;importorg.apache.shiro.subject.PrincipalCollection;publicclassUserRealmextendsAuthorizingRealm{//授权@OverrideprotectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipalCollection){System.out.println("授权");returnnull;}//认证@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthenticationToken)throwsAuthenticationException{System.out.println("认证");Stringname="root";Stringpassword="123456";UsernamePasswordTokenuserToken=(UsernamePasswordToken)authenticationToken;if(!userToken.getUsername().equals(name)){returnnull;//抛出异常用户名错误那个异常}//密码认证,shiro自己做returnnewSimpleAuthenticationInfo("",password,"");}}

但是,我们在用户认证这里,真实情况是从数据库中取的,所以,我们接下来去实现一下从数据库中取出数据来实现用户认证

Shiro整合mybatis

前期工作

在前面导入的依赖中,继续添加以下依赖

<!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--log4j--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><!--数据源Druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.5</version></dependency><!--引入mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>

导入了mybatis和Druid,就去application.properties配置一下和Druid
Druid

spring:datasource:username:rootpassword:123456url:jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8driver-class-name:com.mysql.cj.jdbc.Drivertype:com.alibaba.druid.pool.DruidDataSource#自定义数据源#SpringBoot默认是不注入这些属性值的,需要自己绑定#druid数据源专有配置initialSize:5minIdle:5maxActive:20maxWait:60000timeBetweenEvictionRunsMillis:60000minEvictableIdleTimeMillis:300000validationQuery:SELECT1FROMDUALtestWhileIdle:truetestOnBorrow:falsetestOnReturn:falsepoolPreparedStatements:true#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入#如果允许时报错java.lang.ClassNotFoundException:org.apache.log4j.Priority#则导入log4j依赖即可,Maven地址:https://mvnrepository.com/artifact/log4j/log4jfilters:stat,wall,log4jmaxPoolPreparedStatementPerConnectionSize:20useGlobalDataSourceStat:trueconnectionProperties:druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

mybatis

mybatis:type-aliases-package:com.example.pojomapper-locations:classpath:mapper/*.xml

连接数据库
编写实体类

packagecom.example.pojo;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructorpublicclassUser{privateIntegerid;privateStringname;privateStringpwd;}

编写mapper

packagecom.example.mapper;importcom.example.pojo.User;importorg.apache.ibatis.annotations.Mapper;importorg.springframework.stereotype.Repository;@Repository@MapperpublicinterfaceUserMapper{publicUsergetUserByName(Stringname);}

编写mapper.xml

<?xmlversion="1.0"encoding="UTF8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="com.example.mapper.UserMapper"><selectid="getUserByName"parameterType="String"resultType="User">select*frommybatis.userwherename=#{name}</select></mapper>

编写service

packagecom.example.service;importcom.example.pojo.User;publicinterfaceUserService{publicUsergetUserByName(Stringname);}

packagecom.example.service;importcom.example.mapper.UserMapper;importcom.example.pojo.User;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;@ServicepublicclassUserServiceImplimplementsUserService{@AutowiredUserMapperuserMapper;@OverridepublicUsergetUserByName(Stringname){returnuserMapper.getUserByName(name);}}

使用数据库中的数据

修改UserRealm.java即可

packagecom.example.config;importcom.example.pojo.User;importcom.example.service.UserService;importorg.apache.shiro.authc.*;importorg.apache.shiro.authz.AuthorizationInfo;importorg.apache.shiro.realm.AuthorizingRealm;importorg.apache.shiro.subject.PrincipalCollection;importorg.springframework.beans.factory.annotation.Autowired;publicclassUserRealmextendsAuthorizingRealm{@AutowiredUserServiceuserService;//授权@OverrideprotectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipalCollection){System.out.println("授权");returnnull;}//认证@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthenticationToken)throwsAuthenticationException{System.out.println("认证");UsernamePasswordTokenuserToken=(UsernamePasswordToken)authenticationToken;//连接真实的数据库Useruser=userService.getUserByName(userToken.getUsername());if(user==null){returnnull;//抛出异常用户名错误那个异常}//密码认证,shiro自己做returnnewSimpleAuthenticationInfo("",user.getPwd(),"");}}认证搞完了,我们再来看看授权

在ShiroConfig.java文件加入授权,加入这行代码: filterMap.put("/user/add","perms[user:add]");//只有拥有user:add权限的人才能访问add,注意授权的位置在认证前面,不然授权会认证不了;

运行测试:add页面无法访问

授权同理:filterMap.put("/user/update","perms[user:update]");//只有拥有user:update权限的人才能访问update

自定义一个未授权跳转页面

在ShiroConfig.java文件设置未授权时跳转到unauthorized页面,加入这行代码:
factoryBean.setUnauthorizedUrl("/unauthorized"); 2. 去Mycontroller写跳转未授权页面

@RequestMapping("/unauthorized")@ResponseBody//懒得写界面,返回一个字符串publicStringunauthorized(){return"没有授权,无法访问";}

在数据库中添加一个属性perms,相应的实体类也要修改

修改UserRealm.java

packagecom.example.config;importcom.example.pojo.User;importcom.example.service.UserService;importorg.apache.shiro.SecurityUtils;importorg.apache.shiro.authc.*;importorg.apache.shiro.authz.AuthorizationInfo;importorg.apache.shiro.authz.SimpleAuthorizationInfo;importorg.apache.shiro.realm.AuthorizingRealm;importorg.apache.shiro.subject.PrincipalCollection;importorg.apache.shiro.subject.Subject;importorg.springframework.beans.factory.annotation.Autowired;publicclassUserRealmextendsAuthorizingRealm{@AutowiredUserServiceuserService;//授权@OverrideprotectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipalCollection){System.out.println("授权");SimpleAuthorizationInfoinfo=newSimpleAuthorizationInfo();//没有使用数据库,直接自己设置的用户权限,给每个人都设置了,现实中要从数据库中取//info.addStringPermission("user:add");//从数据库中得到权限信息//获得当前登录的对象Subjectsubject=SecurityUtils.getSubject();//拿到User对象,通过getPrincipal()获得UsercurrentUser=(User)subject.getPrincipal();//设置当前用户的权限info.addStringPermission(currentUser.getPerms());returninfo;}//认证@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthenticationToken)throwsAuthenticationException{System.out.println("认证");UsernamePasswordTokenuserToken=(UsernamePasswordToken)authenticationToken;//连接真实的数据库Useruser=userService.getUserByName(userToken.getUsername());if(user==null){returnnull;//抛出异常用户名错误那个异常}//密码认证,shiro自己做returnnewSimpleAuthenticationInfo(user,user.getPwd(),"");}}

有了授权后,就又出现了一个问题,我们是不是要让用户没有权限的东西,就看不见呢?这时候,就出现了Shiro-thymeleaf整合

Shiro-thymeleaf整合

导入整合的依赖

<!--https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro--><dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>2.0.0</version></dependency>

在ShiroConfig整合ShiroDialect

//整合ShiroDialect:用来整合shirothymeleaf@BeanpublicShiroDialectgetShiroDialect(){returnnewShiroDialect();}

修改index页面

<htmllang="en"xmlns:th="http://www.thymeleaf.org"xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro"><!--三个命名空间xmlns:th="http://www.thymeleaf.org"xmlns:sec="http://www.thymeleaf.org/extras/spring-security"xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro"--><head><metacharset="UTF-8"><title>首页</title></head><body><h2>首页</h2><pth:text="${msg}"></p><!--判断是否有用户登录,如果有就不显示登录按钮--><divth:if="${session.loginUser==null}"><ath:href="@{/toLogin}"rel="externalnofollow">登录</a></div><divshiro:hasPermission="user:add"><ath:href="@{/user/add}"rel="externalnofollow"rel="externalnofollow"rel="externalnofollow">add</a></div><divshiro:hasPermission="user:update"><ath:href="@{/user/update}"rel="externalnofollow"rel="externalnofollow"rel="externalnofollow">update</a></div></body></html>

判断是否有用户登录

//这个是整合shiro和thymeleaf用到的,让登录按钮消失的判断Subjectsubject=SecurityUtils.getSubject();Sessionsession=subject.getSession();session.setAttribute("loginUser",user);

测试

感谢各位的阅读,以上就是“Java安全框架Shiro怎么使用”的内容了,经过本文的学习后,相信大家对Java安全框架Shiro怎么使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!