
ShiroFilterFactoryBean 是 shiro 为 spring 提供的主 filter 的 factoryBean 类,这个factoryBean 类会创建SpringShiroFilter, 里面内置了很多 filter ,当然用户自定义的 filter 需要用户手动加进来。
二、 几个核心类 1. SecurityManager
集认证、授权以及session 管理于一体,方便开发者使用。
如何使用,我们还是看源码注释:
所以下面这三行代码使我们生产中用的比较多的:
Subject subject = SecurityUtils.getSubject();
NoPasswordToken token = new NoPasswordToken(username);
subject.login(token);
login 成功后会创建 subject 并将 principal 填充到 subject 中, 创建 session :
public void login(AuthenticationToken token) throws AuthenticationException {
clearRunAsIdentitiesInternal();
// 1. 创建 subject 并填充 principal
Subject subject = securityManager.login(this, token);
PrincipalCollection principals;
String host = null;
if (subject instanceof DelegatingSubject) {
DelegatingSubject delegating = (DelegatingSubject) subject;
//we have to do this in case there are assumed identities - we don't want to lose the 'real' principals:
principals = delegating.principals;
host = delegating.host;
} else {
principals = subject.getPrincipals();
}
if (principals == null || principals.isEmpty()) {
String msg = "Principals returned from securityManager.login( token ) returned a null or " +
"empty value. This value must be non null and populated with one or more elements.";
throw new IllegalStateException(msg);
}
this.principals = principals;
this.authenticated = true;
if (token instanceof HostAuthenticationToken) {
host = ((HostAuthenticationToken) token).getHost();
}
if (host != null) {
this.host = host;
}
// 2. 创建 session
Session session = subject.getSession(false);
if (session != null) {
this.session = decorate(session);
} else {
this.session = null;
}
}
2. AuthorizingRealm
securityManager 的认证和授权的实际类,
securityManager 创建时会设置自定义的 Realm ,
@Bean("securityManager")
public SecurityManager securityManager() {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(authRealm());
DefaultWebSecurityManager 父类 AuthorizingSecurityManager 会在 realm 设置后,赋值代理对象 authorizer
protected void afterRealmsSet() {
super.afterRealmsSet();
if (this.authorizer instanceof ModularRealmAuthorizer) {
((ModularRealmAuthorizer) this.authorizer).setRealms(getRealms());
}
}
跟进 ModularRealmAuthorizer 代码:
/**
* Sets the realms wrapped by this Authorizer which are consulted during an authorization check.
*
* @param realms the realms wrapped by this Authorizer which are consulted during an authorization check.
*/
public void setRealms(Collection realms) {
this.realms = realms;
applyPermissionResolverToRealms();
applyRolePermissionResolverToRealms();
}
很明了, 授权代理对象 Autorizer 把权限检查又交给了 realms 刚好,你自定义的 realm 就是干这事的!实现了下面 AuthorizingRealm 的两个接口:
我们需要代码实现的就是这两个抽象方法。
三、总结串下流程:
1. 用户直接访问某个资源时, 会进入 shiroFilter ,shiroFilter 会通过自定义的 PermissionsAuthorizationFilter 检查权限:首先看用户是否登录,如果没登录跳转到 loginurl 地址,否则检查 subject 中的用户权限。
2. subect 中的权限信息是,以 subject.login 方式登录后填充。具体在 securityManager 中,最后又到了 Realm 中 doGetAuthenticaitonInfo 方法中。
当然也可以结合 spring-security-oauth2 服务来登录,只需要将 loginurl 转向 AuthorizationEndpoint 对应的地址即可(通常类似 https://xxxx/oauth/authorize?client_id=xxx&response_type=code&redirect_uri=https://xxxx)
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)