Java中Apache Shiro安全框架怎么用(apache,java,shiro,开发技术)

时间:2024-05-02 21:41:30 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

    一、Shiro简介:

    Apache Shiro是一个Java的安全(权限)框架。
    Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以完成,认证,授权,加密,会话管理,Web集成,缓存等。

    Java中Apache Shiro安全框架怎么用

    shiro功能:

    Java中Apache Shiro安全框架怎么用

    Authentication:身份认证、登录,验证用户是不是拥有相应的身份;
    Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限,即判断用户能否进行什么操作,如:验证某个用户是否拥有某个角色,或者细粒度的验证某个用户对某个资源是否具有某个权限!
    Session Manager:会话管理,即用户登录后就是第一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通的JavaSE环境,也可以是Web环境;
    Cryptography:加密,保护数据的安全性,如密码加密存储到数据库中,而不是明文存储;Web Support: Web支持,可以非常容易的集成到Web环境;
    Caching:缓存,比如用户登录后,其用户信息,拥有的角色、权限不必每次去查,这样可以提高效率
    Concurrency: Shiro支持多线程应用的并发验证,即,如在一个线程中开启另一个线程,能把权限自动的传播过去
    Testing:提供测试支持;
    Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
    Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了

    Shiro架构(外部)

    从外部来看Shiro,即从应用程序角度来观察如何使用shiro完成工作:

    Java中Apache Shiro安全框架怎么用

    subject:应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject,Subject代表了当前的用户,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等,与Subject的所有交互都会委托给SecurityManager; Subject其实是一个门面,SecurityManageer才是实际的执行者
    SecurityManager: 安全管理器,即所有与安全有关的操作都会与SercurityManager交互,并且它管理着所有的Subject,可以看出它是Shiro的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMVC的
    DispatcherServlet的角色
    Realm: Shiro从Realm获取安全数据((如用户,角色,权限),就是说SecurityManager要验证用户身份,那么它需要从Realm 获取相应的用户进行比较,来确定用户的身份是否合法;也需要从Realm得到用户相应的角色、权限,进行验证用户的操作是否能够进行,可以把Realm看成DataSource;

    Shiro架构(内部)

    Java中Apache Shiro安全框架怎么用

    subject:任何可以与应用交互的'用户';
    Security Manager:相当于SpringMVC中的DispatcherServlet;是Shiro的心脏,所有具体的交互都通过Security Manager进行控制,它管理者所有的Subject,且负责进行认证,授权,会话,及缓存的管理.

    Authenticator:负责Subject认证,是一个扩展点,可以自定义实现;可以使用认证策略(AuthenticationStrategy),即什么情况下算用户认证通过了;
    Authorizer: 授权器,即访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的那些功能;
    Realm:可以有一个或者多个的realm,可以认为是安全实体数据源,即用于获取安全实体的,可以用DBC实现,也可以是内存实现等等,由用户提供;所以一般在应用中都需要实现自己的realm
    SessionManager: 管理Session生命周期的组件,而Shiro并不仅仅可以用在Web环境,也可以用在普通的JavaSE环境中
    CacheManager:缓存控制器,来管理如用户,角色,权限等缓存的;因为这些数据基本上很少以受,成到缓存中后可以提高访问的性能;
    Cryptography:密码模块,Shiro提高了一些常见的加密组件用于密码加密,解密等

    二、快速入门

    1.拷贝案例

    1.按照官网提示找到 快速入门案例 GitHub地址:shiro/samples/quickstart/

    Java中Apache Shiro安全框架怎么用

    2.新建一个 Maven 工程,删除其 src 目录,将其作为父工程

    3.在父工程中新建一个 Maven 模块

    4.复制快速入门案例 POM.xml 文件中的依赖

    <dependencies><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.4.1</version></dependency><!--configurelogging--><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>1.7.29</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.29</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies>

    5.把快速入门案例中的 resource 下的log4j.properties复制下来

    6.复制一下shiro.ini文件

    7.复制一下Quickstart.java文件

    8.运行启动Quickstart.java

    Java中Apache Shiro安全框架怎么用

    2.分析代码

    publicclassQuickstart{privatestaticfinaltransientLoggerlog=LoggerFactory.getLogger(Quickstart.class);publicstaticvoidmain(String[]args){//工厂模式,通过shiro.ini配置文件中的信息,生成一个工厂实例Factory<SecurityManager>factory=newIniSecurityManagerFactory("classpath:shiro.ini");SecurityManagersecurityManager=factory.getInstance();SecurityUtils.setSecurityManager(securityManager);//获取当前的用户对象SubjectSubjectcurrentUser=SecurityUtils.getSubject();//通过当前用户拿到sessionSessionsession=currentUser.getSession();session.setAttribute("someKey","aValue");Stringvalue=(String)session.getAttribute("someKey");if(value.equals("aValue")){log.info("Subject=>session["+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){//意外情况?错误?}}//打印其标识主体(在这种情况下,为用户名)log.info("User["+currentUser.getPrincipal()+"]loggedinsuccessfully.");//测试角色是否存在if(currentUser.hasRole("schwartz")){log.info("MaytheSchwartzbewithyou!");}else{log.info("Hello,meremortal.");}//粗粒度,极限范围小//测试类型化的极限(不是实例级别)if(currentUser.isPermitted("lightsaber:wield")){log.info("Youmayusealightsaberring.Useitwisely.");}else{log.info("Sorry,lightsaberringsareforschwartzmastersonly.");}//细粒度,极限范围广//实例级别的权限(非常强大)if(currentUser.isPermitted("winnebago:drive:eagle5")){log.info("Youarepermittedto'drive'thewinnebagowithlicenseplate(id)'eagle5'."+"Herearethekeys-havefun!");}else{log.info("Sorry,youaren'tallowedtodrivethe'eagle5'winnebago!");}//注销currentUser.logout();//退出System.exit(0);}}

    三、SpringBoot 集成 Shiro

    1.编写测试环境

    1.在刚刚的父项目中新建一个 springboot 模块

    Java中Apache Shiro安全框架怎么用

    2.导入 SpringBoot 和 Shiro 整合包的依赖

    <!--SpringBoot和Shiro整合包--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.1</version></dependency>

    下面是编写配置文件
    Shiro 三大要素

    Subject 用户 -> ShiroFilterFactoryBean
    SecurityManager 管理所有用户 -> DefaultWebSecurityManager
    Realm 连接数据

    实际操作中对象创建的顺序 : realm -> securityManager -> subject

    3.编写自定义的 realm ,需要继承 AuthorizingRealm

    //自定义的UserRealmextendsAuthorizingRealmpublicclassUserRealmextendsAuthorizingRealm{//授权@OverrideprotectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipalCollection){//打印一个提示System.out.println("执行了授权方法");returnnull;}//认证@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthenticationToken)throwsAuthenticationException{//打印一个提示System.out.println("执行了认证方法");returnnull;}}

    4.新建一个ShiroConfig配置文件

    @ConfigurationpublicclassShiroConfig{//ShiroFilterFactoryBean:3@BeanpublicShiroFilterFactoryBeangetShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManagerdefaultWebsecurityManager){ShiroFilterFactoryBeanbean=newShiroFilterFactoryBean();//设置安全管理器bean.setSecurityManager(defaultWebsecurityManager);returnbean;}//DefaultWebSecurityManager:2@Bean(name="securityManager")publicDefaultWebSecurityManagergetDefaultWebSecurityManager(@Qualifier("userRealm")UserRealmuserRealm){DefaultWebSecurityManagersecurityManager=newDefaultWebSecurityManager();//关闭UserRealmsecurityManager.setRealm(userRealm);returnsecurityManager;}//创建realm对象,需要自定义类:1@Bean(name="userRealm")publicUserRealmuserRealm(){returnnewUserRealm();}}

    5.测试成功!

    Java中Apache Shiro安全框架怎么用

    2.使用

    1.登录拦截

    在getShiroFilterFactoryBean方法中添加需要拦截的登录请求

    @ConfigurationpublicclassShiroConfig{//ShiroFilterFactoryBean:3@BeanpublicShiroFilterFactoryBeangetShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManagerdefaultWebsecurityManager){ShiroFilterFactoryBeanbean=newShiroFilterFactoryBean();//设置安全管理器bean.setSecurityManager(defaultWebsecurityManager);//添加shiro的内置过滤器/*anon:无需认证,就可以访问authc:必须认证了才能访问user:必须拥有“记住我”功能才能用perms:拥有对某个资源的权限才能访问role:拥有某个角色权限才能访问*/filterMap.put("/user/add","authc");filterMap.put("/user/update","authc");//拦截Map<String,String>filterMap=newLinkedHashMap<>();filterMap.put("/user/*","authc");bean.setFilterChainDefinitionMap(filterMap);////设置登录的请求//bean.setLoginUrl("/toLogin");returnbean;}

    测试:点击 add链接,不会跳到 add 页面,而是跳到登录页,拦截成功

    Java中Apache Shiro安全框架怎么用

    2.用户认证

    1.在Controller层写一个登录的方法

    //登录的方法@RequestMapping("/login")publicStringlogin(Stringusername,Stringpassword,Modelmodel){//获取当前用户Subjectsubject=SecurityUtils.getSubject();//封装用户的登录数据,获得令牌UsernamePasswordTokentoken=newUsernamePasswordToken(username,password);//登录及异常处理try{//执行用户登录的方法,如果没有异常就说明OK了subject.login(token);return"index";}catch(UnknownAccountExceptione){//如果用户名不存在System.out.println("用户名不存在");model.addAttribute("msg","用户名错误");return"login";}catch(IncorrectCredentialsExceptionice){//如果密码错误System.out.println("密码错误");model.addAttribute("msg","密码错误");return"login";}}}

    2.测试

    Java中Apache Shiro安全框架怎么用

    可以看出是先执行了自定义的UserRealm中的AuthenticationInfo方法,再执行登录相关的操作

    3.修改UserRealm中的doGetAuthenticationInfo方法

    //认证@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthenticationToken)throwsAuthenticationException{//打印一个提示System.out.println("执行了认证方法");//用户名密码Stringname="root";Stringpassword="123456";//通过参数获取登录的控制器中生成的令牌UsernamePasswordTokentoken=(UsernamePasswordToken)authenticationToken;//用户名认证if(!token.getUsername().equals(name)){//returnnullUnKnownAccountExceptionreturnnull;}//密码认证,Shiro自己做,为了避免和密码的接触//最后返回一个AuthenticationInfo接口的实现类,这里选择SimpleAuthenticationInfo//三个参数:获取当前用户的认证;密码;认证名returnnewSimpleAuthenticationInfo("",password,"");}}

    4.测试,输入错误的密码

    Java中Apache Shiro安全框架怎么用

    Java中Apache Shiro安全框架怎么用

    输入正确的密码,即可登录成功

    四、Shiro整合Mybatis

    1.导入依赖

    <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.19</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.12</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.1</version></dependency>

    2.新建个application.yml

    spring:datasource:username:rootpassword:123456url:jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTCdriver-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=500mybatis:type-aliases-package:com.huang.pojomapper-locations:classpath:mybatis/mapper/*.xml

    3.在application.properties

    mybatis.type-aliases-package=com.longdi.pojomybatis.mapper-locations=classpath:mapper/*.xml

    4.导入依赖

    <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version><scope>provided</scope></dependency>

    5.编写User类

    @Data@AllArgsConstructor@NoArgsConstructorpublicclassUser{privateintid;privateStringname;privateStringpwd;privateStringperms;}

    6.编写UserMapper

    @Repository@MapperpublicinterfaceUserMapper{publicUserqueryUserByName(Stringname);}

    7.编写UserMapper.xml

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

    8.Service层

    UserService接口:

    publicinterfaceUserService{publicUserqueryUserByName(Stringname);}

    9.编写接口实现类UserServiceImpl

    @ServicepublicclassUserServiceImplimplementsUserService{@AutowiredUserMapperuserMapper;@OverridepublicUserqueryUserByName(Stringname){returnuserMapper.queryUserByName(name);}}

    10.在ShiroSpringbootApplicationTests测试

    @SpringBootTestclassShiroSpringbootApplicationTests{@AutowiredUserServiceImpluserService;@TestvoidcontextLoads(){System.out.println(userService.queryUserByName("longdi"));}}

    11.成功连接数据库

    五、实现请求授权

    1.在ShiroConfig类中修改

    Java中Apache Shiro安全框架怎么用

    2.controller跳转

    Java中Apache Shiro安全框架怎么用

    3.登录拦截授权,测试成功

    Java中Apache Shiro安全框架怎么用

    Java中Apache Shiro安全框架怎么用

    4.编写授权doGetAuthorizationInfo方法

    Java中Apache Shiro安全框架怎么用

    5.请求授权测试成功

    六、Shiro整合Thymeleaf

    1.导入依赖

    <!--shiro和thymeleaf整合--><dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>2.0.0</version></dependency>

    2.整合ShiroDialect

    Java中Apache Shiro安全框架怎么用

    3.index.html

    Java中Apache Shiro安全框架怎么用

    4.测试

    Java中Apache Shiro安全框架怎么用

    5.在认证里放session

    Java中Apache Shiro安全框架怎么用

    6.修改index.html

    Java中Apache Shiro安全框架怎么用

     </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
    本文:Java中Apache Shiro安全框架怎么用的详细内容,希望对您有所帮助,信息来源于网络。
    上一篇:spring boot怎么整合activiti下一篇:

    4 人围观 / 0 条评论 ↓快速评论↓

    (必须)

    (必须,保密)

    阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18