1 Shiro是什么
Shiro是一个强大易用的 Java 安全框架,提供了认证、授权、加密和会话管理功能。
应用安全的四要素:
- 认证 - 用户身份识别,常被称为用户“登录”;
- 授权 - 访问控制;
- 密码加密 - 保护或隐藏数据防止被偷窥;
- 会话管理 - 与用户相关的时间敏感的状态;
Shiro 还支持一些辅助特性,如 Web 应用安全、单元测试和多线程
2 Hello Shiro
最好的学习地址是官网:http://shiro.apache.org/
运行一个简单的样例:
pom.xml:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
src\main\resources下:
log4j.properties:
log4j.rootLogger=info,appender1
#输出到控制台
log4j.appender.appender1=org.apache.log4j.ConsoleAppender
#样式为PatternLayout
log4j.appender.appender1.layout=org.apache.log4j.PatternLayout
#输出格式
log4j.appender.appender1.layout.ConversionPattern=[%p] %l - %m%n
shiro.ini:创建几个默认用户,角色,权限
# -----------------------------------------------------------------------------
# Users and their (optional) assigned roles
# username = password, role1, role2, ..., roleN
# -----------------------------------------------------------------------------
[users]
admin = admin, admin
manager = 12345, manager
managerOperator = 12345, manager, operator
auditor = 12345, auditor
# -----------------------------------------------------------------------------
# Roles with assigned permissions
# roleName = perm1, perm2, ..., permN
# -----------------------------------------------------------------------------
[roles]
admin = *
manager = manager:*
auditor = auditor:*
operator = operator:*
主程序-App.java:
/**
* Hello Shiro!
* </p>
* 以常见权限系统为例,包含4种角色:admin、manager、operator、auditor
*
* </p>
*/
public class App
{
private static final transient Logger log = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
log.info("Hello Shiro!");
//加载classpath下的shiro.ini配置文件,使用url:或者file:格式也可以
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//解析ini文件并返回一个SecurityManager实例
SecurityManager securityManager = factory.getInstance();
//securityManager只能单例访问,一般交由容器管理
SecurityUtils.setSecurityManager(securityManager);
//获取当前执行的用户:
Subject currentUser = SecurityUtils.getSubject();
//获取当前用户的会话,并效验数据(shiro独立会话,非HTTP环境也可以存在)
Session session = currentUser.getSession();
session.setAttribute("nickname", "shiro");
String value = (String) session.getAttribute("nickname");
if (value.equals("shiro")) {
log.info("Retrieved the correct nickname! [" + value + "]");
}
// 登录当前用户,以便检查角色和权限:先判断是否已经登录,否则,执行登录操作
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken("managerOperator", "12345");
token.setRememberMe(true);
try {
currentUser.login(token);
} catch (UnknownAccountException uae) {
// 若没有指定的账户
log.info("There is no user with username of " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
// 若账户存在, 但密码不匹配
log.info("Password for account " + token.getPrincipal() + " was incorrect!");
} catch (LockedAccountException lae) {
// 若用户被锁定
log.info("The account for username " + token.getPrincipal() + " is locked. " +
"Please contact your administrator to unlock it.");
}
//你可以检查许多不同类型的异常,也可以针对自定义条件抛出自己的异常,而Shiro可能无法解决
catch (AuthenticationException ae) {
// 用户角色异常的父类,意想不到的条件?错误?
}
}
log.info("User [" + currentUser.getPrincipal() + "] login successfully.");
//测试是否包含manager角色:
if (currentUser.hasRole("manager")) {
log.info("you can do something that manager can do!");
} else {
log.info("you are not manager");
}
//测试是否包含operator角色:
if (currentUser.hasRole("operator")) {
log.info("you can do something that operator can do!");
} else {
log.info("you are not operator");
}
//测试是否包含auditor角色:
if (currentUser.hasRole("auditor")) {
log.info("you can do something that auditor can do!");
} else {
log.info("you are not auditor");
}
//测试是否包含某个权限:
if (currentUser.isPermitted("manager:*")) {
log.info("you has permission [manager:*]");
} else {
log.info("you has not permission[manager:*]");
}
//一个超出自身的权限:
if (currentUser.isPermitted("*")) {
log.info("you has permission [*]!");
} else {
log.info("you has not permission[*]!");
}
//登出
currentUser.logout();
}
}
运行结果:
[INFO] com.chaozai.shiro.App.main(App.java:30) - Hello Shiro!
[INFO] org.apache.shiro.session.mgt.AbstractValidatingSessionManager.enableSessionValidation(AbstractValidatingSessionManager.java:233) - Enabling session validation scheduler...
[INFO] com.chaozai.shiro.App.main(App.java:47) - Retrieved the correct nickname! [shiro]
[INFO] com.chaozai.shiro.App.main(App.java:73) - User [managerOperator] login successfully.
[INFO] com.chaozai.shiro.App.main(App.java:77) - you can do something that manager can do!
[INFO] com.chaozai.shiro.App.main(App.java:83) - you can do something that operator can do!
[INFO] com.chaozai.shiro.App.main(App.java:91) - you are not auditor
[INFO] com.chaozai.shiro.App.main(App.java:96) - you has permission [manager:*]
[INFO] com.chaozai.shiro.App.main(App.java:105) - you has not permission[*]!
3 总结
上述例子简单的体现了shiro的权限判定功能,可能你会有疑问,感觉没用实际作用呀,用户登陆这么草率么?密码加密呢?权限控制又体现在哪里?这些就需要后续章节的补充啦。敬请期待......
爱家人,爱生活,爱设计,爱编程,拥抱精彩人生!