Shiro入门-shiro与spring整合

引入jar

<!-- shiro核心jar -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.3.2</version>
</dependency>

<!-- shiro对web的支持 -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-web</artifactId>
    <version>1.3.2</version>
</dependency>

<!-- shiro与spring整合jar -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.3.2</version>
</dependency>

配置web.xml

<!-- shiro的filter -->
<!-- shiro过滤器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来 -->
<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <!-- 设置true由servlet容器控制filter的生命周期 -->
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
    <!-- 设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean-->
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>shiroFilter</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

配置spring-shiro.xml
注意:Shiro 集成 Spring 应该添加到父上下文中去,而不能添加到 Spring MVC 的子上下文中。

<!-- web.xml中shiro的filter对应的bean -->
<!-- Shiro 的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager" />
    <!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
    <property name="loginUrl" value="/login.action" />
    <!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 -->
    <property name="successUrl" value="/first.action"/>
    <!-- 通过unauthorizedUrl指定没有权限操作时跳转页面-->
    <property name="unauthorizedUrl" value="/refuse.jsp" />
    <!-- 自定义filter配置 -->
    <property name="filters">
        <map>
            <!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中-->
            <entry key="authc" value-ref="formAuthenticationFilter" />
        </map>
    </property>

    <!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
    <property name="filterChainDefinitions">
        <value>
            <!-- 对静态资源设置匿名访问 -->
            /images/** = anon
            /js/** = anon
            /styles/** = anon
            <!-- 验证码,可匿名访问 -->
            /validatecode.jsp = anon

            <!-- 请求 logout.action地址,shiro去清除session-->
            /logout.action = logout
            <!--商品查询需要商品查询权限 ,取消url拦截配置,使用注解授权方式 -->
            <!-- /items/queryItems.action = perms[item:query]
            /items/editItems.action = perms[item:edit] -->
            <!-- 配置记住我或认证通过可以访问的地址 -->
            /index.jsp  = user
            /first.action = user
            /welcome.jsp = user
            <!-- /** = authc 所有url都必须认证通过才可以访问-->
            /** = authc
            <!-- /** = anon所有url都可以匿名访问 -->

        </value>
    </property>
</bean>

<!-- securityManager安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="customRealm" />
    <!-- 注入缓存管理器 -->
    <property name="cacheManager" ref="cacheManager"/>
    <!-- 注入session管理器 -->
    <property name="sessionManager" ref="sessionManager" />
    <!-- 记住我 -->
    <property name="rememberMeManager" ref="rememberMeManager"/>    
</bean>

<!-- realm -->
<bean id="customRealm" class="cn.itcast.ssm.shiro.CustomRealm">
    <!-- 将凭证匹配器设置到realm中,realm按照凭证匹配器的要求进行散列 -->
    <property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean>

<!-- 凭证匹配器 -->
<bean id="credentialsMatcher"
    class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
    <property name="hashAlgorithmName" value="md5" />
    <property name="hashIterations" value="1" />
</bean>

<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    <property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
</bean>

<!-- 会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
     <!-- session的失效时长,单位毫秒 -->
     <property name="globalSessionTimeout" value="600000"/>
     <!-- 删除失效的session -->
     <property name="deleteInvalidSessions" value="true"/>
</bean>

<!-- 自定义form认证过虑器 -->
<!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
<bean id="formAuthenticationFilter" 
    class="cn.itcast.ssm.shiro.CustomFormAuthenticationFilter ">
    <!-- 表单中账号的input名称 -->
    <property name="usernameParam" value="username" />
    <!-- 表单中密码的input名称 -->
    <property name="passwordParam" value="password" />
    <!-- 记住我input的名称 -->
    <property name="rememberMeParam" value="rememberMe"/>
</bean>

<!-- rememberMeManager管理器,写cookie,取出cookie生成用户信息 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
    <property name="cookie" ref="rememberMeCookie" />
</bean>

<!-- 记住我cookie -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
    <!-- rememberMe是cookie的名字 -->
    <constructor-arg value="rememberMe" />
    <!-- 记住我cookie生效时间30天 -->
    <property name="maxAge" value="2592000" />
</bean>

配置springmvc.xml

<!-- 开启aop,对类代理 -->
<aop:config proxy-target-class="true"></aop:config>
<!-- 开启shiro注解支持 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager" />
</bean>


对静态资源设置逆名访问

<!-- 对静态资源设置匿名访问 -->
/images/** = anon
/js/** = anon
/styles/** = anon

登陆原理
使用FormAuthenticationFilter过虑器实现 ,原理如下:

将用户没有认证时,请求loginurl进行认证,用户身份和用户密码提交数据到loginurl
FormAuthenticationFilter拦截住取出request中的username和password(两个参数名称是可以配置的
FormAuthenticationFilter调用realm传入一个token(username和password)
realm认证时根据username查询用户信息(在Activeuser中存储,包括 userid、usercode、username、menus)。
如果查询不到,realm返回null,FormAuthenticationFilter向request域中填充一个参数(记录了异常信息)
登陆页面
由于FormAuthenticationFilter的用户身份和密码的input的默认值(username和password),修改页面的账号和密码 的input的名称为username和password
也可以配置:

<!-- 自定义form认证过虑器 -->
<!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
<bean id="formAuthenticationFilter" 
    class="cn.itcast.ssm.shiro.CustomFormAuthenticationFilter ">
    <!-- 表单中账号的input名称 -->
    <property name="usernameParam" value="username" />
    <!-- 表单中密码的input名称 -->
    <property name="passwordParam" value="password" />
    <!-- 记住我input的名称 -->
    <property name="rememberMeParam" value="rememberMe"/>
</bean>

登录代码实现

//登陆提交地址,和spring-shiro.xml中配置的loginurl一致
@RequestMapping("login")
public String login(HttpServletRequest request)throws Exception{

    //如果登陆失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名
    String exceptionClassName = (String) 
            request.getAttribute("shiroLoginFailure");
    //根据shiro返回的异常类路径判断,抛出指定异常信息
    if(exceptionClassName!=null){
        if (UnknownAccountException.class.getName()
            .equals(exceptionClassName)) {
            //最终会抛给异常处理器
            throw new CustomException("账号不存在");
        } else if (IncorrectCredentialsException.class.getName()
            .equals(exceptionClassName)) {
                throw new CustomException("用户名/密码错误");
        } else if("randomCodeError".equals(exceptionClassName)){
                throw new CustomException("验证码错误 ");
        }else {
                throw new Exception();//最终在异常处理器生成未知错误      
        }
    }
    //此方法不处理登陆成功(认证成功),shiro认证成功会自动跳转到上一个请求路径
    //登陆失败还到login页面
    return "login";
}

退出使用LogoutFilter
不用我们去实现退出,只要去访问一个退出的url(该 url是可以不存在),由LogoutFilter拦截住,清除session。

在spring-shiro.xml配置LogoutFilter:

<!-- 请求 logout.action地址,shiro去清除session-->
/logout.action = logout

问题总结

  1. 在spring-shiro.xml中配置过滤器链接,需要将全部的url和权限对应起来进行配置,比较发麻不方便使用。
  2. 每次授权都需要调用realm查询数据库,对于系统性能有很大影响,可以通过shiro缓存来解决。

shiro的过虑器

过滤器简称 对应的java类:
anon org.apache.shiro.web.filter.authc.AnonymousFilter
authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port org.apache.shiro.web.filter.authz.PortFilter
rest org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
roles org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl org.apache.shiro.web.filter.authz.SslFilter
user org.apache.shiro.web.filter.authc.UserFilter
logout org.apache.shiro.web.filter.authc.LogoutFilter

anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,FormAuthenticationFilter是表单认证,没有参数
perms:例子/admins/user/=perms[user:add:],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/=perms[“user:add:,user:modify:*”],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
user:例如/admins/user/**=user没有参数表示必须存在用户, 身份认证通过或通过记住我认证通过的可以访问,当登入操作时不做检查

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值