架构

核心是SecurityManager
认证是通过调用Authenticator来实现的,authenticator内部又是调用realm的doGetAuthenticationInfo实现
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);}}doSingleRealmAuthenticationAuthenticationInfo info = realm.getAuthenticationInfo(token);info = doGetAuthenticationInfo(token);//SimpleAccountRealm.javaprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {UsernamePasswordToken upToken = (UsernamePasswordToken) token;SimpleAccount account = getUser(upToken.getUsername());if (account != null) {if (account.isLocked()) {throw new LockedAccountException("Account [" + account + "] is locked.");}if (account.isCredentialsExpired()) {String msg = "The credentials for account [" + account + "] are expired";throw new ExpiredCredentialsException(msg);}}return account;}//拿到AuthenticationInfo后使用assertCredentialsMatch(token,info)进行账户、密码比对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;}//assertCredentialsMatch(token,info)内部又调用了SimpleCredentialsMatcher.doCredentialsMatch比对public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {Object tokenCredentials = getCredentials(token);Object accountCredentials = getCredentials(info);return equals(tokenCredentials, accountCredentials);}
同理,授权也是通过调用authorizer来实现,authorize内部调用realm的doGetAuthorizationInfo实现
认证

package com.twx.shiro;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.mgt.DefaultSecurityManager;import org.apache.shiro.realm.SimpleAccountRealm;import org.apache.shiro.subject.Subject;import org.junit.Before;import org.junit.Test;public class AuthenticationTest {SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();@Beforepublic void addUser(){simpleAccountRealm.addAccount("mark","123456");}@Testpublic void testAuthentication(){//1.构建SecruityManager环境DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();defaultSecurityManager.setRealm(simpleAccountRealm);//2. 主体提交认证请求SecurityUtils.setSecurityManager(defaultSecurityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("mark","123456");subject.login(token);System.out.println("isAuthenticated: "+subject.isAuthenticated());subject.logout();System.out.println("isAuthenticated: "+subject.isAuthenticated());}}
授权

package com.twx.shiro;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.mgt.DefaultSecurityManager;import org.apache.shiro.realm.SimpleAccountRealm;import org.apache.shiro.subject.Subject;import org.junit.Before;import org.junit.Test;public class AuthenticationTest {SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();@Beforepublic void addUser(){simpleAccountRealm.addAccount("mark","123456","admin","dev");}@Testpublic void testAuthentication(){//1.构建SecruityManager环境DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();defaultSecurityManager.setRealm(simpleAccountRealm);//2. 主体提交认证请求SecurityUtils.setSecurityManager(defaultSecurityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("mark","123456");subject.login(token);System.out.println("isAuthenticated: "+subject.isAuthenticated());// subject.checkRole("admin");subject.checkRoles("admin","dev");subject.logout();System.out.println("isAuthenticated: "+subject.isAuthenticated());}}
