1、shiro内部架构简介
- Subject :主题,任何可以与应用交互的 用户
- SecurityManage : shiro的核心,所有具体的交互通需要通过securityManage进行控制,它管理所有的subject,负责进行认证和授权、回话,缓存管理
- Authenticator : 认证器,负责主体认证,用户可以自定义实现,自定义认证策略,确定什么情况下算用户认证通过
- Authrizer : 授权器,决定主体是否拥有相应的权限进行操作
- Realm:可以定义一个或者多个Realm,安全实体数据源,可以使jdbc,ldap或者内存实现。
- SessionManager:回话管理器,如果写过 Servlet 就应该知道 Session 的概念,Session 需要有人去管理它的生命周期,这个组件就是 SessionManager。而 Shiro 并不仅仅可以用在 Web 环境,也可以用在如普通的 JavaSE 环境
shiro认证授权流程
从官网上的代码看下认证和授权流程 地址:https://www.infoq.com/articles/apache-shiro/
Subject
1.获取主题:
import org.apache.shiro.subject.Subject;
import org.apache.shiro.SecurityUtils;
...
Subject currentUser = SecurityUtils.getSubject();
一旦获取到subject,你就可以对当前用户绝大部分的操作,比如登录,登出,访问session,授权检查等。
SecurityManager
2.使用ini配置shiro
[main]
cm = org.apache.shiro.authc.credential.HashedCredentialsMatcher
cm.hashAlgorithm = SHA-512
cm.hashIterations = 1024
# Base64 encoding (less text):
cm.storedCredentialsHexEncoded = false
iniRealm.credentialsMatcher = $cm
[users]
jdoe = TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJpcyByZWFzb2
asmith = IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbXNoZWQsIG5vdCB
3.加载shiro.ini
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.util.Factory;
...
//1. Load the INI configuration
Factory<SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro.ini");
//2. Create the SecurityManager
SecurityManager securityManager = factory.getInstance();
//3. Make it accessible
SecurityUtils.setSecurityManager(securityManager);
Realms
4.配置realm 链接到ldap用户数据中心
[main]
ldapRealm = org.apache.shiro.realm.ldap.JndiLdapRealm
ldapRealm.userDnTemplate = uid={0},ou=users,dc=mycompany,dc=com
ldapRealm.contextFactory.url = ldap://ldapHost:389
ldapRealm.contextFactory.authenticationMechanism = DIGEST-MD5
认证 Authentication
5.授权:主体登录
//1. Acquire submitted principals and credentials:
AuthenticationToken token =
new UsernamePasswordToken(username, password);
//2. Get the current Subject:
Subject currentUser = SecurityUtils.getSubject();
//3. Login:
currentUser.login(token);
6.处理登录失败情况
//3. Login:
try {
currentUser.login(token);
} catch (IncorrectCredentialsException ice) { …
} catch (LockedAccountException lae) { …
}
…
catch (AuthenticationException ae) {…
}
授权Authorization
7.角色检查
if ( subject.hasRole(“administrator”) ) {
//show the ‘Create User’ button
} else {
//grey-out the button?
}
8.权限检查
if ( subject.isPermitted(“user:create”) ) {
//show the ‘Create User’ button
} else {
//grey-out the button?
}
回话管理Session Management
9.主题回话
Session session = subject.getSession();
Session session = subject.getSession(boolean create);
session.getAttribute(“key”, someValue);
Date start = session.getStartTimestamp();
Date timestamp = session.getLastAccessTime();
session.setTimeout(millis);