Shiro实现用户认证
登录成功,则前往index页面
登录失败,输出失败原因
Controller计算Token实现登录
- 新建登录路由
/user/login
- 使用
SecurityUtils
获取当前用户 - 使用
UsernamePasswordToken
的构造方法,传入username和password来生成Token
- 用
Token
登录,会进入UserRealm
的认证方法
- 使用
- 登录页面
- 添加表单提交路由地址
- 如果登陆失败,显示失败原因
自定义Realm查询用户名密码
获取Controller计算好的token,
- 从token获取用户名、密码
查询数据库获取用户信息
- 查询用户名、密码
认证
调用
token.getUsername
认证用户名,失败return null,自动抛出UnknownAccountException
异常密码认证Shiro自动完成
返回类型
AuthenticationInfo
是一个接口,我们返回它的实现类SimpleAuthenticationInfo
Simple中可以传四个参数也可以传三个参数。三个参数省略
盐
第一个参数,有的人传的是userInfo对象对用的用户名。在学习过程中,传入的都是user对象,没有尝试过对象对应的用户名,但是从前辈们的经验看得到,此处也可以传用户名,因人而异吧。
第二个参数,传的是从数据库中获取的password,然后再与token中的password进行对比,匹配上了就通过,匹配不上就报异常。
第三个参数,盐–用于加密密码对比,–获取的经验:为了防止两用户的初始密码是一样的, –巨佬们的解答:四个参数,防止两用户可能初始密码相同时候用,token 用simplehash(四个参数的构造) 加密默认用了MD5 迭代一次加密,info中在密码比对调用new SimpleHash(String algorithmName, Object source)这个实例化对象默认迭代一次了,所以当你用三个参数加密时候可能两 个初始密码相同人的就没能区别开 (因此realm中密码要从数据库的查的原因),通过设置reaml 中credentialsMatcher 属性的各项属性可实现
第四个参数:当前realm的名字。
—ps:第一个参数可以直接通过token.getPrincipal()方法获取—获取当前记录的用户名,从这个用户名获取一系列的对应需求属性。
public class UserRealm extends AuthorizingRealm {@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println("执行了<<授权>>方法");return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {System.out.println("执行了<<认证>>方法");//查询数据库获得用户数据String username = "root";String password = "123456";UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;if (!token.getUsername().equals(username)) {return null; //Shiro自动抛出 UnknownAccountException}//密码认证,shiro会自动做return new SimpleAuthenticationInfo("", password, "");}}
测试
- index.ftl