在Spring项目中使用Shiro身份验证

By
写代码

身份验证,现在web中普遍都采用的机制,即在应用中证明我就是我本人。记得上大学那会儿写过一些小东西,登陆就是明文记录用户名密码,然后用户输入就登陆。其实想起来流程类似,不过Shiro显然高级很多。

功能简要介绍如下:

什么是Shiro

官方网站:shiro.apache.org,已经加入apache软件全家桶。

Apache Shiro(发音为“shee-roh”(西罗?),日语“堡垒(Castle)”的意思)是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可为任何应用提供安全保障 – 从命令行应用、移动应用到大型网络及企业应用。

Shiro为解决下列问题(我喜欢称它们为应用安全的四要素)提供了保护应用的API:

认证 – 用户身份识别,常被称为用户“登录”;
授权 – 访问控制;
密码加密 – 保护或隐藏数据防止被偷窥;
会话管理 – 每用户相关的时间敏感的状态。
Shiro还支持一些辅助特性,如Web应用安全、单元测试和多线程,它们的存在强化了上面提到的四个要素。
更多介绍,请查看 这里

在shiro中,用户需要提供principals (身份)和credentials(证明)给shiro,从而应用能验证用户身份:
principals:身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/密码/手机号。
credentials:证明/凭证,即只有主体知道的安全值,如密码/数字证书等。
最常见的principals和credentials组合就是用户名/密码了。接下来先进行一个基本的身份认证。

Shiro身份验证步骤

1、收集用户身份/凭证,即如用户名/密码;
2、调用Subject.login进行登录,如果失败将得到相应的AuthenticationException异常,根据异常提示用户错误信息;否则登录成功;
3、最后调用Subject.logout进行退出操作。

Shiro Structure
Shiro身份验证流程

1、Authenticator是真正的身份验证者,Shiro API中核心的身份认证入口点,此处可以自定义插入自己的实现;
2、Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认ModularRealmAuthenticator会调用AuthenticationStrategy进行多Realm身份验证;
3、Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。

Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。如我们之前的ini配置方式将使用org.apache.shiro.realm.text.IniRealm。

Shiro默认提供的Realm结构:

Shiro Realm

一点代码

一般继承AuthorizingRealm(授权)即可。

我重写了org.apache.shiro.realm.jdbc.JdbcRealm实现,这个文件本身就包含一些关键features,只保留了加密方式和permissionsLookupEnabled等,在realm的bean声明:

其中credentialsMatcher用于信任匹配,可用于加密密码的验证。采用SHA-256方式(更改hashAlgorithmName即可,可选MD5、SHA-1、SHA-256等),注意和数据库密码加密方式一致。还可以加盐(salt)来混淆密码。

遇到一个问题,设置的unauthorizedUrl不会跳转,即碰到没有登陆的用户,会返回一个异常。一个解决办法是采用springframework的exceptionResolver来处理,相关代码如下:

Comments: 2

  1. :!: 居然是代码啊

    2016年01月22日

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

:razz: