<!--[if !supportLists]-->1、 前面已经介绍完了创建subject用户和封装shiro自己的session,这里介绍用户的登录和退出。
<!--[endif]-->直登录直接调用subject.login(token)方法即可,因为我们在创建subject的时候就把securityManager传入到了subject中,所以subject可以调用securManager的方法,当调用login时,就会调用securityManager会调用里面的login方法。
我们使用的securityManager是DefaultSecurityManager的子类DefaultWebSecurityManager,所以调用的是defaultsecurityManager中的login方法,它里面继续调用了authenticate方法,这个方法的实现在其父类AuthenticatingSecurityManager中,这个类中有一个属性authenticator是Authenticator类型的,然后在构造方法中会生成一个ModularRealmAuthenticator。这里看一下authenticator类和ModularRealmAuthenticator类。
我们看一下他的authenticator的实现AbstractAuthenticator,他的里面有个属性listeners,用户捕获用户的登录失败,登录成功的事件,然后进行相应的处理,当用户退出的时候也会进行通知。
这个类中最重要的方法就是authenticate方法,里面调用了doAuthenticate方法,该方法在ModularRealmAuthenticator类的实现,先看一下这个类的构造方法
public ModularRealmAuthenticator() {
this.authenticationStrategy = new AtLeastOneSuccessfulStrategy();
}
生成一个登录校验的策略——只要有一个realm校验成功即可。这个是用于多个reaml时才会用到的,如果我们配置了一个realm时不用管他。继续看他的实现的doAuthenticate方法。
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
assertRealmsConfigured();
Collection<Realm> realms = getRealms();//
if (realms.size() ==1) {
return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);
} else {
return doMultiRealmAuthentication(realms, authenticationToken);
}
}
里面有个方法getRealms方法,所以我们必须知道他是如何传入的realm,可以在setRealms方法上打上断点然后debug,我们暂时不管它。
他是根据我们配置的realm的个数来区分调用的,因为我们都是只配一个realm,所以我们只看doSingleRealmAuthentication方法即可:
protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) {
if (!realm.supports(token)) {
String msg = "Realm [" + realm + "] does not support authentication token [" +
token + "]. Please ensure that the appropriate Realm implementation is " +
"configured correctly or that the realm accepts AuthenticationTokens of this type.";
thrownew UnsupportedTokenException(msg);
}
AuthenticationInfo info = realm.getAuthenticationInfo(token);
if (info == null) {
String msg = "Realm [" + realm + "] was unable to find account data for the " +
"submitted AuthenticationToken [" + token + "].";
thrownew UnknownAccountException(msg);
}
returninfo;
}
可以发现这个方法就是调用的传入的realm的getAuthenticationInfo方法。
所以现在的关键是得到如何传入的realm。从断点可以发现,在
.RealmSecurityManager.setRealms(Collection<Realm>)这个方法中会执行afterRealmSet方法,而在AuthenticatingSecurityManager.afterRealmsSet()方法中会将传入的realm添加到authenticator(也就是ModularRealmAuthenticator)中,所以我们就明白了校验调用的方法就是传入的realm的getAuthenticationInfo方法。
protectedvoid afterRealmsSet() {
super.afterRealmsSet();
if (this.authenticatorinstanceof ModularRealmAuthenticator) {
((ModularRealmAuthenticator) this.authenticator).setRealms(getRealms());
}
}
<!--[if !supportLists]-->2、 <!--[endif]-->在登陆之后会继续修改产生的subject,添加的属性有isAuthenticated,authenticationToken。authenticationInfo.在登陆成功之后会将发送的rememberMe的cookie重新发送,然后将校验通过的信息保存在session中.这个在DefaultSecurityManager中的login方法中可以发现。
<!--[if !supportLists]-->3、 <!--[endif]-->退出:我也是用debug的方法来查看的org.apache.shiro.subject.support.DelegatingSubject.logout()调用的是这个方法,源码如下:
try {
clearRunAsIdentitiesInternal();
this.securityManager.logout(this);//调用的还是securityManager,就是创建subject时绑定的securityManager。
} finally {
this.session = null;
this.principals = null;
this.authenticated = false;
}
我们查看一下调用的securityManager的logout。
beforeLogout(subject);//这个最终调动的是cookierememberMeManager的forgetIdentity方法,将cookie删掉。
PrincipalCollection principals = subject.getPrincipals();
if (principals != null && !principals.isEmpty()) {
Authenticator authc = getAuthenticator();
if (authcinstanceof LogoutAware) {
((LogoutAware) authc).onLogout(principals);//这个最终调用的是cacherealm中清楚缓存的authenticationInfo的方法,将之前缓存的信息清楚掉,当然我们默认是禁用了验证信息的缓存的。
}
}
try {
delete(subject);//这个是将把session中缓存的principalCollection和登录状态删掉。
} catch (Exception e) {
Xxx
} finally {
try {
stopSession(subject);//这个最终调用的是将httpSeesion销毁,即httpSession.invalidate();
} catch (Exception e) {
xxxx
}
}
}
可以发现,如果用户最后调用了logout,则下一次无法通过cookie获得用户信息了。
相关推荐
本人提供这个Shiro + SpringMvc + Mybatis + Redis 的Demo 本着学习的态度,如果有欠缺和不足的地方,给予指正,并且多多包涵。 “去其糟粕取其精华”。如果觉得写的好的地方就给个赞,写的不好的地方,也请多多包涵...
在这个"shiro登录/退出demo(web应用)"项目中,我们将深入理解Shiro如何在Web环境中处理用户登录与退出操作。 首先,项目的构建环境基于Eclipse IDE,这是一个广泛使用的Java开发工具,便于代码编写、调试和项目管理...
- **登录/退出**:这是Shiro中最基础的操作之一,通过配置Shiro的`LoginController`等类来实现用户登录和注销的过程。 - **身份认证流程**: - **Realm**:Realm是Shiro的核心概念之一,它是Shiro与应用安全数据的...
这份"Shiro学习笔记"可能包含了以下主题: - Shiro的安装与配置 - Shiro基本概念详解 - Realm的创建与使用 - 登录与登出流程 - 权限控制机制 - 缓存管理和会话管理 - Shiro与Spring的整合 - Shiro的Filter链配置 - ...
### Shiro 学习心得与应用实践 #### 一、Shiro 认证与权限管理基础 Apache Shiro 是一个强大且易用的 Java 安全框架,它提供了认证(Authentication)、授权(Authorization)、加密(Cryptography)以及会话管理...
7. **Remember Me服务**:允许用户在退出后重新登录时仍保持之前的身份,通常通过Cookie实现。 在"shiro-master"的源码中,我们可以找到以下几个关键部分: 1. **core模块**:包含Shiro的基本组件,如Subject、...
6. **退出登录**:通过调用`Subject.logout()`,用户会话会被清理,用户被登出。 在"shiro权限案例demo"中,你可能还会发现一些辅助类,比如过滤器(Filter),它们用于拦截HTTP请求并执行权限检查。例如,`shiro-...
- **登录/退出**:实现用户的登录与注销功能。 - **认证流程**:用户提交身份凭证后,Shiro 进行验证。 - **Realm**:数据源接口,用于获取用户信息。 - **Authenticator**:负责实际的身份验证工作。 - **...
在身份认证方面,Shiro提供了一套完整的认证流程,包括环境准备、登录和退出等。它还涉及到了REALM的使用,REALM在Shiro中充当着“域”的角色,用于获取安全数据,比如用户、角色和权限等。Shiro还提供了多种身份...
- **Subject**:代表用户,是Shiro与应用程序交互的主要接口。 #### 七、与Web集成 - **Shiro Filter**:Shiro与Web应用集成的关键点之一,用于处理HTTP请求的过滤。 - **Web INI配置**:专门针对Web应用的配置文件...
在“Shiro学习第一式身份验证1(HelloWorld)”中,我们将探讨如何通过 Shiro 进行基本的身份验证设置,实现一个简单的 "Hello, World!" 示例。 1. **Shiro 框架介绍**: Apache Shiro 是一款轻量级的安全框架,它...
- **登录与登出**:Shiro提供`login()`和`logout()`方法,方便实现用户登录和退出功能。 6. **Shiro的实战应用** - **权限控制**:通过`@RequiresPermissions`、`@RequiresRoles`等注解实现方法级别的权限控制。 ...
Apache Shiro是一个强大且易用的Java安全框架,它提供了认证、授权、加密和会话管理功能,可以非常轻松地开发出足够安全的应用。...学习和掌握Shiro框架,将有助于提升Java应用的安全性和用户体验。
- **登录/退出**:实现用户的登录和登出功能。 - **身份认证流程**:定义用户登录时的验证步骤。 - **授权流程**:定义用户访问资源时的权限检查过程。 #### 六、Shiro的高级特性 - **拦截器机制**:自定义拦截器...
5. **登录与注销**:编写登录和注销的Controller,调用Shiro提供的API进行登录验证和用户退出。 6. **权限控制**:使用Shiro的注解(如`@RequiresAuthentication`、`@RequiresPermissions`、`@RequiresRoles`等)来...
《退出Web框架:Spring MVC、Hibernate与Shiro的深度整合》 在当今的Web开发领域,Spring MVC、Hibernate和Shiro是三个极为重要的组件。它们分别在MVC设计模式、对象关系映射(ORM)以及应用程序安全方面发挥着关键...
5. **登录退出逻辑**:确保用户登录、注销操作的正确性,防止会话劫持和会话固定攻击。 6. **状态感知**:在页面和API接口中,利用Shiro提供的工具判断用户是否已登录,实现权限控制。 7. **测试**:进行充分的...
在Shiro中,我们经常与Subject交互,而不是直接与用户交互。 2. SecurityManager是Shiro架构的核心,是Shiro框架安全操作的引擎。所有的Subject实例在幕后都是由SecurityManager实例来管理的。Shiro提供了多种...