Shiro身份认证的流程

时间:2022-09-23 23:34:12

Shiro身份认证流程如下:请看Shiro架构图

Shiro身份认证的流程


登录的时候-------->给Security Manager进行管理----------------->Authenticator----------------------->Authentication Strategy---------------------->各种Realm


什么叫做Realm?

Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。


一个例如如下:

单Realm

shiro-realm.ini 文件内容如下:

[main]

#声明一个realm

myRealm=com.lgy.shiro.MyRealm
#指定securityManager的realms实现

securityManager.realms=$myRealm

自定义Realm实现如下:

package com.lgy.shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.Realm;

public class MyRealm implements Realm {
public String getName() {
return "myrealm1";
}

public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken; //仅支持UsernamePasswordToken类型的Token
}

public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

String username = (String)token.getPrincipal(); //得到用户名
String password = new String((char[])token.getCredentials()); //得到密码
if(!"zhang".equals(username)) {
throw new UnknownAccountException(); //如果用户名错误
}
if(!"123".equals(password)) {
throw new IncorrectCredentialsException(); //如果密码错误
}
//如果身份认证验证成功,返回一个AuthenticationInfo实现;
return new SimpleAuthenticationInfo(username, password, getName());
}
}

以上3个方法是继承Realm的接口:

    String getName(); //返回一个唯一的Realm名字  
boolean supports(AuthenticationToken token); //判断此Realm是否支持此Token
AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException; //根据Token获取认证信息


测试类如下:

@Test
public void testCustomRealm() {
// 1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
// 2、得到SecurityManager实例 并绑定给SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory
.getInstance();
SecurityUtils.setSecurityManager(securityManager);

// 3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");

try {
// 4、登录,即身份验证
subject.login(token);
} catch (AuthenticationException e) {
// 5、身份验证失败
e.printStackTrace();
}

Assert.assertEquals(true, subject.isAuthenticated()); // 断言用户已经登录

// 6、退出
subject.logout();
}