Apache Shiro 安全框架(4)-与web集成

本文介绍了如何将Apache Shiro安全框架与Web应用进行集成,包括添加shiro-spring依赖,配置shiro,设置URL规则,以及使用shiro的注解进行权限管理。详细讲述了登录控制器的实现,URL通配符的规则,以及如何启用注解鉴权。

要将shiro与web集成必须要添加shiro-spring依赖:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.0</version>
</dependency>

配置shiro

import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 结合spring,shiro完成web的认证和授权
 */
@Configuration
public class ShiroConfig {

    @Bean
    public DefaultSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(definedRealm());
        return securityManager;
    }

    @Bean
    public DefinedRealm definedRealm(){
        DefinedRealm realm = new DefinedRealm();
        return realm;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilter(){
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager());
        shiroFilter.setLoginUrl("/login");//设置登录URL
        shiroFilter.setUnauthorizedUrl("/403");//设置未授权URL
        shiroFilter.setSuccessUrl("/index");//设置登录成功后跳转URL

        //设置拦截的路径
        Map<String,String> filterChain = new LinkedHashMap<>();
        filterChain.put("/logout","logout");
        filterChain.put("/css/**","anon");
        filterChain.put("/fonts/**","anon");
        filterChain.put("/images/**","anon");
        filterChain.put("/js/**","anon");
        filterChain.put("/login","anon");
        filterChain.put("/list","roles[frame]");
        filterChain.put("/**","authc");//设置在最后,按照顺序判断,如果匹配则返回
        shiroFilter.setFilterChainDefinitionMap(filterChain);

        return shiroFilter;
    }
}

登录控制器:

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class LoginController {

    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String login(){
        System.out.println("首页登录");
        return "login";
    }

    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(String username,String password){
        System.out.println("开始验证登录信息,username " + username );
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","123");
        try {

            subject.login(token);
            return "index";
        }catch (Exception e){
            e.printStackTrace();
        }
        return "login";

    }

    @RequestMapping("/index")
    public String index(){
        System.out.println("登录成功");
        return "index";
    }

    @RequestMapping("/403")
    public String error(){
        System.out.println("请先登录");
        return "403";
    }
}

以上简单实现了shiro和web的集成。集合以上shiro配置代码和POST请求方式的login()方法,与上一节的登录控制器比较,发现其实我们只是将realm和securityManager的Bean交个spring容器来管理。

上一节登录控制器如下:

 DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //设置realm
        securityManager.setRealm(definedRealm);
        //绑定securityManager到securityUtils
        SecurityUtils.setSecurityManager(securityManager);
        //创建登录实体
        Subject subject = SecurityUtils.getSubject();
        //创建登录token
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","01d7f40760960e7bd9443513f22ab9af");
        //登录
        subject.login(token);

并且再配置ShiroFilterFactoryBean。通过该类来配置我们loginUrl、UnauthorizedUrl、SuccessUrl,以及用户访问时需要认证和鉴权的URL。

配置URL的规则

配置URL通配符的规则:

  • ?、*、**,注意通配符匹配不包括目录分隔符“/”
  • ?:匹配一个字符,如 /admin? 将匹配 /admin1,但不匹配 /admin 或 /admin/;
  •  *:匹配零个或多个字符串,如 /admin* 将匹配 /admin、/admin123,但不匹配 /admin/1;
  • **:匹配路径中的零个或多个路径,如 /admin/** 将匹配 /admin/a 或 /admin/a/b

后面的选项只能在下面的 表格中选择:

首先是认证相关,当我们配置认证相关过滤器时,如果没有认证通过将会跳转到我们配置的loginUrl。常用authc过滤器

其次是授权相关的,当我们配置如下过滤器,鉴权没通过是,将会跳转到配置的UnauthorizedUrl。一般很少使用,因为使用注解会更方便


上面提到了注解做鉴权,下面来看看如何使用shiro的注解鉴权。

shiro中注解的使用

首先是启用shiro-spring的aop,在shiro配置类中增加如下配置:

 /**
     * Spring的一个bean,有advisor决定对那些类实现AOP代理
     * 配置通过注解完成权限和角色验证
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisor = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisor.setProxyTargetClass(true);
        return defaultAdvisor;
    }

    /**
     * shiro类的实现Advisor的类,开启shiro的注解支持
     * 内部使用AopAllianceAnnotationsAuthorizingMethodInterceptor
     * 拦截@RequiredRoles,@RequiredPermission注解的方法
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager());
        return advisor;
    }

    /**
     * shiro生命周期处理器
     * @return
     */
    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

在loginController中增加如下接口:

   @RequiresRoles("admin")
    @RequestMapping("list")
    public String list(){
        return "list";
    }

当我们登录成功后,再去访问该接口时,如果当前登录用户没有该角色将会抛出org.apache.shiro.authz.AuthorizationException异常。

以上就是shiro和web的初步结合,下一节来探讨shiro中会话管理


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值