shiro整合spring

来源:互联网 发布:域名dns劫持 编辑:程序博客网 时间:2024/06/05 08:42

shiro整合spring的配置

shiro整合spring配置主要分为以下几个步骤:

  • 1.在web.xml中配置shiro过滤器并配置监听
  • 2.在spring-shiro.xml中配置与1中同名的bean
  • 3.配置自定义realm并关联到安全管理器中
  • 4.将安全管理器绑定到securityUtils中
  • 5.配置subject工厂
  • 6.配置会话管理器
  • 7.配置shiro注解
  • 8.自定义realm

一.在web.xml中配置shiro过滤器并配置监听

1.shiro过滤器配置

 <filter>    <filter-name>shiroFilter</filter-name>    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>    <init-param>      <!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->      <param-name>targetFilterLifecycle</param-name>      <param-value>true</param-value>    </init-param>  </filter>  <filter-mapping>    <filter-name>shiroFilter</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping>

2.设置监听

 <context-param>    <param-name>contextConfigLocation</param-name>    <param-value>      classpath:spring.xml,      classpath:spring-shiro.xml    </param-value>  </context-param>  <listener>    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  </listener>

二.在spring-shiro.xml中配置与web.xml中与过滤器同名的bean

<!-- 此bean要被web.xml引用,和web.xml中的filtername同名 -->    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">        <property name="securityManager" ref="securityManager"/>        <property name="loginUrl" value="/welcome/index" /> <!-- 没有认证返回地址 -->        <property name="successUrl" value="/hrm/welcome/manage" />        <property name="unauthorizedUrl" value="/index2.jsp" /> <!-- 没有授权返回地址 -->        <!--自定义的filter-->        <property name="filters">            <map>                <entry key="logout" value-ref="logoutFilter"/>            </map>        </property>        <property name="filterChainDefinitions">            <value>            <!-- **代表任意子目录 -->                /welcome/** = anon -->                /api/** = anon -->                 /educate/** = authc,roles[admin] -->                <!--/users/** = authc-->                /logout=logout            </value>        </property>    </bean>

三.配置自定义realm并关联到安全管理器中

1配置自定义realm

<bean id="authRealm" class="com.jointem.hrm.auth.HrmRealm"/>

2.关联到安全管理器中

<!-- 安全管理 -->    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">        <!-- Single realm app.  If you have multiple realms, use the 'realms' property instead. -->        <property name="realm" ref="authRealm"/><!-- 引用自定义的realm -->    </bean>

四.将安全管理器绑定到securityUtils中

<!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">        <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>        <property name="arguments" ref="securityManagerForMobile"/>    </bean>

五.配置subject工厂

<!-- Subject工厂 -->    <bean id="subjectFactory" class="com.jointem.hrm.mgt.StatelessDefaultSubjectFactory"/>

六.配置会话管理器

<!-- 会话管理器 -->    <bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager">        <property name="sessionValidationSchedulerEnabled" value="false"/>    </bean>

七.配置shiro注解

<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/><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>

八.自定义realm如下

package com.jointem.hrm.auth;/** * Created by dartagnan on 17/8/2. */import com.jointem.hrm.common.MD5Tools;import com.jointem.hrm.entity.Permissions;import com.jointem.hrm.entity.Roles;import com.jointem.hrm.entity.Users;import com.jointem.hrm.service.UserService;import org.apache.commons.lang3.StringUtils;import org.apache.commons.lang3.builder.ReflectionToStringBuilder;import org.apache.commons.lang3.builder.ToStringStyle;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;import org.apache.shiro.authz.AuthorizationException;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.session.InvalidSessionException;import org.apache.shiro.session.Session;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.SimplePrincipalCollection;import org.apache.shiro.subject.Subject;import org.apache.shiro.util.CollectionUtils;import org.springframework.beans.factory.annotation.Autowired;import sun.security.provider.MD5;import java.io.Serializable;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;/** * 自定义的指定Shiro验证用户登录的类 * @create * @author */public class HrmRealm extends AuthorizingRealm {    @Autowired    private UserService userService;    /**     * 获取身份信息,我们可以在这个方法中,从数据库获取该用户的权限和角色信息     */    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {        String username = (String) getAvailablePrincipal(principals);        //我们可以通过用户名从数据库获取权限/角色信息        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();        Users user=userService.findUsersByName(username);        //数据库查询:权限集合,角色集合        Set<String> s = new HashSet<String>();        Set<String> r = new HashSet<String>();        for(Roles role:user.getRolesList())        {            r.add(role.getDescription());            for(Permissions permisson:role.getPermissionsList())            {                s.add(permisson.getUrl());            }        }//        s.add("users:top");//        s.add("users:left");//        s.add("users:main");//        r.add("admin");        info.setStringPermissions(s);        info.setRoles(r);        return info;    }    /**     * 在这个方法中,进行身份验证     */    @Override    protected AuthenticationInfo doGetAuthenticationInfo(            AuthenticationToken token) throws AuthenticationException {        //用户名        String username = (String) token.getPrincipal();        //密码        String password = new String((char[])token.getCredentials());        //从数据库获取用户名密码进行匹配        Users user = userService.getByUsername(username);        if(!user.getUsername().equals(username)){            throw new UnknownAccountException();        }        if(!user.getPassword().equals(MD5Tools.MD5(password))){            throw new IncorrectCredentialsException();        }        //身份验证通过,返回一个身份信息        AuthenticationInfo aInfo = new SimpleAuthenticationInfo(username,password,getName());        setSession("user", user);        return aInfo;    }    /**     * 保存登录名     */    private void setSession(Object key, Object value){        Session session = getSession();        System.out.println("Session默认超时时间为[" + session.getTimeout() + "]毫秒");        if(null != session){            session.setAttribute(key, value);        }    }    private Session getSession(){        try{            Subject subject = SecurityUtils.getSubject();            Session session = subject.getSession(false);            if (session == null){                session = subject.getSession();            }            if (session != null){                return session;            }        }catch (InvalidSessionException e){        }        return null;    }}