龙空技术网

Shiro学习系列(三):shiro登陆认证及授权

诗意凌风 200

前言:

当前你们对“shiro认证每次请求都要”大概比较讲究,同学们都需要学习一些“shiro认证每次请求都要”的相关内容。那么小编在网摘上汇集了一些对于“shiro认证每次请求都要””的相关资讯,希望我们能喜欢,小伙伴们一起来学习一下吧!

回顾

上节我们整合了shiro与web,没有经过认证访问接口,最后都会重定向到我们自定义的登陆页面,点击shiro与web整合 可以查看上节内容,那么本节我们继续接上节内容来实现我们的登陆认证,以及登陆后接口的访问权限控制。为方便测试,以下都简写了,不与数据库交互。

shiro配置

在上一节中,我们配置的是所有的请求都需要经过认证后才能访问,现在我们需要将登陆接口排除掉,就是无论是谁都可以访问登陆接口,改写如下

    @Bean    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager) {        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();        shiroFilterFactoryBean.setSecurityManager(securityManager);        shiroFilterFactoryBean.setLoginUrl("/test/login");        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();        filterChainDefinitionMap.put("/test/login","anon");        filterChainDefinitionMap.put("/**","authc");        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);        return shiroFilterFactoryBean;    }

我们只需要加入filterChainDefinitionMap.put("/test/login","anon") 这一行代码就可以了,其中anon表示的是AnonymousFilter ,表示请求都会放行。现在我们写个测试类来测试下。我在TestController.java 中新增2个方法,一个是去到登陆页的,一个是处理登陆的提交,如下:

    @GetMapping("/login")    public String toLogin() {        return "login";    }    @PostMapping("/login")    public String login(String username, String password) {        UsernamePasswordToken token = new UsernamePasswordToken(username, password);        Subject subject = SecurityUtils.getSubject();        subject.login(token);        return "/index";    }

其中UsernamePasswordToken 是 AuthenticationToken 的一种实现,还记得我们在第一节中讲到的几个核心对象的方法吗,此处就是通过subject.login(token)将登陆委托给SecurityManager#login方法登陆。

另外,我们还需要在自定义的UserRealm类中修改下认证的逻辑,这里为了测试,我们就将用户名和密码写死,其实这里是要和数据库交互的,从数据库中查询用户名密码和你提交的进行比对,这是后面的事了,这里就简写了。

    @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {        System.out.println("=============认证==============");        SimpleAuthenticationInfo info = null;        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;        if(token.getUsername().equals("admin")) {            info = new SimpleAuthenticationInfo("admin", "123", getName());        } else if (token.getUsername().equals("user")) {            info = new SimpleAuthenticationInfo("user", "123", getName());        }        return info;    }

这里就用SimpleAuthenticationInfo 包装下基本信息返回就可以了。这里我们给了两个用户,admin和user,密码都是123。

测试-1

启动服务访问,分别用这2个用户登陆,都能跳到首页,在首页中有增删查改四个接口,而且这2个用户登陆后都能访问,点击新增则到新增页面,如下

首页接口

但是现在有一个问题,就是我想其中某些接口只能由某个人能访问,比如说删除接口只能由admin访问,其他的接口admin和user只要登陆了就可以访问,改如何实现呢?这就是我们下面要讲的授权,只有你有这个接口的权限才能访问。

授权

我们继续更改shiro配置

    @Bean    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager) {        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();        shiroFilterFactoryBean.setSecurityManager(securityManager);        shiroFilterFactoryBean.setLoginUrl("/test/login");        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();        filterChainDefinitionMap.put("/test/login","anon");        filterChainDefinitionMap.put("/test/delete","roles[admin]");        filterChainDefinitionMap.put("/**","authc");        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);        return shiroFilterFactoryBean;    }

增加filterChainDefinitionMap.put("/test/delete","roles[admin]") 这一行代码,其中roles[admin] roles 表示RolesAuthorizationFilter 过滤器,admin 表示一个角色,如果有多个,用逗号分隔;此处表示/test/delete 需要admin角色的才可以访问。

然后再更改下UserRealm的授权方法,这里如果登陆的是admin,就给admin角色,是user就给user角色。

    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {        System.out.println("=============授权==============");        String username = (String) principalCollection.getPrimaryPrincipal();        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();        if(username.equals("admin")) {            info.addRole("admin");        }else if (username.equals("user")) {            info.addRole("user");        }        return info;    }
测试-2

启动服务,先用admin登陆,一次点击增删查改四个接口,发现都可以访问;再用user登陆,访问增查改三个接口都能访问,访问删除接口的时候,出现以下页面,红框里的意思我想大家都明白,未授权,禁止访问,这与我们期望的相符。

错误页面

这里问题又来了,难道未授权的人访问我都要给他展示这样一个页面吗?可以想象下,老板看到你的基操后的处理动作。那该怎样处理这种未授权的呢?以下有2种方法。

自定义未授权页面方法一:只需要在shiro配置中,在shiroFilterFactoryBean方法中加上shiroFilterFactoryBean.setUnauthorizedUrl("/test/unauth"), 然后写个控制器跳转即可。方法二:在根路径下新建个error.html, 然后自定义上提示信息就OK了。

这里我们使用方法二测试下,结果如下:

未授权页面

结尾

由于文章长度限制,就到这里了。今天我们讲解了认证登陆及角色授权访问的问题,但是如果某个用户拥有此角色,我又想他必须拥有某权限 才能访问,比如删除接口,必须拥有admin角色和删除权限才让你访问,又该如何实现呢?

喜欢的小伙伴记得关注下,我们下节讲解[机智]

标签: #shiro认证每次请求都要 #shiro登录认证流程 #shiro登录过程 #shiro认证流程包括哪些步骤 #shiro实现登陆