3

shiro登录认证过程讲解

 1 year ago
source link: https://blog.51cto.com/u_15941034/6005849
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

shiro登录认证过程讲解

精选 原创

先粘出登录的代码

​@RequestMapping(value="/submitLogin",method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> submitLogin(String username,String password){
System.out.println(username+"-----"+password);
String msg = "";
Map<String, Object> map = new HashMap<>();
try {
UsernamePasswordToken token = token = new UsernamePasswordToken(username, password);
char[] password1 = token.getPassword();
String s = password1.toString();

System.out.println("*******"+s);
SecurityUtils.getSubject().login(token);
token.setRememberMe(true);
map.put("status",200);
} catch (UnknownAccountException e) {
msg = "UnknownAccountException -- > 账号不存在:";
map.put("status",400);
} catch (IncorrectCredentialsException e){
msg = "IncorrectCredentialsException -- > 密码不正确:";
map.put("status",500);
}catch (Exception exception){
msg = "else >> "+exception;
System.out.println("else -- >" + exception);
}
return map;
}

可以看到已经获取到了username和password ,为了接下来的认证过程,我们需要获取subject对象,也就是代表当前登录用户,并且要将username和password两个变量设置到UsernamePasswordToken对象的token中, 调用SecurityUtils.getSubject().login(token)方法,将 token传入

接下来看看login方法的实现:

主要还是用到了securityManager安全管理器

shiro登录认证过程讲解_权限

进入securityManager里边的login方法,看看他的实现:

shiro登录认证过程讲解_缓存_02

 在这个方法中定义了AuthenticationInfo对象来接受从Realm传来的认证信息

进入authenticate方法中

public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {

       return this.authenticator.authenticate(token);

发现调用了authenticator的authenticate这个方法

进入this.authenticator.authenticate(token)这个方法中

shiro登录认证过程讲解_java_03

在这个 类中调用了这个方法,再进去看他的实现

​protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {

       this.assertRealmsConfigured();

       Collection<Realm> realms = this.getRealms();

       return realms.size() == 1?this.doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken):this.doMultiRealmAuthentication(realms, authenticationToken);

在这里才是刚才前边的那个authenticator的实现, this.assertRealmsConfigured() 这个方法是判断realm是否存在,不存在则抛出异常,他会根据realm的个数来判断执行哪个方法,上篇中springboot整合shiro我只配置了一个realm,所以他只会执行this.doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken)这个方法,并且会将 realm和token作为参数传入,这里的realm其实就是自己定义的MyShiroRealm

接下来再进入doSingleRealmAuthentication这个方法中,

shiro登录认证过程讲解_权限_04

在这里 他会先判断realm是否支持token

接下来执行else中的getAuthenticationInfo方法

shiro登录认证过程讲解_shiro_05

this.getCachedAuthenticationInfo(token)这个方法是从shiro缓存中读取用户信息,如果没有,才从realm中获取信息。如果是第一次登陆,缓存中肯定没有认证信息,所以会执行this.doGetAuthenticationInfo(token)这个方法。

查看this.doGetAuthenticationInfo(token)方法,会发现有这么几个类提供我们选择

shiro登录认证过程讲解_权限_06

其中就有我们自定义的realm,进去

shiro登录认证过程讲解_shiro_07

 所以 ,上边的doGetAuthorizationInfo是 执行的我们自定义realm中重写的doGetAuthorizationInfo这个方法。这个方法就会从数据库中读取我们所需要的信息,最后封装成SimpleAuthorizationInfo返回去。

现在获取到认证信息了,接下来就是shiro怎么去进行认证,我们返回去看

shiro登录认证过程讲解_System_08

获取 完信息之后就是进行密码匹配,进入assertCredentialsMatch方法中看一下,

shiro登录认证过程讲解_权限_09

首先 获取一个CredentialsMatcher对象,译为凭证匹配器,这个类的主要作用就是将用户输入的密码一某种计算加密。

再看一下cm.doCredentialsMatch(token,info)

shiro登录认证过程讲解_java_10

这里会用到equals方法对token中加密的密码和从数据库中取出来的info中的密码进行对比,如果认证相同就返回true,失败就返回false,并抛出AuthenticationException,将info返回到defaultSecurityManager中,到此认证过程结束。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK