My custom UserRealm inherits from AuthorizingRealm, which inherits from AuthenticatingRealm, which inherits from AuthenticatingRealm

CachingRealm.

When logging in with the subject.login() method, the Subject calls the Login method of the securityManager, if using its default implementation class DefaultSecurityManager,

The Authenticate method is called in the Login method of DefaultSecurityManager for authentication. The Authenticate method is its DefaultSecurityManager parent

Method of AuthenticatingSecurityManager AuthenticatingSecurityManager interface combines the authenticator: the authenticator,

Then call the authenticator. Authenticate (token), the authenticator of abstract implementation AbstractAuthenticator call doAuthenticate (token) method,

This method will to invoke the shiro provides AbstractAuthenticator subclasses ModularRealmAuthenticator doAuthenticate (token) method.

It goes back and determines how many Reaml are registered with Shiro, and I only have one here, so there’s no validation policy involved. And then it calls

DoSingleRealmAuthentication (realms. The iterator (). The next (), the authenticationToken) method,

DoSingleRealmAuthentication method again to call realm. GetAuthenticationInfo (token);

AuthenticatingRealm: getAuthenticationInfo UserRealm: getAuthenticationInfo UserRealm: getAuthenticationInfo

The first call to the cache will be null, and the second call will only be cached. So he went back to my custom UserReaml doGetAuthenticationInfo method, but I made a password check in there, and if the password is incorrect, it throws an exception, so it’s not possible to execute CredentialsMatcher, This is why CredentialsMatcher is not used. Realm cannot make password judgments, but it can make other judgments and throw exceptions.

/**
     * This implementation functions as follows:
     * <ol>
     * <li>It attempts to acquire any cached {@link AuthenticationInfo} corresponding to the specified
     * {@link AuthenticationToken} argument.  If a cached value is found, it will be used for credentials matching,
     * alleviating the need to perform any lookups with a data source.</li>
     * <li>If there is no cached {@link AuthenticationInfo} found, delegate to the
     * {@link #doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)} method to perform the actual
     * lookup.  If authentication caching is enabled and possible, any returned info object will be
     * {@link #cacheAuthenticationInfoIfPossible(org.apache.shiro.authc.AuthenticationToken, org.apache.shiro.authc.AuthenticationInfo) cached}
     * to be used in future authentication attempts.</li>
     * <li>If an AuthenticationInfo instance is not found inthe cache or by lookup, {@code null} is returned to * indicate an account cannot be found.</li> * <li>If an AuthenticationInfo instance is found  (either cached or via lookup), ensure the submitted * AuthenticationToken's credentials match the expected {@code AuthenticationInfo}'s credentials using the
     * {@link #getCredentialsMatcher() credentialsMatcher}. This means that credentials are always verified
     * for an authentication attempt.</li>
     * </ol>
     *
     * @param token the submitted account principal and credentials.
     * @return the AuthenticationInfo corresponding to the given {@code token}, or {@code null} if no
     *         AuthenticationInfo could be found.
     * @throws AuthenticationException if authentication failed.
     */
    public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        AuthenticationInfo info = getCachedAuthenticationInfo(token);
        if (info == null) {
            //otherwise not cached, perform the lookup:
            info = doGetAuthenticationInfo(token);
            log.debug("Looked up AuthenticationInfo [{}] from doGetAuthenticationInfo", info);
            if(token ! = null && info ! = null) { cacheAuthenticationInfoIfPossible(token, info); }}else {
            log.debug("Using cached authentication info [{}] to perform credentials matching.", info);
        }

        if(info ! = null) { assertCredentialsMatch(token, info); }else {
            log.debug("No AuthenticationInfo found for submitted AuthenticationToken [{}]. Returning null.", token);
        }

        return info;
    }
Copy the code

DoGetAuthenticationInfo method in UserRealm

 @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String email = token.getPrincipal().toString();

        User userDB = userService.findByEmail(email);

        if (userDB == null) {
            throw new UnknownAccountException("Email can't be found.");
        }

        if (userDB.getStatus() == ReturnValue.ACCOUNT_NOT_ACTIVATED.getCode()){
            throw new DisabledAccountException("User not active");
        }

        if(! userDB.equals(token.getCredentials().toString())){ throw new IncorrectCredentialsException("Password error");
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userDB.getEmail(),userDB.getPassword(), getName());

//        if(userDB.getSalt() ! = null) { // info.setCredentialsSalt(ByteSource.Util.bytes(userDB.getSalt())); / /}return info;

    }
Copy the code