Shiro認證
一,什么是認證
認證——驗證用戶身份合法性。認證過程中,用戶需要提供principals(身份實體信息)、credentials(憑據實體信息)。常用的是“實體/憑證”組合,即“用戶名/密碼”組合。
二、名詞解釋:
principal:身份(主體的標識屬性),如:用戶名、手機號、郵箱等(唯一)。
credentials:憑證(只有主體知道的安全值),如密碼/數字證書等。
三、認證過程
1,收集實體/憑據信息
2,提交實體/憑據信息
3,認證處理——提交成功,允許訪問;否則重新進行身份認證或阻止訪問
1,收集實體/憑據信息
UsernamePasswordTokentoken = new UsernamePasswordToken(
user.getUsercode(),EncryptUtils.encryptMD5(user.getPassword()));
token.setRememberMe(true);
2,提交實體/憑據信息
SubjectcurrentUser = SecurityUtils.getSubject();
currentuser.login(token);
3,認證處理——提交成功,允許訪問;否則重新進行身份認證或阻止訪問
try {
currentUser.login(token);
} catch ( UnknownAccountException uae ) { ...
} catch ( IncorrectCredentialsException ice ){ ...
} catch (LockedAccountException lae ) { ...
} catch (ExcessiveAttemptsException eae ) { ...
} catch your own ...
} catch (AuthenticationException ae ) {
}
流程總結:
1、首先收集實體/憑據信息,再通過Subject.login(token)提交認證進行登錄,其會自動委托給 Security Manager;
2、SecurityManager負責真正的身份驗證邏輯;它會委托給 Authenticator進行身份驗證(subject.isAuthenticated()判斷用戶是否已驗證都將返回 true);若Subject.login(token)順利執行,并沒有拋出任何異常,即認證通過;
注:(1)Authenticator才是真正的身份驗證者,Shiro API 中核心的身份認證入口點,此處可以自定義插入自己的實現;
(2)Authenticator可能會委托給相應的 AuthenticationStrategy進行多Realm身份驗證,默認ModularRealmAuthenticator會調用 AuthenticationStrategy進行多 Realm 身份驗證;
(3)Authenticator會把相應的 token 傳入 Realm,從 Realm獲取身份驗證信息,如果沒有返回/拋出異常表示身份驗證失敗了。此處可以配置多個 Realm,將按照相應的順序及策略進行訪問。
四,部分示例代碼
@Controller @RequestMapping(value= "login") public classLoginController { /* * @Autowired User user; */ /** * 用戶登錄 * * @param user * 登錄用戶 * @return */ @RequestMapping(params= "main") publicModelAndView login(User user,HttpSession session, HttpServletRequest request) { ModelAndViewmodelView = new ModelAndView(); SubjectcurrentUser = SecurityUtils.getSubject(); UsernamePasswordTokentoken = new UsernamePasswordToken( user.getUsercode(),EncryptUtils.encryptMD5(user.getPassword())); token.setRememberMe(true); try { currentUser.login(token); } catch ( UnknownAccountException uae ) { ... } catch (IncorrectCredentialsException ice ) { ... } catch (LockedAccountException lae ) { ... } catch (ExcessiveAttemptsException eae ) { ... } catchyour own ... } catch (AuthenticationException ae ) { } }
自定義Realm實現:
@Service("monitorRealm") public class MonitorRealm extends AuthorizingRealm { @Resource private UserService userService; //登錄認證 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)throws AuthenticationException { UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token; String username = String.valueOf(usernamePasswordToken.getUsername()); User user = userService.findByUserName(username); //業務方法,通過用戶名獲取用戶實體信息 AuthenticationInfo authenticationInfo = null; if (null != user) { String password = new String(usernamePasswordToken.getPassword()); if (password.equals(user.getPassword())) { authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(), getName()); } } return authenticationInfo; } }
五,總結
通過shiro提供的實體及API進行身份認證。
來自:http://blog.csdn.net/hanxuemin12345/article/details/45192715