Shiro介绍
1.shiro介绍:Shirp是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权,加密,会话管理等功能,组成一个通用的安全认证框架。
2.Shiro框架
3.对象:
a) Subject:主体,外部应用与subject进行交互,subject记录了当前操作用户,将用户的概念理解为当前操作的主体,可能是通过浏览器请求的用户,也可能是一个运行的程序。Subject在shiro中是一个接口,接口中定义了很多认证授权的相关方法,外部程序通过subject进行认证授权,而subject是通过SecurityManager安全管理器进行认证授权。
b) SecurityManager:安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证,授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessuionManager进行会话管理等。SecurityManager是一个接口,继承了Authenticator,Authorizer,SessionManager三个接口。
c) Authenticator:认证器,对用户身份进行认证。Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大部分需求,也可以自定义认证器。
d) Authorizer:授权器,用户通过认证器认证后,在访问功能时需要通过授权器判断用户是否有此功能的操作权限。
e) realm:领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户数据,比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。realm不仅仅时从数据源取数据,在realm中还有认证授权校验的代码。
f) sessionManager:会话管理,shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。
g) SessionDAO:会话dao,是对session会话操作的一套接口,比如将session存储到数据库。可以通过jdbc将会话存储到数据库。
h) CacheManager:缓存管理,将用户权限数据存储到缓存里,这样可以提高性能。
i) Cryptography:密码管理,shiro提供一套加密/解密的组件,方便开发。比如提供常用的散列,加/解密等功能。
j) shiro的jar包(maven):
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-quartz</artifactId> <version>1.2.3</version> </dependency> 也可以通过引入shiro-all包括shiro所有的包: <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.2.3</version> </dependency> |
Shiro使用(用maven)
认证的简单使用
1.导入jar包,关于shiro的jar包的maven坐标
<!-- shiro的core包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency>
<!-- --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency> |
2.在resources下配置shiro.ini文件
[users] #用户信息:账号=密码(shiro默认的realm是iniRealm) admin=admin user=user |
3.测试代码
package com.zhiyou100.kfs.shiro; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; public class Shiro { public static void main(String[] args) { //1.根据IniSecurityManager类加ini文件创建SecurityManager factory Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiro.ini"); //2.根据factory的getInstance方法创建SecurityManager对象 SecurityManager securityManager=factory.getInstance(); //3.把securityManager放到运行环境中 SecurityUtils.setSecurityManager(securityManager); //4.获取subject对象 Subject subject=SecurityUtils.getSubject(); //创建UsernamePasswordToken对象获取输入的身份信息(账号密码) UsernamePasswordToken token=new UsernamePasswordToken("admin","admin");
try { //认证登录,该方法通过异常来区分登录失败和成功 subject.login(token); System.out.println("登录成功"); }catch(Exception e){ System.out.println("登录失败"); }
} } |
认证使用自定义的realm
1.在resources配置shiroRealm.ini文件
[main] #定义自己的realm myrealm=com.zhiyou100.kfs.realm.MyRealm #把该realm绑定到securityManager上 securityManager.realms=$myrealm |
2.创建自定义的realm
package com.zhiyou100.kfs.realm; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import com.zhiyou100.kfs.bean.User; public class MyRealm extends AuthorizingRealm{ //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { return null; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("开始执行认证"); //获取输入的账号 String username = token.getPrincipal().toString(); //根据该账号查询数据库(这边用固定的值) User user=new User(); user.setUsername("admin"); user.setPassword("admin");
if(user==null) { return null; } /* * principal:输入的账号 * credentials:根据账号查询的密码 * realName:随便给,但企业习惯用 this.getName() * info:对象会帮你比较 密码是否一致 * new SimpleAuthenticationInfo(principal, credentials, realmName); */ SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,user.getPassword(),getName()); return info; } } |
授权的简单使用
1.在resources下配置shiroPermission.ini文件
[main] #定义自己的realm myrealm=com.zhiyou100.kfs.realm.MyRealm #把该realm绑定到securityManager上 securityManager.realms=$myrealm |
2.测试代码
package com.zhiyou100.kfs.shiro; import java.util.ArrayList; import java.util.Arrays; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; public class ShiroPermission { public static void main(String[] args) { //1.根据IniSecurityManagerFactory类和ini文件创建SecurityManager的factory Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiroPermission.ini"); //2.根据factory的getInstance方法创建securityManager对象 SecurityManager securityManager = factory.getInstance(); //3.把securityManager对象放到运行环境 SecurityUtils.setSecurityManager(securityManager);
//4.获取Subject对象 Subject subject = SecurityUtils.getSubject(); //5.获取输入的身份信息 UsernamePasswordToken token=new UsernamePasswordToken("admin","admin");
try { subject.login(token); System.out.println("登录成功"); }catch (Exception e) { System.out.println("登录失败"); }
//判断是否有某个角色 boolean isone = subject.hasRole("role1"); System.out.println("判断是否有某个角色:"+isone); //判断是否有某多个角色 boolean ismul = subject.hasAllRoles(Arrays.asList("role1","role2")); System.out.println("判断是否有某多个角色:"+ismul);
//判断是否有某个权限 boolean ispone = subject.isPermitted("user:create"); System.out.println("判断是否有某个权限:"+ispone); //判断是否有某多个权限 boolean ispmul = subject.isPermittedAll("user:create","user:delete"); System.out.println("判断是否有某多个权限:"+ispmul);
} } |
授权使用自定义的realm
1.在resources中创建shiroPermission.ini文件
[users] #用户信息:账号=密码,角色1,角色2...(shiro默认的realm是iniRealm) admin=admin,role1,role2 [roles] #角色名称=权限1,权限2,... role1=user:create,user:delete role2=user:query |
2.创建自定义的realm
package com.zhiyou100.kfs.realm; import java.util.ArrayList; import java.util.List; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import com.zhiyou100.kfs.bean.Role; import com.zhiyou100.kfs.bean.User; public class MyRealm extends AuthorizingRealm{ //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("开始授权"); //获取认证过的账号 String username=principals.toString(); System.out.println(username);
//根据认证的账号查询该用户具有的角色(这边用固定值) List<Role> roles=new ArrayList<Role>(); if("admin".equals(username)) { Role role1 = new Role(); role1.setRolename("admin"); roles.add(role1); Role role2 = new Role(); role2.setRolename("user"); roles.add(role2); }else if("user".equals(username)) { Role role1 = new Role(); role1.setRolename("user"); roles.add(role1); } if(roles.isEmpty()) {//该用户没任何角色 return null; }
//该角色具有的权限 SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
for(Role role:roles) { //把角色名放到info里 info.addRole(role.getRolename()); //根据该角色查询对应的权限 if("admin".equals(role.getRolename())) { info.addStringPermission("user:delete"); } if("user".equals(role.getRolename())) { info.addStringPermission("user:select"); } } return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("开始执行认证"); //获取输入的账号 String username = token.getPrincipal().toString(); //根据该账号查询数据库(这边用固定的值) User user=new User(); user.setUsername("user"); user.setPassword("user");
if(user==null) { return null; } /* * principal:输入的账号 * credentials:根据账号查询的密码 * realName:随便给,但企业习惯用 this.getName() * info:对象会帮你比较 密码是否一致 * new SimpleAuthenticationInfo(principal, credentials, realmName); */ SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,user.getPassword(),getName()); return info; } } |
3.测试代码
package com.zhiyou100.kfs.shiro; import java.util.Arrays; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; public class ShiroRealm { public static void main(String[] args) { //得到一个Factory对象 作用创建SecurityManager对象 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiroRealm.ini"); //获取SecurityManager对象 SecurityManager securityManager=factory.getInstance();
//把securityManager放到运行环境中 SecurityUtils.setSecurityManager(securityManager); //获取Subject对象。 Subject subject=SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken("user","user"); //值可以从网页中获取 try { subject.login(token); //需要账号和密码 Token对象中 System.out.println("登录成功"); }catch (Exception e) { e.printStackTrace(); System.out.println("登录失败"); }
//有没有某个角色 boolean hasRole = subject.hasRole("admin"); System.out.println("有没有某个角色:"+hasRole); //有没有同时拥有某多个角色 boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("admin","user")); System.out.println("有没有某多个角色"+hasAllRoles);
//有没有某个权限 boolean permitted = subject.isPermitted("user:select"); System.out.println("有没有某个权限"+permitted); //有没有同时拥有某多个权限 boolean permittedAll = subject.isPermittedAll("user:delete","user:select"); System.out.println("有没有某多个权限"+permittedAll);
} } |
自定义realm的认证和授权(固定值)
1.导入jar包(用的maven)
<!-- shiro的core包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency>
<!-- --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency> |
2.配置realm.ini文件
#自定义的realm #定义自定义realm shiropermissionrealm=com.zhiyou100.kfs.realm.ShiroPermissionRealm #把自定义的realm绑定到securityManager中 securityManager.realms=$shiropermissionrealm |
3.创建自定义realm类ShiroPermissionRealm类
package com.zhiyou100.kfs.realm; import java.util.ArrayList; import java.util.List; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import com.zhiyou100.kfs.bean.Role; import com.zhiyou100.kfs.bean.User; public class ShiroPermissionRealm extends AuthorizingRealm{ //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("开始授权");
//获取认证通过的账号 String username = principals.toString(); //根据账号查询数据库的角色(这边用固定值) List<Role> roles=new ArrayList<Role>(); Role role1 = new Role(); role1.setRilename("admin"); roles.add(role1); Role role2 = new Role(); role2.setRilename("user"); roles.add(role2);
//判断根据账号有没有查到数据 if(roles.isEmpty()) { return null; }
//给对应的角色赋予对应的权限(资源) SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); for(Role role:roles) { //根据角色查询数据库的权限(这边用固定值)
//添加角色名到info info.addRole(role.getRilename()); if(role.getRilename().equals("admin")) { //为角色赋予权限 info.addStringPermission("user:create"); }else if(role.getRilename().equals("user")) { info.addStringPermission("user:delete"); } }
return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("开始认证");
//获取输入的账号 String username = token.getPrincipal().toString(); System.out.println(username);
//根据账号查询数据库的用户(这边用固定值) User user=new User();//假设是数据库的 user.setUsername("admin"); user.setPassword("admin");
//判断用账号有没有查到数据 if(user==null) { return null; } System.out.println(user);
/* * 比较输入的账号密码对不对,对没有异常,错误有各种异常(账号错误,密码错误是不同的异常) * new SimpleAuthenticationInfo(principal, credentials, realmName); * principal:输入的账号 * credentials:根据账号在数据库查到的密码 * realmName:随便,但企业用this.getName() * */ SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,user.getPassword(),getName()); return info; } } |
4.测试代码
package com.zhiyou100.kfs.shiro; import java.util.Arrays; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; public class ShiroPermission { public static void main(String[] args) { /* * Shiro的认证和授权 */
//认证 //1.根据IniSecurityManagerFactory类和ini文件获取创建SecurityManager类的Factory Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:realm.ini"); //2.根据factory对象的getInstance方法创建securityManager对象 SecurityManager securityManager = factory.getInstance(); //3.根据SecurityUtils工具类的setSecurityManager把securityManager对象放到运行环境中 SecurityUtils.setSecurityManager(securityManager); //以上3步整合由框架完成
//4.根据SecurityUtils工具类的getSubject方法获取subject对象 Subject subject = SecurityUtils.getSubject(); //5.把输入的账号密码放到UsernamePasswordToken类的token对象中 UsernamePasswordToken token=new UsernamePasswordToken("admin", "admin");
try { //6.根据subject对象的login方法进行认证(认证成功不会有异常,认证失败会有各种不同的异常,所有通过try,catch来判断是否认证成功) subject.login(token); System.out.println("认证成功"); }catch (Exception e) { System.out.println("认证失败"); }
//授权 //有没有某个角色 boolean hasRole = subject.hasRole("admin"); System.out.println("有没有某个角色:"+hasRole); //有没有同时拥有某多个角色 boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("admin","user")); System.out.println("有没有某多个角色"+hasAllRoles);
//有没有某个权限 boolean permitted = subject.isPermitted("user:select"); System.out.println("有没有某个权限"+permitted); //有没有同时拥有某多个权限 boolean permittedAll = subject.isPermittedAll("user:delete","user:create"); System.out.println("有没有某多个权限"+permittedAll);
} } |
自定义realm和ssm整合再加数据库的认证和授权
1.jar包(ssm的jar包、shiro的jar包和shiro-springjar包)用maven
<!-- shiro的core包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency> <!-- --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency> <!-- shiro-web --> <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-web --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.4.0</version> </dependency> <!-- shiro-spring --> <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> |
2.mysql数据库的5张表(user,role,permission,user_role,role_permission):
3.逆向工程生成对应bean实体类,dao操作类接口,mapper映射文件
4.ssm配置代码
5.配置自定义的Realm类:ShiroRealm
package com.zhiyou100.kfs.realm; import java.util.List; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; import com.zhiyou100.kfs.bean.Permission; import com.zhiyou100.kfs.bean.Role; import com.zhiyou100.kfs.bean.User; import com.zhiyou100.kfs.service.PermissionService; import com.zhiyou100.kfs.service.RoleService; import com.zhiyou100.kfs.service.UserService; public class ShiroRealm extends AuthorizingRealm{ @Autowired private UserService userService; @Autowired private RoleService roleService; @Autowired private PermissionService permissionService;
//授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("开始授权");
//获取认证通过的账号 String username = principals.getPrimaryPrincipal().toString();
//根据账号查询角色 List<Role> roles = roleService.selectByUsername(username); System.out.println(roles);
if(roles.isEmpty()) {//判断是否为空 return null; }
//遍历并给对应的角色赋予对应的权限(资源) SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); for(Role role:roles) { //添加角色名到info info.addRole(role.getRolename());
//根据角色查询对应的资源并添加到info里 List<Permission> permissions = permissionService.selectByRoleId(role.getRoleid()); for(Permission permission:permissions) { info.addStringPermission(permission.getUrl()); } } return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("开始认证");
//获取输入的账号 String username = token.getPrincipal().toString(); System.out.println(username);
//根据账号查询用户 User user=userService.selectByUsername(username); System.out.println(user); if(user==null) { return null; }
SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,user.getPassword(),getName()); return info; } } |
6.测试认证的controller类:LoginController
package com.zhiyou100.kfs.controller; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.zhiyou100.kfs.bean.User; @Controller @RequestMapping("user") public class LoginController {
@RequestMapping("login") public ModelAndView login(ModelAndView mv,User user) { System.out.println(user); //通过shiro认证
//获取subject Subject subject = SecurityUtils.getSubject(); //用UsernamePasswordToken对象yoken接输入的账号密码 UsernamePasswordToken token=new UsernamePasswordToken(user.getUsername(),user.getPassword());
try { subject.login(token); System.out.println("认证成功"); mv.setViewName("index"); }catch (Exception e) { e.printStackTrace(); System.out.println("认证失败"); mv.setViewName("login"); } return mv; }
@RequestMapping("logout") public ModelAndView logout(ModelAndView mv) { mv.setViewName("/login"); //用shiroFilter的logout过滤器可以完成注销操作 return mv; } } |
7.测试授权的controller类:UserController
package com.zhiyou100.kfs.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.zhiyou100.kfs.service.UserService; @Controller @RequestMapping("user") public class UserController { @Autowired private UserService userService;
@RequestMapping("insertUser") public ModelAndView insertUser(ModelAndView mv) { mv.setViewName("");
return mv; }
@RequestMapping("deleteUser") public ModelAndView deleteUser(ModelAndView mv) { mv.setViewName("");
return mv; }
@RequestMapping("updateUser") public ModelAndView updateUser(ModelAndView mv) { mv.setViewName("");
return mv; } } |
8.测试的jsp
//login.jsp: <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>login</title> </head> <body> <form action="<c:url value='user/login'/>" method="post"> 账号:<input type="text" name="username" /><br/> 密码:<input type="text" name="password" /><br/> <input type="submit" value="登录" /><br/> </form> </body> </html> //index.jsp: <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>index</title> </head> <body> index<br/> 欢迎,<a href="<c:url value='/user/logout'/>">注销</a><br/> <a>user</a><br/> <a href="<c:url value='/user/insertUser'/>">user:create</a><br/> <a href="<c:url value='/user/deleteUser'/>">user:delete</a><br/> <a href="<c:url value='/user/updateUser'/>">user:update</a><br/> <a>good</a><br/> <a href="<c:url value='/user/insertGood'/>">good:create</a><br/> </body> </html> |
9.shiro和spring的整合xml:applicationContext-shiro.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 把shiro配置在spring里 -->
<!-- 配置自定义的realm类 --> <bean id="shiroRealm" class="com.zhiyou100.kfs.realm.ShiroRealm"/>
<!-- 配置DefaultWebSecurityManager,并把realm放到运行环境里 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="shiroRealm"/> </bean>
<!-- 请求过滤器,id要和web.xml的过滤器名一样 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 过滤器和securityManager关联 --> <property name="securityManager" ref="securityManager"/>
<!-- 登录界面login.jsp放行 --> <property name="loginUrl" value="/login.jsp"/>
<!-- 权限不足的跳转页面 --> <property name="unauthorizedUrl" value="/error.jsp"/>
<!-- 设置拦截规则 --> <property name="filterChainDefinitions"> <value> /js/*=anon /css/*=anon /images/*=anon
<!-- 给登录的控制层方法放行,否则进不去 --> /user/login=anon
<!-- 基于角色拦截 --> <!-- /user/insertUser=roles[user] /user/updateUser=roles['admin','user'] /user/deleteUser=roles[admin] -->
<!-- 基于资源拦截 --> /user/insertUser=perms[user:create] /user/updateUser=perms[user:update] /user/deleteUser=perms[user:delete]
<!-- 注销 --> /user/logout=logout
/**=authc </value> </property> </bean>
</beans> |
- 以上是shiro和ssm的整合,
- 继续授权的三种方式(用以上的整合的代码继续)
a) 用配置文件配置拦截器来授权(以上就是用配置文件完成授权的)
b) 注解式:用注解式就不用配置上面applicationContext-shiro.xml中的filterChainDefinitions。
i. web.xml还是以上配置,但是springContext-shiro.xml需要把<property name="filterChainDefinitions">给去掉,然后在controller层加相应注解。
ii. springContext-shiro.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 把shiro配置在spring里 -->
<!-- 配置自定义的realm类 --> <bean id="shiroRealm" class="com.zhiyou100.kfs.realm.ShiroRealm"/>
<!-- 配置DefaultWebSecurityManager,并把realm放到运行环境里 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="shiroRealm"/> </bean>
<!-- 请求过滤器,id要和web.xml的过滤器名一样 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 过滤器和securityManager关联 --> <property name="securityManager" ref="securityManager"/>
<!-- 登录界面login.jsp放行 --> <property name="loginUrl" value="/login.jsp"/>
<!-- 权限不足的跳转页面 --> <property name="unauthorizedUrl" value="/error.jsp"/>
<!-- 设置拦截规则:用配置文件式授权用,若用注解式授权则不用 --> <!-- <property name="filterChainDefinitions"> <value> /js/*=anon /css/*=anon /images/*=anon
给登录的控制层方法放行,否则进不去 /user/login=anon
基于角色拦截 /user/insertUser=roles[user] /user/updateUser=roles['admin','user'] /user/deleteUser=roles[admin]
基于资源拦截 /user/insertUser=perms[user:create] /user/updateUser=perms[user:update] /user/deleteUser=perms[user:delete]
注销 /user/logout=logout
/**=authc </value> </property> --> </bean>
</beans> |
iii. controller层
package com.zhiyou100.kfs.controller; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresRoles; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping("user") public class UserController {
@RequestMapping("insertUser") @RequiresPermissions(value="user:create") public ModelAndView insertUser(ModelAndView mv) { mv.setViewName("");
return mv; }
@RequestMapping("deleteUser") /* * @RequiresRoles:注解式授权,表示基于角色的授权,logical.OR表示或的关系,不写表示与,value里的就是需要的角色 * @RequiresPermissions:注解式授权,表示基于资源的授权 */ @RequiresRoles(value= {"admin","user"},logical=Logical.OR) @RequiresPermissions(value="user:delete") public ModelAndView deleteUser(ModelAndView mv) { mv.setViewName("");
return mv; }
@RequestMapping("updateUser") @RequiresPermissions(value="user:update") public ModelAndView updateUser(ModelAndView mv) { mv.setViewName("");
return mv; } } |
c) 标签式:在网页加入shiro的标签来授权
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>index</title> </head> <body> index<br/> 欢迎,<a href="<c:url value='/user/logout'/>">注销</a><br/> <a>user</a><br/> <!-- 有user:create资源的角色才看的见 --> <shiro:hasPermission name="user:create"> <a href="<c:url value='/user/insertUser'/>">user:create</a><br/> </shiro:hasPermission> <a href="<c:url value='/user/deleteUser'/>">user:delete</a><br/> <a href="<c:url value='/user/updateUser'/>">user:update</a><br/> <a>good</a><br/> <!-- 有角色admin才看得见 --> <shiro:hasRole name="admin"> <a href="<c:url value='/user/insertGood'/>">good:create</a><br/> </shiro:hasRole> </body> </html> |