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