Files
rikako-note/spring/Apache Shiro/Apache Shiro Authentication.md
wu xiangkai eff5492b2e 日常提交
2022-11-09 11:09:14 +08:00

4.5 KiB
Raw Blame History

Apache Shiro Authentication

Apache Shiro Authentication简介

Authentication是一个对用户进行身份认证的过程在认证过程中用户需要向应用提供用于证明用户的凭据。

Apache Authentication概念

subject

在应用的角度subject即是一个用户

principals

主体用于标识一个用户可以是username、social security nubmer等

credentials

凭据,在用户认证过程中用于认证用户的身份,可以是密码、生物识别数据(如指纹、面容等)

realms

专用于security的dao对象用于和后端的datasource进行沟通。

Shiro Authentication过程

Shiro框架的Authentication过程

  1. 收集用户的principals和credentials
  2. 向应用的认证系统提交用户的principals和credentials
  3. 认证结束之后,根据认证结果允许访问、重试访问请求或者阻塞访问

收集用户的principals和credentials

可以通过UsernamePasswordToken来存储用户提交的username和password并可以调用UsernamePasswordToken.rememberMe方法来启用Shiro的“remember-me”功能。

//Example using most common scenario:
//String username and password.  Acquire in
//system-specific manner (HTTP request, GUI, etc)
UsernamePasswordToken token = new UsernamePasswordToken( username, password );

//”Remember Me” built-in, just do this:
token.setRememberMe(true);

将收集的principals和credentials提交给认证系统

在收集完用户的principals和credentials之后需要将其提交给应用的认证系统。
在Shiro中代表认证系统的是Realm其从存放安全数据的datasource中获取数据并且对用户提交的principals和credentials进行校验。
在Shiro中该过程用如下代码表示

//With most of Shiro, you'll always want to make sure you're working with the currently
//executing user, referred to as the subject
Subject currentUser = SecurityUtils.getSubject();

//Authenticate the subject by passing
//the user name and password token
//into the login method
currentUser.login(token);

在Shiro中subject可以被看做是用户在当前执行的线程中永远有一个subject与其相关联。
可以通过SecurityUtils.getSubject()方法来获取当前执行线程相关联的subject。

在获取当前执行线程关联subject之后需要对当前subject进行身份认证通过subject.login(token)来对用户提交的principals和credentials进行Authentication

身份认证后对访问进行allow/retry authentication/block

在调用subject.login(token)之后如果身份认证成功用户将在seesion的生命周期内维持他们的identity。但是如果身份认证失败可以为抛出的异常指定不同的异常处理逻辑来定义登录失败之后的行为。

try {
    currentUser.login(token);
} catch  ( UnknownAccountException uae ) { ...
} catch  ( IncorrectCredentialsException ice ) { ...
} catch  ( LockedAccountException lae ) { ...
} catch  ( ExcessiveAttemptsException eae ) { ...
} ...  your own ...
} catch ( AuthenticationException ae ) {
    //unexpected error?
}
//No problems, show authenticated view…

rememberMe支持

Apache Shiro除了正常的Authentication流程外还支持rememberMe功能。
Shiro中Subject对象拥有两个方法isRemembered()和isAuthenticated

  • 一个remembered subject其identity和principals自上次session成功认证后就被记住
  • 一个authenticated subject其identity只在本次会话中有效

remembered和authenticated的区别

在Shiro中一个remembered subject并不代表该subject已经被authenticated。如果一个subject被remembered仅仅会向系统提示该subject可能是系统的某个用户但是不会对subject的身份提供保证。但是如果subject被authenticated该subject的identity在当前会话中已经被认证。

故而isRemembered校验可以用来执行一些非敏感的操作如用户自定义界面视图等。但是敏感性操作如金额信息和变动操作等必须通过isAuthenticated校验而不是isRemembered校验敏感性操作的用户身份必须得到认证。

logging out

在Shiro中登出操作可以通过如下代码实现

currentUser.logout(); //removes all identifying information and invalidates their session too.

当执行登出操作时Shiro会关闭当前session并且会移除当前subject的任何identity。如果在web环境中使用rememberMelogout默认会从浏览器中删除rememberMe cookie。