shiro是什么
Apache Shiro是一个强大且易用的Java安全框架,有身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
shiro的作用
Shiro 开发团队称为“应用程序的四大基石” ——身份验证,授权,会话管理和加密作为其目标。
Authentication(身份认证) :
有时也简称为“登录”,这是一个证明用户是他们所说的他们是谁的行为。
Authorization(授权):
访问控制的过程,也就是绝对“谁”去访问“什么”权限。
Session Management:管理用户特定的会话,即使在非 Web 或 EJB 应用程序。
Cryptography:通过使用加密算法保持数据安全同时易于使用。
也提供了额外的功能来支持和加强在不同环境下所关注的方面,尤其是以下这些:
Web Support: Shiro 的 web 支持的 API 能够轻松地帮助保护 Web 应用程序。
Caching:缓存是 Apache Shiro 中的第一层公民,来确保安全操作快速而又高效。
Concurrency: Apache Shiro 利用它的并发特性来支持多线程应用程序。
Testing:测试支持的存在来帮助你编写单元测试和集成测试,并确保你的能够如预期的一样安全。
“Run As”:一个允许用户假设为另一个用户身份(如果允许)的功能,有时候在管理脚本很有用。
“Remember Me”:在会话中记住用户的身份,所以他们只需要在强制时候登录。
架构:
shiro外部来看
从外部来看Shiro,即从应用程序角度(使用者)来如何使用shiro来完成工作(认证、授权等)。
Shiro内部看
即shiro内部夹走
导入所需的包
拷贝资源
resources下面两个配置文件
log4j.properties
shiro.ini
java下面一个java文件
Quickstart.java
测试:
public class Quickstart {
private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
public static void main(String[] args) {
//通过一个配置了realms,users,roles,permissions的ini的配置文件快速创建一个SecurityManager
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
//为了程序能偶正常运行,需要设置securityManager
SecurityUtils.setSecurityManager(securityManager);
//获取当前用户
Subject currentUser = SecurityUtils.getSubject();
//1 会话操作
Session session = currentUser.getSession();//获取session
session.setAttribute("someKey", "aValue");//在session中设置值
String value = (String) session.getAttribute("someKey");//从session中获取值
if (value.equals("aValue")) {
log.info("Retrieved the correct value! [" + value + "]");
//return;
}
//2 身份认证(登录)
//如果没有登录
if (!currentUser.isAuthenticated()) {
//把前台传入的用户名和密码创建一个UsernamePasswordToken
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
token.setRememberMe(true);
try {
//通过currentUser调用login传入UsernamePasswordToken执行登录操作,如果不正确就会抛出对应错误
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.");
}
//其他异常-AuthenticationException是上面一样的父类
// ... catch more exceptions here (maybe custom ones specific to your application?
catch (AuthenticationException ae) {
//unexpected condition? error?
}
}
//say who they are:
//print their identifying principal (in this case, a username):
log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
//3 权限
//判断当前用户是否拥有该角色
if (currentUser.hasRole("schwartz")) {
log.info("May the Schwartz be with you!");
} else {
log.info("Hello, mere mortal.");
}
//测试权限 lightsaber:*
if (currentUser.isPermitted("lightsaber:weild")) {
log.info("You may use a lightsaber ring. Use it wisely.");
} else {
log.info("Sorry, lightsaber rings are for schwartz masters only.");
}
//a (very powerful) Instance Level permission:
if (currentUser.isPermitted("winnebago:drive:eagle5")) {
log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " +
"Here are the keys - have fun!");
} else {
log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
}
//all done - log out!
currentUser.logout();
System.exit(0);
}
}
总结
通过SecurityManger获取Suject
通过Subject来做事情:
获取Session-存值和获取值 Suject.getSession session.setAttribute session.getAttribute
认证(登录):
判断是否登录Suject.isAuthenticated
如果没有登录,通过用户名和密码创建UsernamePasswordToken
调用suject.login(UsernamePasswordToken)来进行登录判断
授权
判断是否具有某个角色subject .hasRole
判断是否有权限subject .isPrermited(resource:操作)