Shiro中自定义Realm的作用(FormAuthenticationFilter和PermissionAuthorizationFilter)以及源码解析
来源:互联网 发布:js复选框取消选中事件 编辑:程序博客网 时间:2024/04/30 11:30
在使用shiro时都会自定义一个Realm,Realm的作用就是提供给shiro和数据库进行交互的一个中间层,这样shiro能够帮助我们处理登录(成功、失败),授权,访问控制等功能,但是用户登录的用户信息和用户具体的权限信息是shiro未知的,所以需要每次都请求Realm,由Realm提供
比如授权的流程
使用PermissionAuthorizationFilter在xml中设置权限${adminPath}/areaInfo = perms[area:query,area:add]当发出这个请求(已经验证通过)被PermisssionsAuthorizationFilter拦截,发现需要权限会调用realm的doGetAuthorizationInfo获取数据库中正确的数据库权限(所以realm的作用 就是查询,剩下的活是shiro的)PermissionAuthorizationFilter对请求的url对应的权限和从realm中获取的权限进行对比
登录和授权,realm只提供查找返回,不提供逻辑处理,都由shiro解决
拿login来分析
当请求信息是login时,FormAuthenticationFilter会对其进行拦截,解析是不是login请求,并处理
//FormAuthenticationFilter 判断是不是一个login请求 protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if (isLoginRequest(request, response)) { if (isLoginSubmission(request, response)) { if (log.isTraceEnabled()) { log.trace("Login submission detected. Attempting to execute login."); } return executeLogin(request, response); } else { if (log.isTraceEnabled()) { log.trace("Login page view."); } //allow them to see the login page ;) return true; } } else { if (log.isTraceEnabled()) { log.trace("Attempting to access a path which requires authentication. Forwarding to the " + "Authentication url [" + getLoginUrl() + "]"); } saveRequestAndRedirectToLogin(request, response); return false; } }可以看到如果是login请求会执行executeLogin方法
//AuthenticatingFilter 此处找到subject.login(token)操作 protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception { AuthenticationToken token = createToken(request, response); if (token == null) { String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " + "must be created in order to execute a login attempt."; throw new IllegalStateException(msg); } try { Subject subject = getSubject(request, response); subject.login(token);//调用了realm return onLoginSuccess(token, subject, request, response); } catch (AuthenticationException e) { return onLoginFailure(token, e, request, response); } }
//DelegatingSubject public void login(AuthenticationToken token) throws AuthenticationException { clearRunAsIdentitiesInternal(); Subject subject = securityManager.login(this, token);//调用了realm 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; } Session session = subject.getSession(false); if (session != null) { this.session = decorate(session); } else { this.session = null; } }由securityManager进行登录
重点来了
public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException { AuthenticationInfo info; try { info = authenticate(token); } catch (AuthenticationException ae) { try { onFailedLogin(token, ae, subject); } catch (Exception e) { if (log.isInfoEnabled()) { log.info("onFailedLogin method threw an " + "exception. Logging and propagating original AuthenticationException.", e); } } throw ae; //propagate } Subject loggedIn = createSubject(token, info, subject); onSuccessfulLogin(token, info, loggedIn); return loggedIn; }
我们发现public class DefaultSecurityManager extends SessionsSecurityManager
也就是上面的securityManager的实现类中调用的login,这里就是反悔了一个AuthenticationInfo对象,其中autheticate(token)这个方法继续跟踪到最后就会到达我们的自定义realm中的doGetAuthenticationInfo方法
所以这个info主要是为这行代码服务的
Subject loggedIn = createSubject(token, info, subject);即生成subject的代码
这样就完成了交互
0 0
- Shiro中自定义Realm的作用(FormAuthenticationFilter和PermissionAuthorizationFilter)以及源码解析
- shiro表单的验证 自定义FormAuthenticationFilter
- shiro 自定义FormAuthenticationFilter,记住我
- Shiro登录机制验证,自定义FormAuthenticationFilter
- (六) shiro在web中自定义Realm
- ssm和shiro整合,shiro的自定义的realm不能自动注入的问题
- Shiro使用之自定义realm的编写
- shiro自定义Realm
- Shiro入门-自定义realm
- Shiro自定义Realm
- shiro自定义Realm实现
- Shiro 自定义realm认证
- 【shiro】--- 自定义realm
- Shiro(四) 自定义Realm
- Spring Boot Shiro权限管理--自定义 FormAuthenticationFilter验证码整合
- shiro中自定义realm实现md5散列算法加密的模拟(二)
- shiro Realm以及相关对象
- shiro试用记录-FormAuthenticationFilter
- nlp文本处理开源工具,及聊天机器人实现
- ghttp作为客户端下载大文件的问题
- PHP中的会话控制(二):session
- C++ 虚函数表解析
- 简单使用Ajax实现异步查询用户名是否被占用
- Shiro中自定义Realm的作用(FormAuthenticationFilter和PermissionAuthorizationFilter)以及源码解析
- Visual Studio控制台程序输出窗口一闪而过的解决方法
- ssm整合原来的版本
- android 实现拉出回弹效果通过自定义ListView重写overScrollBy()
- [BZOJ3510][启发式合并][LCT维护子树信息]首都
- 06 无线通信概念
- jggrid可见列文件引入不好用
- java常用的Date方法
- 单独安装 PHP 的扩展