1.创建一个简单shiro项目
-
创建一个java工程
-
加入shiro需要的jar包
-
在src下创建log4j配置文件(非必需步骤,可以跳过)
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
“License”); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
“AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %nGeneral Apache libraries
log4j.logger.org.apache=WARN
Spring
log4j.logger.org.springframework=WARN
Default Shiro logging
log4j.logger.org.apache.shiro=TRACE
Disable verbose logging
log4j.logger.org.apache.shiro.util.ThreadContext=WARN
log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN -
在src下创建shiro.ini配置文件
[users]
admin = 123,role1
[roles]
role1 = printer:print
用户名:admin
密码:123
为admin这个账户赋予role1角色,多个角色使用逗号隔开
role1这个角色拥有printer:print
这个权限,关于这个权限的写法,后面会讲到
-
HelloWorld
package com.shiro.helloworld;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class HelloWorld {
//如果不使用日志,也可以直接用System.out.println(),也就可以不用配置log4j.properties了
private static final transient Logger log = LoggerFactory.getLogger(HelloWorld.class);public static void main(String[] args) { //获取SecurityManager的实例 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject currenUser = SecurityUtils.getSubject(); //session的使用 Session session = currenUser.getSession(); session.setAttribute("key", "value"); String value = (String) session.getAttribute("key"); log.info("value:"+value); //如果还未认证 if(!currenUser.isAuthenticated()){ UsernamePasswordToken token = new UsernamePasswordToken("admin","123"); token.setRememberMe(true); try { currenUser.login(token); } catch (UnknownAccountException uae) { log.info("没有该用户: " + token.getPrincipal()); } catch (IncorrectCredentialsException ice) { log.info( token.getPrincipal() + " 的密码不正确!"); } catch (LockedAccountException lae) { log.info( token.getPrincipal() + " 被锁定 ,请联系管理员"); }catch (AuthenticationException ae) { //其他未知的异常 } } if(currenUser.getPrincipal() != null) log.info("用户 "+currenUser.getPrincipal() +" 登录成功"); //是否有role1这个角色 if(currenUser.hasRole("role1")){ log.info("有角色role1"); }else{ log.info("没有角色role1"); } //是否有对打印机进行打印操作的权限 if(currenUser.isPermitted("printer:print")){ log.info("可以对打印机进行打印操作"); }else { log.info("不可以对打印机进行打印操作"); } //退出登录 currenUser.logout(); System.exit(0); }
}
- 其实我们使用shiro就为了做两件事:1. 验证用户的身份,2. 验证该用户是否有进行某个操作的权限
运行结果:
2.Shiro的权限
2.1 简单字符串
用简单的字符串来表示一个权限,如:queryPrinter
2.2 多层次管理
-
printer:print
其中第一部分是权限被操作的领域(打印机),第二部分是被执行的操作
-
多个值
多个值使用逗号隔开,如role1 = printer:print,printer:query
不一定要xxx:yyyy的形式,也可以直接使用简单字符串 -
可以使用*号表示所有
比如printer:* ,表示你可以对打印机进行任何操作,
或者使用 *:query ,表示你在任何领域下,都有查询操作
2.2 实例级访问控制
-
这种情况通常会使用三个部件——第一个是域,第二个是操作,第三个是被付诸
实施的实例。如:printer:query:lp7200也可以使用通配符来定义,如:
printer:print:*
printer::
printer:*:lp7200
printer:query, print:lp7200 -
部分省略:缺少的部件意味着用户可以访问所有与之匹配的值
printer:print 等价于 printer:print:*
printer 等价于 printer::
但是请记住:只能从字符串的结尾处省略部件,也就是说
printer:lp7200 于 并不等价于 printer:*:lp7200