Shiro安全框架使用

Shiro安全框架使用

1.添加依赖
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-all</artifactId>
    <version>${shiro.version}</version>
</dependency>
2.在web.xml配置文件中配置过滤器
<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
3.spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/data/jpa 
        http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <!-- 配置Shiro核心Filter  --> 
    <bean id="shiroFilter" 
        class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 安全管理器 -->
        <property name="securityManager" ref="securityManager" />
        <!-- 未认证,跳转到哪个页面  -->
        <property name="loginUrl" value="/login.html" />
        <!-- 登录页面页面 -->
        <property name="successUrl" value="/index.html" />
        <!-- 认证后,没有权限跳转页面 -->
        <property name="unauthorizedUrl" value="/unauthorized.html" />
        <!-- shiro URL控制过滤器规则  -->
        <property name="filterChainDefinitions">
            <!--
                anon 未认证可以访问   
                authc 认证后可以访问   
                perms 需要特定权限才能访问  
                roles 需要特定角色才能访问  
                user 需要特定用户才能访问   
                port 需要特定端口才能访问  
                reset 根据指定 
                HTTP 请求访问才能访问 
            -->
            <value>
                /login.html* = anon
                /user_login.action* = anon 
                /css/** = anon
                /js/** = anon
                /images/** = anon
                /services/** = anon 
                <!--
                    配置需要特定的权限;
                    配置需要特定的角色;
                -->
                /pages/base/courier.html* = perms[courier:list]
                /pages/base/area.html* = roles[base]
                /** = authc
            </value>
        </property>
    </bean>

    <!-- 安全管理器  -->
    <bean id="securityManager" 
        class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm" />
        <property name="cacheManager" ref="shiroCacheManager" />
    </bean>

    <!-- 配置Realm -->
    <bean id="bosRealm" class="cn.itcast.bos.realm.BosRealm">
        <!-- 缓存区的名字 就是 ehcache.xml 自定义 cache的name -->
        <property name="authorizationCacheName" value="bos" />
    </bean>

    <bean id="lifecycleBeanPostProcessor"
        class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!-- 开启shiro注解模式  -->
    <bean
        class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
        depends-on="lifecycleBeanPostProcessor" >
        <property name="proxyTargetClass" value="true" />
    </bean>

    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
         <property name="securityManager" ref="securityManager"/>
    </bean>

</beans>
4.基于粗粒度的权限控制
// Action代码
@Action(value = "user_login", results = {
            @Result(name = "index", type = "redirect", location = "index.html"),
            @Result(name = "login", type = "redirect", location = "login.html")})
    public String login(){
        // 获取到表单提交的数据
        //1. 构建Shiro登陆
        Subject subject = SecurityUtils.getSubject();
        //2. 构建token
        UsernamePasswordToken token =
                new UsernamePasswordToken(model.getUsername(), model.getPassword());
        //3. 基于subject登陆
        try {
            subject.login(token);
            //3.1 不报异常就登陆成功
            return "index";
        } catch (Exception e) {
            e.printStackTrace();
            //3.2 报异常说明登陆失败
            return "login";
        }
    }
// Realm类的编写, 需要继承 AuthorizingRealm接口
@Service("bosService")
public class BosRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    /**
     * 认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //1. 转换token
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        //2. 调用UserService查询用户名是否可以查询到对象
        User user = userService.findByUsername(usernamePasswordToken.getUsername());
        //3. 判断用户是否在数据库中存在, 然后再比对密码
        if(user == null){
            // 说明该用户名对象的用户不存在
            return null;
        }else {
            // 说明用户存在, 然后比对密码
            /**
             *  参数1: 期望登陆后保存在subject中的信息
             *  参数2: 如果返回null, 说明用户不存在
             *  参数3: realm名称
             */
            return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
        }
    }
}
5.基于细粒度(方法级别的)权限控制
<!--第一步: 在spring配置文件中激活注解-->
<!--开启shiro注解模式-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager"/>
</bean>
/**
     * 在Action类中的方法上添加注解:
     * @RequiresAuthentication: 验证用户是否登陆.
     * @RequiresUser: 判断用户是否被记忆.
     * @RequiresGuest: 验证是否是一个guest请求.
     * @RequiresRoles("","") 验证是否有需要的角色
     * @RequiresPermissions("","") 验证是否有需要的权限
     */
    @RequiresPermissions("courier_add")
    @Action(value = "courier_save", results = 
    @Result(name = "success", type = "redirect", location = "./pages/base/courier.html"))
    public String save() {
        System.out.println("保存业务员");
        courierService.save(courier);
        return SUCCESS;
    }
注意: 在service层添加的事务默认采用的是jdk的动态代理, 这里需要配置为cglib的动态代理
<!--开启shiro注解模式-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor">
    <property name="proxyTargetClass" value="true"/>
</bean>
6.基于自定义标签实现权限管理
<!--1. 页面中引入标签库-->
<%@taglib uri="http://shiro.apache.org.tags" prefix="shiro"%>
<!--
    <shiro:authenticated> 登录后才能访问
    <shiro:hasPermission name="abc"> 需要特定权限才能访问 
    <shiro:hasRole name="abc"> 需要特定角色才能访问 
-->
<shiro:hasPermission name="courier:add">
    <a href="#">添加</a>
</shiro:hasPermission>

猜你喜欢

转载自blog.csdn.net/Orangesss_/article/details/82319646