【Shiro】05 自定义Realm认证实现

likesyour 2020-08-01

【前提情要】

Shiro默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,

大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm。

根接口:Realm

public interface Realm

缓存处理:CachingRealm

public abstract class CachingRealm implements Realm, Nameable, CacheManagerAware, LogoutAware

认证处理:AuthenticationRealm

public abstract class AuthenticatingRealm extends CachingRealm implements Initializable

授权处理:AuthorizingRealm

public abstract class AuthorizingRealm extends AuthenticatingRealm implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware

我们自定义Realm是继承AuthorizingRealm来实现:

package cn.echo42.shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * @author DaiZhiZhou
 * @file Shiro
 * @create 2020-08-01 18:38
 */
public class UserRealm extends AuthorizingRealm {

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        // 通过提交的令牌获取信息(用户名称?)
        String principal = authenticationToken.getPrincipal().toString();
        
        // 或者是业务层调取记录对象用来验证 User user=userService.queryUserByUserName(username);

        // 如果这里从数据库获取的用户名核对成功 返回一个简单的验证结果对象               // 用户名,令牌凭证(就是密码),和这个类的限定名
        if ("username".equals(principal)) return new SimpleAuthenticationInfo(principal, authenticationToken.getCredentials(), this.getName());

        // 否则返回空,表明查不到
        return null;
    }
}

然后更改我们的shiro.ini配置:

[main]
#创建userRealm对象
userRealm=com.sxt.realm.UserRealm
#把当前对象给安全管理器
#securityManager=org.apache.shiro.mgt.DefaultSecurityManager
securityManager.realm=$userRealm

测试类实现:

public static void main(String[] args) {

        log.info("My First Apache Shiro Application");


        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        defaultSecurityManager.setRealm(new UserRealm());
        SecurityUtils.setSecurityManager(defaultSecurityManager);

        Subject subject = SecurityUtils.getSubject();
        AuthenticationToken userToken = new UsernamePasswordToken(username,password);
        subject.login(userToken);

        // 通过或者异常处理

    }

【AuthenticationException体系】

AuthenticationException 异常是Shiro在登录认证过程中,认证失败需要抛出的异常。

AuthenticationException包含以下子类:
CredentitalsException 凭证异常
IncorrentCredentialsException 不正确的凭证
ExpiredCredentialsException 凭证过期

AccountException 账号异常
ConcurrentAccessException 并发访问异常(多个用户同时登录时抛出)
UnknownAccountException 未知的账号
ExcessiveAttemptsException 认证次数超过限制
DisabledAccountException 禁用的账号
LockedAccountException 账号被锁定
UnsupportedTokenException 使用了不支持的Token

相关推荐