Java安全框架——Apache Shiro(九)

98 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

在真实的项目中,角色与权限都存放在数据库中。为了快速上手,我们先创建一个自定义DefinitionRealm,模拟它已经登录成功。直接返回一个登录验证凭证,告诉Shiro框架,我们从数据库中查询出来的密码是也是就是你输入的密码。所以,不管用户输入什么,本次登录验证都是通过的。

  /**
     * @Description 认证接口
     * @param token 传递登录token
     * @return
     */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    //从AuthenticationToken中获得登录名称
    String loginName = (String) token.getPrincipal();
    SecurityService securityService = new SecurityServiceImpl();
    Map<String, String> map = securityService.findPasswordByLoginName(loginName);
    if (map.isEmpty()){
        throw new UnknownAccountException("账户不存在");
    }
    String salt = map.get("salt");
    String password = map.get("password");
    //传递账号和密码:参数1:用户认证凭证信息,参数2:明文密码,参数三:字节salt,参数4:当前DefinitionRealm名称
    return  new SimpleAuthenticationInfo(loginName,password, ByteSource.Util.bytes(salt),getName());
}

好了,接下来,我们要重写我们本小节的核心方法了。在DefinitionRealm中找到下列方法:

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    return null;
}

此方法的传入的参数PrincipalCollection principals,是一个包装对象,它表示"用户认证凭证信息"。包装的是谁呢?没错,就是认证doGetAuthenticationInfo()方法的返回值的第一个参数loginName。你可以通过这个包装对象的getPrimaryPrincipal()方法拿到此值,然后再从数据库中拿到对应的角色和资源,构建SimpleAuthorizationInfo。

/**
     * @Description 授权方法
     */
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    //拿到用户认证凭证信息
    String loginName = (String) principals.getPrimaryPrincipal();
    //从数据库中查询对应的角色和资源
    SecurityService securityService = new SecurityServiceImpl();
    List<String> roles = securityService.findRoleByloginName(loginName);
    List<String> permissions = securityService.findPermissionByloginName(loginName);
    //构建资源校验
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    authorizationInfo.addRoles(roles);
    authorizationInfo.addStringPermissions(permissions);
    return authorizationInfo;
}

【2】案例演示

【2.1】需求
1、实现doGetAuthorizationInfo方法实现鉴权
2、使用subject类实现权限的校验
【2.2】实现
【2.2.1】创建项目

拷贝shiro-day01-05-ciphertext-realm新建shiro-day01-06-authentication-realm

【2.2.2】编写SecurityService

在SecurityService中添加

 	/**
     * @Description 查找角色按用户登录名
     * @param  loginName 登录名称
     * @return
     */
List<String> findRoleByloginName(String loginName);

	/**
     * @Description 查找资源按用户登录名
     * @param  loginName 登录名称
     * @return
     */
List<String>  findPermissionByloginName(String loginName);

SecurityServiceImpl添加实现

@Override
public List<String> findRoleByloginName(String loginName) {
    List<String> list = new ArrayList<>();
    list.add("admin");
    list.add("dev");
    return list;
}

@Override
public List<String>  findPermissionByloginName(String loginName) {
    List<String> list = new ArrayList<>();
    list.add("order:add");
    list.add("order:list");
    list.add("order:del");
    return list;
}