1.先导入所需要的依赖包
2.【shiro-web】依赖库引用完成之后,需要修改web.xml配置文件
• 进行shiro整合一定要在web.xml配置文件中配置一个Shiro环境监听器
• 在任何一个shiro项目里面都睡存在有一个shiro.ini配置文件,需要在web.xml配置文件中为其追加一个配置的过滤器
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <listener><!--shiro环境监听器--> <listener-class> org.apache.shiro.web.env.EnvironmentLoaderListener </listener-class> </listener> <filter><!--过滤shiro.ini配置文件--> <filter-name>ShiroFilter</filter-name> <filter-class> org.apache.shiro.web.servlet.ShiroFilter </filter-class> <init-param> <param-name>configPath</param-name> <param-value>classpath:shiro.ini</param-value> </init-param> </filter> <filter-mapping> <filter-name>ShiroFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> </web-app>
3.src/main/resources/目录下的shiro.ini配置文件:ini文件中主要配置有四大类:main,users,roles,urls
● main:配置shiro对象,例如securityManager,Realm,authenticator,autchStrategy等等
● users:配置静态的用户信息,包含用户名,密码,角色,一个用户可以拥有多个角色。如:lee=hello,member,dept 其中lee为用户名,hello为密码,member和dept为角色
● roles:定义角色与权限的关联。如:member=member:add,member:list,member:edit 其中代表着member角色下的add,list和edit权限
● urls:配置主要在web应用中,格式为:url=拦截器[参数],拦截器[参数],...。如:/login.jsp=anon
4.自定义Realm:
● 自定义Realm一定要实现Realm接口并覆写其中的三个方法,例如以下代码
package com.yootk.shiro.realm; import org.apache.shiro.authc.*; import org.apache.shiro.realm.Realm; public class MyselfDefaultRealm implements Realm { private static int count = 0 ; @Override public String getName() { // 获取Realm的名称 return "my-happy-realm - " + count++; } @Override public boolean supports(AuthenticationToken token) { // 判断当前的Token是否可以使用此Realm return token instanceof UsernamePasswordToken; // 当前Realm只支持“UsernamePasswordToken”类型 } @Override public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String mid = (String) token.getPrincipal() ; // 获取用户名 String password = new String((char[]) token.getCredentials()) ; // 获取密码 if (!"lee".equals(mid)) { // 此时用户名不存在 throw new UnknownAccountException("【"+mid+"】该用户信息不存在,请确认输入的用户名!") ; } if (!"hello".equals(mid)) { // 密码不正确 throw new IncorrectCredentialsException("错误的用户名或密码!") ; } return new SimpleAuthenticationInfo(token.getPrincipal(),token.getCredentials(),this.getName()) ; } }
● 编写完自定义Ream类之后需要在shiro.ini配置文件中配置一下
[main]
#要想让自定义的Realm生效一定要配置这两项 # 将自定义的Realm定义在配置文件之中,表示此类的对象将由Shiro类负责实例化 myselfRealm=com.yootk.shiro.realm.MyselfDefaultRealm # 此时的配置就表示调用了SecurityManager子类中的setRealms()方法进行设置,内部引用使用“$”符号 securityManager.realms=$myselfRealm [urls] #web项目一定要设置过滤链,否则会报缺少FilterChainResolver /login.jsp=anon
5.配置JDBC认证信息,系统里面不仅仅只包含有自定义Realm,同时还提供有一种JdbcRealm程序,这类程序的最大特点是可以直接进行数据库的认证信息。
● 想使用JdbcRealm,首先需要修改pom.xml配置文件引入mysql-connector-java依赖包
● 修改shiro.ini配置文件,引入JdbcRealm进行程序的处理
[main] # 定义当前项目之中要使用的DataSource,此时的DataSource为MySQL驱动自带 dataSource=com.mysql.jdbc.jdbc2.optional.MysqlDataSource #dataSource.url=jdbc:mysql://localhost:3306/yootk_authentication dataSource.serverName=localhost dataSource.port=3306 dataSource.databaseName=yootk_authentication dataSource.user=root dataSource.password=mysqladmin # 定义JdbcRealm类型,为当前的使用Realm jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm # 为JdbcRealm设置要使用的数据源 jdbcRealm.dataSource=$dataSource # 设置数据库的查询操作指令 jdbcRealm.authenticationQuery=SELECT password FROM member WHERE mid=? AND locked=0 # 将当前使用的Realm整合在SecurityManager之中 securityManager.realms=$jdbcRealm [urls] /login.jsp=anon
6.Realm与Subject与token与SececurityManager与SecurityUtils的关系
● 首先创建一个SececurityManager的实例
● Realm设置数据源,读取shiro.ini文件
● SececurityManager的实例设置上具体的Realm对象
● SecurityUtils设置上SececurityManager的实例
● 通过SecurityUtils.getSubect获得Subject的对象
● 实例化对象token并向token中存入用户名和密码
● 采用subject.login(token)认证
package com.yootk.test; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.realm.Realm; import org.apache.shiro.realm.text.IniRealm; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import org.junit.Test; public class TestShiroBase { public static final String USERNAME = "lee" ; // 假设此处内容为输入数据 public static final String PASSWORD = "hello" ; // 假设此处内容为输入数据 @Test public void testAuth() throws Exception { // 1、创建一个SececurityManager接口类的对象实例,使用子类为了设置realm DefaultSecurityManager securityManager = new DefaultSecurityManager() ; // 2、所有的认证信息都保存在shiro.ini文件,这个文件存储在CLASSPATH目录下; Realm realm = new IniRealm("classpath:shiro.ini") ; // 3、此时的SecurityManager需要设置上具体的realm对象信息 securityManager.setRealm(realm); // 4、如果要想进行数据的认证处理,还需要获取SecurityUtils工具类 SecurityUtils.setSecurityManager(securityManager); // 设置安全管理类实例 // 5、如果要继续用户认证处理,则首先一定要获取一个Subject(用户) Subject subject = SecurityUtils.getSubject(); // 6、利用一个专属的认证Token的结构包装输入的用户名与密码信息 AuthenticationToken token = new UsernamePasswordToken(USERNAME,PASSWORD) ; // 7、利用Subject实现最终的用户认证处理操作 subject.login(token); // 进行认证操作 System.out.println("用户名:" + subject.getPrincipal()); } }
7.以后开发的时候编写自定义Realm类的时候一般会继承AuthorizingRealm类,然后覆写其中的认证和授权方法。
● 认证方法是doGetAuthenticationInfo():参数类型.getPrincipal()是获取用户名,参数类型.getCredentials()是获取密码,返回值类型是new SimpleAuthenticationInfo(token.getPrincipal(),token.getCredentials(),this.getName());
● 授权方法是doGetAuthorizationInfo():SimpleAuthorizationInfo authz = new SimpleAuthorizationInfo() ; // 返回的授权信息 ;authz.setRoles(map.get("allRoles"));//设置角色;authz.setStringPermissions(map.get("allActions"));//设置权限;return authz;//返回对象