目录

1.运用shiro进行用户身份认证:

1.1导入基于Shiro的数据库脚本

1.2.引入依赖(shiro-1.4.1)

shiro-core  shiro-web  shiro-spring

1.3.自定义Realm

1.4.Spring与Shiro集成

1) 配置自定义Realm

2) 注册安全管理器

3) 配置Shiro核心过滤器

4) 配置Shiro生命周期

5.修改web.xml文件,添加shiroFilter的配置

1.6.实现Shiro身份认证登录

1.7.盐加密

7.1 生成加密密码PasswordHelper类(盐加密)    MD5+散列1024+Hex/Base64

7.2 修改applicationContext-shirod的自定义Realm配置,增加以下:

2.用户授权

2.1.添加角色和权限的授权方法

2.2.自定义Realm配置Shiro授权认证

1) 获取验证身份(用户名)  2) 根据身份(用户名)获取角色和权限信息  3) 将角色和权限信息设置到SimpleAuthorizationInfo

2.3.使用Shiro标签实现权限验证

2.3.1 导入Shiro标签库

2.3.2 Shiro标签库

2.4.配置注解权限验证

2.4.1 Shiro注解

2. 4.2 开启注解

2.4.3 注解权限验证失败不跳转路径问题


1.运用shiro进行用户身份认证:

重要:
        在 shiro 中,用户需要提供principals (身份)和credentials(凭证)给shiro,从而应用能验证用户身份
   即帐号/密码

1.1导入基于Shiro的数据库脚本

  t_sys_user:用户信息表,例如:zs,ls,ww
  t_sys_role:用户角色表,例如:普通员工、经理、CEO
  t_sys_permission 权限信息表,例如:做自己的工作、做自己的工作及管理整个部门,做自己的工作及管理这个公司
  t_sys_user_role 用户角色表
  t_sys_role_permission 角色权限表 (一个角色对应多个权限)

  关联关系:
        用户与角色         角色与权限
  用户--------------角色---------------权限

1.2.引入依赖(shiro-1.4.1)

shiro-core
  shiro-web
  shiro-spring

1.3.自定义Realm

Shiro从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。

最基础的是Realm接口,CachingRealm负责缓存处理,AuthenticationRealm负责认证,AuthorizingRealm负责授权。

通常自定义的realm继承AuthorizingRealm

注1:体系结构见“shiro提供的realm.png”

AuthorizationInfo:授权信息
  AuthenticationInfo:认证信息

1.4.Spring与Shiro集成

1) 配置自定义Realm(里面给了点提示)

  <bean id="shiroRealm" class="com.zking.ssm.book.shiro.ShiroRealm">//注入UserService实现类,通过账号密码登录时实现基于Shiro身份认证识别//盐加密算法配置</bean>

2) 注册安全管理器
  将自定义的Realm设置到Shiro的SecurityManager中,在Shiro授权和认证时使用自定义的Realm数据源进行校验

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="shiroRealm" /></bean>

3) 配置Shiro核心过滤器
  Shiro核心过滤器用于拦截请求,通过给定的授权认证机制对用户访问身份和权限进行认证识别
  “Shiro核心过滤器配置”:

​​​​/**
* Shiro过滤器配置
*/
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilter() {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
// Shiro的核心安全接口,这个属性是必须的
shiroFilter.setSecurityManager(securityManager());
// shiroFilter.setLoginUrl("");//身份认证失败,则跳转到登录页面的配置 没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面。
// shiroFilter.setSuccessUrl("");//登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,则在登录自动跳转到那个需要登录的页面。不跳转到此。
// shiroFilter.setUnauthorizedUrl("");//没有权限默认跳转的页面
// shiroFilter.setFilterChainDefinitions("");//filterChainDefinitions的配置顺序为自上而下,以最上面的为准//自定义过滤
//oauth2
Map<String, Filter> filters = new HashMap<>(16);
filters.put("oauth2", new Oauth2Filter());
shiroFilter.setFilters(filters);//当运行一个Web应用程序时,Shiro将会创建一些有用的默认Filter实例,并自动地在[main]项中将它们置为可用自动地可用的默认的Filter实例是被DefaultFilter枚举类定义的,枚举的名称字段就是可供配置的名称
/**
* anon---------------org.apache.shiro.web.filter.authc.AnonymousFilter 没有参数,表示可以匿名使用。
* authc--------------org.apache.shiro.web.filter.authc.FormAuthenticationFilter 表示需要认证(登录)才能使用,没有参数
* authcBasic---------org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter 没有参数表示httpBasic认证
* logout-------------org.apache.shiro.web.filter.authc.LogoutFilter
* noSessionCreation--org.apache.shiro.web.filter.session.NoSessionCreationFilter
* perms--------------org.apache.shiro.web.filter.authz.PermissionAuthorizationFilter 参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
* port---------------org.apache.shiro.web.filter.authz.PortFilter port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。
* rest---------------org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter 根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。
* roles--------------org.apache.shiro.web.filter.authz.RolesAuthorizationFilter 参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
* ssl----------------org.apache.shiro.web.filter.authz.SslFilter 没有参数,表示安全的url请求,协议为https
* user---------------org.apache.shiro.web.filter.authz.UserFilter 没有参数表示必须存在用户,当登入操作时不做检查
*//**
* 通常可将这些过滤器分为两组
* anon,authc,authcBasic,user是第一组认证过滤器
* perms,port,rest,roles,ssl是第二组授权过滤器
* 注意user和authc不同:当应用开启了rememberMe时,用户下次访问时可以是一个user,但绝不会是authc,因为authc是需要重新认证的
* user表示用户不一定已通过认证,只要曾被Shiro记住过登录状态的用户就可以正常发起请求,比如rememberMe 说白了,以前的一个用户登录时开启了rememberMe,然后他关闭浏览器,下次再访问时他就是一个user,而不会authc
*
*
* 举几个例子
* /admin=authc,roles[admin] 表示用户必需已通过认证,并拥有admin角色才可以正常发起'/admin'请求
* /edit=authc,perms[admin:edit] 表示用户必需已通过认证,并拥有admin:edit权限才可以正常发起'/edit'请求
* /home=user 表示用户不一定需要已经通过认证,只需要曾经被Shiro记住过登录状态就可以正常发起'/home'请求
*//**
* 各默认过滤器常用如下(注意URL Pattern里用到的是两颗星,这样才能实现任意层次的全匹配)
* /admins/**=anon 无参,表示可匿名使用,可以理解为匿名用户或游客
* /admins/user/**=authc 无参,表示需认证才能使用
* /admins/user/**=authcBasic 无参,表示httpBasic认证
* /admins/user/**=ssl 无参,表示安全的URL请求,协议为https
* /admins/user/**=perms[user:add:*] 参数可写多个,多参时必须加上引号,且参数之间用逗号分割,如/admins/user/**=perms["user:add:*,user:modify:*"]。当有多个参数时必须每个参数都通过才算通过,相当于isPermitedAll()方法
* /admins/user/**=port[8081] 当请求的URL端口不是8081时,跳转到schemal://serverName:8081?queryString。其中schmal是协议http或https等,serverName是你访问的Host,8081是Port端口,queryString是你访问的URL里的?后面的参数
* /admins/user/**=rest[user] 根据请求的方法,相当于/admins/user/**=perms[user:method],其中method为post,get,delete等
* /admins/user/**=roles[admin] 参数可写多个,多个时必须加上引号,且参数之间用逗号分割,如:/admins/user/**=roles["admin,guest"]。当有多个参数时必须每个参数都通过才算通过,相当于hasAllRoles()方法
*
*///Shiro验证URL时,URL匹配成功便不再继续匹配查找(所以要注意配置文件中的URL顺序,尤其在使用通配符时)
// 配置不会被拦截的链接 顺序判断
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/favicon.ico", "anon");
filterMap.put("/webjars/**", "anon");
filterMap.put("/web/**", "anon");
filterMap.put("/login", "anon");//所有请求需要oauth2认证
filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap);
return shiroFilter;
}
spring中 shiro logout 配置方式1. 普通的 实现自己的logout方法,取到Subject,然后logout。2. 使用shiro提供的logout filter

filterChainDefinitions Shiro过滤链定义类型:
  (1) anon,authcBasic,auchc,user是认证过滤器 
  (2) perms,roles,ssl,rest,port是授权过滤器

<!--anon 表示匿名访问,不需要认证以及授权-->
  <!--authc表示需要认证 没有进行身份认证是不能进行访问的-->
  <!--roles[admin]表示角色认证,必须是拥有admin角色的用户才行-->
  <!--user表示用户不一定已通过认证,只要曾被Shiro记住过登录状态的用户就可以正常发起请求,比如rememberMe-->
  <!--perms表示指定过滤规则,这个一般是扩展使用,不会使用原生的-->
  <!--port表示请求的URL端口验证-->
  <!--ssl表示安全的URL请求,协议为https-->
  <!--rest表示根据请求的方法,如post、get、delete等-->

4) 配置Shiro生命周期

  <!-- Shiro生命周期,保证实现了Shiro内部lifecycle函数的bean执行 --><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

5.修改web.xml文件,添加shiroFilter的配置

<filter><filter-name>shiroFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><init-param><param-name>tartgetFilterLifecycle</param-name><param-value>true</param-value></init-param>
</filter><filter-mapping><filter-name>shiroFilter</filter-name><url-pattren>*</url-pattern>
</filter-mapping>

   注:使用的代理类DelegatingFilterProxy

1.6.实现Shiro身份认证登录

//登录
@RequestMapping("/userLogin")
public String userLogin(@RequestParam(value = "username") String username,@RequestParam(value = "password") String password,Model model) {//获取当前用户Subject currentUser = SecurityUtils.getSubject();//当前用户的登录数据令牌UsernamePasswordToken currentUserToken = new UsernamePasswordToken(username, password);//设置记住我//currentUserToken.setRememberMe(true);try {//执行登录方法,如果没异常就okcurrentUser.login(currentUserToken);if (currentUser.isAuthenticated() == true) {//判断当前用户是否已经登录return "index";}} catch (UnknownAccountException uae) {model.addAttribute("msg", "用户不存在");return "login";} catch (IncorrectCredentialsException ice) {model.addAttribute("msg", "密码不正确");return "login";}return "index";
}//退出登录
@RequestMapping("/logout")
public String Logout(HttpServletResponse response) {Subject currentUser = SecurityUtils.getSubject();currentUser.logout();return "redirect:toLogin";
}

1.7.盐加密

//认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {System.out.println("执行认证操作");UsernamePasswordToken currentUserToken = (UsernamePasswordToken) authenticationToken;System.out.printf(currentUserToken.getPassword().toString());User u = new User();u.setUsername(currentUserToken.getUsername());//1.数据库拿数据User dataUser = sysUserDao.selectOne(u);if (dataUser == null){return null;  //抛出异常UnknownAccountException}else{Subject subject = SecurityUtils.getSubject();Session session = subject.getSession();session.setAttribute("currentUser",u);}//2.realmName:当前Realm对象的name。调用父类的getName()即可String realmeName = this.getName();//3.盐值ByteSource credentialsSalt = ByteSource.Util.bytes(dataUser.getUsername());//密码认证,由shiro自己做,防止密码泄露//涉及密码加密的,shiro有多种加密方式,如:MD5加密、MD5盐值加密。SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(dataUser, dataUser.getPassword(), credentialsSalt, realmeName);return simpleAuthenticationInfo; //此处返回的对象中的dataUser供授权方法获取}
}

7.1 生成加密密码PasswordHelper类(盐加密)
  
  MD5+散列1024+Hex/Base64

7.2 修改applicationContext-shirod的自定义Realm配置,增加以下:

 <!--配置Shiro明文密码如何进行加密--><!--注意:重要的事情说三次~~~~~~此处加密方式要与用户注册时的算法一致 --><!--以下三个配置告诉shiro将如何对用户传来的明文密码进行加密--><property name="credentialsMatcher"><bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"><!--指定hash算法为MD5--><property name="hashAlgorithmName" value="md5"/><!--指定散列次数为1024次--><property name="hashIterations" value="1024"/>    <!--true指定Hash散列值使用Hex加密存. false表明hash散列值用用Base64-encoded存储--><property name="storedCredentialsHexEncoded" value="true"/></bean></property>

2.用户授权

2.1.添加角色和权限的授权方法

//根据username查询该用户的所有角色,用于角色验证Set<String> findRoles(String username);//根据username查询他所拥有的权限信息,用于权限判断Set<String> findPermissions(String username);

授权:

 //授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println("执行授权操作");SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();Subject subject = SecurityUtils.getSubject();User currentUser = (User)subject.getPrincipal();  //获取当前用户对象,是认证方法中返回的参数User//设置当前对象的权限simpleAuthorizationInfo.addStringPermission(currentUser.getPermission()); //获取数据库里的权限return simpleAuthorizationInfo;}

2.2.自定义Realm配置Shiro授权认证

1) 获取验证身份(用户名)
  2) 根据身份(用户名)获取角色和权限信息
  3) 将角色和权限信息设置到SimpleAuthorizationInfo

SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();info.setRoles(roles);info.setStringPermissions(permissions);

2.3.使用Shiro标签实现权限验证

2.3.1 导入Shiro标签库

 <%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

2.3.2 Shiro标签库

  guest标签 :验证当前用户是否为“访客”,即未认证(包含未记住)的用户
  user标签 :认证通过或已记住的用户
 
authenticated标签 :已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在
  notAuthenticated标签 :未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户
 
principal 标签 :输出当前用户信息,通常为登录帐号信息 
  hasRole标签 :验证当前用户是否属于该角色 
 
lacksRole标签 :与hasRole标签逻辑相反,当用户不属于该角色时验证通过
  hasAnyRole标签 :验证当前用户是否属于以下任意一个角色
 
hasPermission标签 :验证当前用户是否拥有指定权限
  lacksPermission标签 :与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过 

2.4.配置注解权限验证

2.4.1 Shiro注解

@RequiresAuthenthentication:表示当前Subject已经通过login进行身份验证;即 Subjecj.isAuthenticated()返回 true
  @RequiresUser:表示当前Subject已经身份验证或者通过记住我登录的
  @RequiresGuest:表示当前Subject没有身份验证或者通过记住我登录过,即是游客身份
  @RequiresRoles(value = {"admin","user"},logical = Logical.AND):表示当前Subject需要角色admin和user
  @RequiresPermissions(value = {"user:delete","user:b"},logical = Logical.OR):表示当前Subject需要权限user:delete或者user:b

2. 4.2 开启注解
  
  注:
  必须将Shiro注解的开启放置到spring-mvc.xml中(即放在springMVC容器中加载),不然Shiro注解开启无效!!! 

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"depends-on="lifecycleBeanPostProcessor"><property name="proxyTargetClass" value="true"></property>
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager"/>
</bean>

2.4.3 注解权限验证失败不跳转路径问题

  问题原因:由于我们架构是用springmvc框架来搭建的所以项目的路径跳转是由springmvc 来控制的,也就是说我们在shiro里面的配置没有用

<!-- 身份验证成功,跳转到指定页面 --><property name="successUrl" value="/index.jsp"/>                //没有用,达不到预期效果<!-- 权限验证失败,跳转到指定页面 --><property name="unauthorizedUrl" value="/user/noauthorizeUrl"/> //没有用,达不到预期效果

  解决方案:
  springmvc中有一个org.springframework.web.servlet.handler.SimpleMappingExceptionResolver类就可以解决这个问题

  <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><property name="exceptionMappings"><props><prop key="org.apache.shiro.authz.UnauthorizedException">unauthorized</prop></props></property></bean>

shiro中的验证用户身份认证以及授权相关推荐

  1. Spring Security关于用户身份认证与授权

    Spring Security是用于解决认证与授权的框架. 创建spring项目,添加依赖 <!-- Spring Boot Security:处理认证与授权 --><depende ...

  2. 结合 Authing 实现 AWS 云上的身份认证与授权

    身份认证与 Cognito 服务介绍 在 Web 或 App 开发过程中,用户的认证和权限处理是非常重要的一个模块,这里包括用户注册.登录认证及管理对应的权限.除了用户名密码登录外,通过第三方社交帐号 ...

  3. java ladp用户认证_java – LDAP:如何使用连接详细信息验证用户身份

    我无法使用LDAP对用户进行身份验证.我有以下细节: URL=ldap://10.10.10.10:389 LDAP BASE:DC=lab2,DC=ins LDAP Bind Account: CN ...

  4. Springboot整合shiro基于url身份认证和授权认证

    你还不会shiro吗? 前奏 shiro核心配置文件(rolesFilter可选). 身份认证 多表登录源如何操作? 授权管理 如何解决界面多角色/资源问题 访问效果 权限管理在日常开发中很重要,所以 ...

  5. mysql url认证_Springboot+shiro基于url身份认证和授权认证

    你还不会shiro吗?前奏 shiro核心配置文件(rolesFilter可选). 身份认证 多表登录源如何操作? 授权管理 如何解决界面多角色/资源问题 访问效果 权限管理在日常开发中很重要,所以硬 ...

  6. 构建具有用户身份认证的 React + Flux 应用程序

    序言:这是一篇内容详实的 React + Flux 教程,文章主要介绍了如何使用 API 获取远程数据以及如何使用 JSON Web Tokens 进行用户身份认证.在阅读本文之后,我一直使用文章介绍 ...

  7. 转:实例学习PHP程序对用户身份认证实现两种方法

    用户在设计和维护站点的时候,经常需要限制对某些重要文件或信息的访问.通常,我们可以采用内置于WEB服务器的基于HTTP协议的用户身份验证机制. 当访问者浏览受保护页面时,客户端浏览器会弹出对话窗口要求 ...

  8. Spring Boot2整合Shiro(1):身份认证

    Spring Boot2整合Shiro(1):身份认证 前言 本文主要介绍了在Spring Boot2项目中整合Shiro实现登录认证.本文假设读者已经对Shiro和基于RBAC的权限控制系统有了基本 ...

  9. Web应用中基于密码的身份认证机制(表单认证、HTTP认证: Basic、Digest、Mutual)

    Web应用中基于密码的身份认证机制 背景概念 认证(Authentication) 会话管理 1 表单认证(Form-Based Authentication) 1.1 介绍 1.2 流程 2 通用的 ...

最新文章

  1. c++语言static作用,详解c++中的 static 关键字及作用
  2. 1、Angular2 Component 组件
  3. go string 换行_从词法分析角度聊 Go 代码组成
  4. 23. 进程并发控制之Semaphore
  5. c/c++宏函数的定义与使用(宏定义函数)(macro definition)
  6. 【UVA - 1335】Beijing Guards (贪心,二分)
  7. linux使用gcc编译报错“undefined reference to `pthread_create'”
  8. vertica数据库将一个字段用逗号分割与拼接
  9. Python:“TypeError: list indices must be integers or slices, not str“问题解决方案
  10. 华为路由器BGP简单配置
  11. 红旗河工程,南水北调西线工程,藏水入疆工程三合一
  12. Markowitz有效边界投资组合——利用python
  13. 【开源】发布一个软件“WeNote 微便签”,比系统自带的便笺好用,每个便签可独立设倒计时
  14. html 字体图标不显示不出来了,h5页面字体图标显示不正常
  15. Verilog实现移位寄存器
  16. 【Flutter】GridView的使用之GridView.count
  17. 花费多少钱能创建百度百科词条?
  18. 内蒙古国家大数据综合试验区启动
  19. Python学习笔记第二次之列表、字典、集合、数据结构应用之多级菜单
  20. 精读《极客公园 IFX - 上》

热门文章

  1. 线性表的顺序表示02
  2. BigDecimal用法详解
  3. Apache POI 中文使用指南
  4. 用shtml来include网页文件(开启SSI)
  5. HDU - 2553:N皇后问题
  6. P2P的Jxta解决方案
  7. DL-Pytorch Task07:优化算法进阶;word2vec;词嵌入进阶
  8. 华为云GPU服务器深度学习环境搭建
  9. 开放api接口平台鉴权怎么做?
  10. 大学生数据库课程设计之学生选课系统(一个超级简单的系统)