ssm+freemark集成shiro

来源:互联网 发布:网络推广待遇 编辑:程序博客网 时间:2024/05/17 23:30


1.导入的jar包

<!-- shiro start --><!-- freemarker + shiro(标签) begin --><dependency>    <groupId>net.mingsoft</groupId>    <artifactId>shiro-freemarker-tags</artifactId>    <version>0.1</version></dependency><!-- freemarker + shiro(标签) end --><dependency>          <groupId>org.apache.shiro</groupId>          <artifactId>shiro-core</artifactId>      </dependency>      <dependency>          <groupId>org.apache.shiro</groupId>          <artifactId>shiro-web</artifactId>      </dependency>      <dependency>          <groupId>org.apache.shiro</groupId>          <artifactId>shiro-ehcache</artifactId>      </dependency>      <dependency>          <groupId>org.apache.shiro</groupId>          <artifactId>shiro-spring</artifactId>      </dependency>    <!-- shiro end -->
2.在web.xml中加入shiro filter

    <!--Shiro过滤器-->    <filter>        <filter-name>shiroFilter</filter-name>        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>        <init-param>            <param-name>targetFilterLifecycle</param-name>            <param-value>true</param-value>        </init-param>    </filter>    <filter-mapping>        <filter-name>shiroFilter</filter-name>        <url-pattern>/*</url-pattern>        <dispatcher>REQUEST</dispatcher>        <dispatcher>FORWARD</dispatcher>    </filter-mapping>
此过滤器要放在第一个,且名称要与spring-shiro,xml中shiro filter一致

3.在freemarker中加入shiro标签

3.1新建一个FreeMarkerConfigExtend类继承FreeMarkerConfigurer,

package com.business.util;import java.io.IOException;import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;import com.jagregory.shiro.freemarker.ShiroTags;import freemarker.template.Configuration;import freemarker.template.TemplateException;public class FreeMarkerConfigExtend extends FreeMarkerConfigurer {@Override  public void afterPropertiesSet() throws IOException, TemplateException {          super.afterPropertiesSet();        Configuration cfg = this.getConfiguration();        cfg.setSharedVariable("shiro", new ShiroTags());//shiro标签        cfg.setNumberFormat("#");//防止页面输出数字,变成2,000        //可以添加很多自己的要传输到页面的[方法、对象、值]                        /*         * 在controller层使用注解再加一层判断         * 注解 @RequiresPermissions("/delete")         */                /*shiro标签*/        /**        1.游客        <@shiro.guest>          您当前是游客,<a href="javascript:void(0);" class="dropdown-toggle qqlogin" >登录</a>        </@shiro.guest> 2.user(已经登录,或者记住我登录)<@shiro.user>  欢迎[<@shiro.principal/>]登录,<a href="/logout.shtml">退出</a>  </@shiro.user>   3.authenticated(已经认证,排除记住我登录的)<@shiro.authenticated>  用户[<@shiro.principal/>]已身份验证通过  </@shiro.authenticated>   4.notAuthenticated(和authenticated相反)<@shiro.notAuthenticated>          当前身份未认证(包括记住我登录的)</@shiro.notAuthenticated> 5.principal标签(能够取到你在realm中保存的信息比如我存的是ShiroUser对象,取出其中urlSet属性)<!--需要指定property--><@shiro.principal property="urlSet"/>6.hasRole标签(判断是否拥有这个角色)<@shiro.hasRole name="admin">  用户[<@shiro.principal/>]拥有角色admin<br/>  </@shiro.hasRole> 7.hasAnyRoles标签(判断是否拥有这些角色的其中一个)<@shiro.hasAnyRoles name="admin,user,member">  用户[<@shiro.principal/>]拥有角色admin或user或member<br/>  </@shiro.hasAnyRoles> 8.lacksRole标签(判断是否不拥有这个角色)<@shiro.lacksRole name="admin">  用户[<@shiro.principal/>]不拥有admin角色</@shiro.lacksRole> 9.hasPermission标签(判断是否有拥有这个权限)<@shiro.hasPermission name="user:add">  用户[<@shiro.principal/>]拥有user:add权限</@shiro.hasPermission>10.lacksPermission标签(判断是否没有这个权限)<@shiro.lacksPermission name="user:add">  用户[<@shiro.principal/>]不拥有user:add权限</@shiro.lacksPermission> **/    }  }
3.2修改spring-mvc-servlet.xml中的freemarker配置


4.新建CustomCredentialsMatcher类继承shiro的SimpleCredentialsMatcher类,这个类作用是自定义密码验证

package com.business.shiro;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;import com.business.util.MD5Util;/**  * Description: 告诉shiro如何验证加密密码,通过SimpleCredentialsMatcher或HashedCredentialsMatcher  * @Author: zh  * @Create Date: 2017-5-9  */    public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {            @Override       public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {                     UsernamePasswordToken token = (UsernamePasswordToken) authcToken;             Object tokenCredentials = MD5Util.hmac_md5(String.valueOf(token.getPassword()));        Object accountCredentials = getCredentials(info);        //将密码加密与系统加密后的密码校验,内容一致就返回true,不一致就返回false        return equals(tokenCredentials, accountCredentials);    }      }
5.新建ShiroDbRealm类
package com.business.shiro;import java.util.List;import java.util.Set;import javax.annotation.PostConstruct;import org.apache.log4j.Logger;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.DisabledAccountException;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authc.credential.CredentialsMatcher;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.cache.CacheManager;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.SimplePrincipalCollection;import org.springframework.beans.factory.annotation.Autowired;import com.business.dao.UserDao;import com.business.entity.Menu;import com.business.entity.Role;import com.business.entity.User;import com.business.entity.UserRole;import com.business.service.sysService.MenuService;import com.business.service.sysService.RoleService;import com.business.service.sysService.UserRoleService;import com.business.service.sysService.UserService;import com.business.util.SessionUtil;import com.common.util.BizUtil;import com.google.common.collect.Sets;/** * @description:shiro权限认证 * @author:zhanghao * @date:2017/5/8 14:51 */public class ShiroDbRealm extends AuthorizingRealm {    private static final Logger LOGGER = Logger.getLogger(ShiroDbRealm.class);    @Autowired private UserService userService;    @Autowired private UserDao userDao;    @Autowired private RoleService roleService;    @Autowired private UserRoleService userRoleService;    @Autowired private MenuService menuService;        public ShiroDbRealm(CacheManager cacheManager, CredentialsMatcher matcher) {        super(cacheManager, matcher);    }        /**     * Shiro登录认证(原理:用户提交 用户名和密码  --- shiro 封装令牌 ---- realm 通过用户名将密码查询返回 ---- shiro 自动去比较查询出密码和用户输入密码是否一致---- 进行登陆控制 )     */    @Override    protected AuthenticationInfo doGetAuthenticationInfo(            AuthenticationToken authcToken) throws AuthenticationException {        LOGGER.info("Shiro开始登录认证");        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;        User user = userDao.getByName(token.getUsername());        // 账号不存在        if (user == null) {            return null;        }        // 账号未启用        if (user.getStatus() == 1) {            throw new DisabledAccountException();        }        //将用户信息保存在session中        SessionUtil.addSession(user);        UserRole userRole = userRoleService.getByUserId(user.getId());        Role role = roleService.getById(userRole.getRoleId());        // 读取用户的url和角色        Set<String> roles = Sets.newHashSet(role.getName());        List<Long> menuIds = BizUtil.stringToLongList(role.getMenu(), ",");        List<Menu> menuList = menuService.getListByIds(menuIds);        List<String> menuStr = BizUtil.extractToList(menuList, "url");                Set<String> urls = Sets.newHashSet(menuStr);        urls.remove("");        urls.remove(null);                ShiroUser shiroUser = new ShiroUser(user.getId(), user.getLoginName(), user.getUsername(), urls);        shiroUser.setRoles(roles);        // 认证缓存信息        return new SimpleAuthenticationInfo(shiroUser, user.getPassword().toCharArray(),getName());    }    /**     * Shiro权限认证     */    @Override    protected AuthorizationInfo doGetAuthorizationInfo(            PrincipalCollection principals) {        ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();                SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();        info.setRoles(shiroUser.getRoles());        info.addStringPermissions(shiroUser.getUrlSet());                return info;    }        @Override    public void onLogout(PrincipalCollection principals) {        super.clearCachedAuthorizationInfo(principals);        ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();        removeUserCache(shiroUser);    }    /**     * 清除用户缓存     * @param shiroUser     */    public void removeUserCache(ShiroUser shiroUser){        removeUserCache(shiroUser.getLoginName());    }    /**     * 清除用户缓存     * @param loginName     */    public void removeUserCache(String loginName){        SimplePrincipalCollection principals = new SimplePrincipalCollection();        principals.add(loginName, super.getName());        super.clearCachedAuthenticationInfo(principals);    }    @PostConstructpublic void initCredentialsMatcher() {//该句作用是重写shiro的密码验证,让shiro用我自己的验证-->指向重写的CustomCredentialsMatchersetCredentialsMatcher(new CustomCredentialsMatcher());}}
6.自定义shiroUser

package com.business.shiro;import java.io.Serializable;import java.util.Set;/** * @description:自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息 * @author:zhanghao * @date:2017/5/9 */public class ShiroUser implements Serializable {    private static final long serialVersionUID = -1373760761780840081L;        private Long id;    private final String loginName;    private String name;    private Set<String> urlSet;    private Set<String> roles;    public ShiroUser(String loginName) {        this.loginName = loginName;    }    public ShiroUser(Long id, String loginName, String name, Set<String> urlSet) {        this.id = id;        this.loginName = loginName;        this.name = name;        this.urlSet = urlSet;    }    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Set<String> getUrlSet() {        return urlSet;    }    public void setUrlSet(Set<String> urlSet) {        this.urlSet = urlSet;    }    public Set<String> getRoles() {        return roles;    }    public void setRoles(Set<String> roles) {        this.roles = roles;    }    public String getLoginName() {        return loginName;    }    /**     * 本函数输出将作为默认的<shiro:principal/>输出.     */    @Override    public String toString() {        return loginName;    }}
7.两个缓存类

package com.business.shiro.cache;import java.util.Collection;import java.util.Collections;import java.util.Set;import org.apache.log4j.Logger;import org.apache.shiro.cache.CacheException;import org.springframework.cache.Cache;import org.springframework.cache.Cache.ValueWrapper;/** * 使用spring-cache作为shiro缓存 * @author L.cm * */@SuppressWarnings("unchecked")public class ShiroSpringCache<K, V> implements org.apache.shiro.cache.Cache<K, V> {private static final Logger logger = Logger.getLogger(ShiroSpringCache.class);private final org.springframework.cache.Cache cache;public ShiroSpringCache(Cache cache) {if (cache == null) {throw new IllegalArgumentException("Cache argument cannot be null.");}this.cache = cache;}@Overridepublic V get(K key) throws CacheException {if (logger.isTraceEnabled()) {logger.trace("Getting object from cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass());}ValueWrapper valueWrapper = cache.get(key);if (valueWrapper == null) {if (logger.isTraceEnabled()) {logger.trace("Element for [" + key + "] is null.");}return null;}return (V) valueWrapper.get();}@Overridepublic V put(K key, V value) throws CacheException {if (logger.isTraceEnabled()) {logger.trace("Putting object in cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass());}V previous = get(key);cache.put(key, value);return previous;}@Overridepublic V remove(K key) throws CacheException {if (logger.isTraceEnabled()) {logger.trace("Removing object from cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass());}V previous = get(key);cache.evict(key);return previous;}@Overridepublic void clear() throws CacheException {if (logger.isTraceEnabled()) {logger.trace("Clearing all objects from cache [" + this.cache.getName() + "]");}cache.clear();}@Overridepublic int size() {return 0;}@Overridepublic Set<K> keys() {return Collections.emptySet();}@Overridepublic Collection<V> values() {return Collections.emptySet();}@Overridepublic String toString() {return "ShiroSpringCache [" + this.cache.getName() + "]";}}
package com.business.shiro.cache;import org.apache.log4j.Logger;import org.apache.shiro.cache.Cache;import org.apache.shiro.cache.CacheException;import org.apache.shiro.cache.CacheManager;import org.apache.shiro.util.Destroyable;/** * 使用spring-cache作为shiro缓存 * 缓存管理器 * @author L.cm * */public class ShiroSpringCacheManager implements CacheManager, Destroyable {private static final Logger logger = Logger.getLogger(ShiroSpringCacheManager.class);private org.springframework.cache.CacheManager cacheManager;public org.springframework.cache.CacheManager getCacheManager() {return cacheManager;}public void setCacheManager(org.springframework.cache.CacheManager cacheManager) {this.cacheManager = cacheManager;}@Overridepublic <K, V> Cache<K, V> getCache(String name) throws CacheException {if (logger.isTraceEnabled()) {logger.trace("Acquiring ShiroSpringCache instance named [" + name + "]");}org.springframework.cache.Cache cache = cacheManager.getCache(name);return new ShiroSpringCache<K, V>(cache);}@Overridepublic void destroy() throws Exception {cacheManager = null;}}
8.spring-shiro.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans.xsd"    default-lazy-init="true">    <description>Shiro安全配置</description>    <!--安全管理器-->    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">        <!--设置自定义Realm-->        <property name="realm" ref="shiroDbRealm"/>        <!--将缓存管理器,交给安全管理器-->        <property name="cacheManager" ref="shiroSpringCacheManager"/>        <!-- 记住密码管理 -->        <property name="rememberMeManager" ref="rememberMeManager"/>        <property name="sessionManager" ref="sessionManager"/>    </bean>    <!-- 項目自定义的Realm -->    <bean id="shiroDbRealm" class="com.business.shiro.ShiroDbRealm">        <constructor-arg index="0" name="cacheManager" ref="shiroSpringCacheManager"/>        <constructor-arg index="1" name="matcher" ref="credentialsMatcher"/>        <!-- 启用身份验证缓存,即缓存AuthenticationInfo信息,默认false -->        <property name="authenticationCachingEnabled" value="true"/>        <!-- 缓存AuthenticationInfo信息的缓存名称 -->        <property name="authenticationCacheName" value="authenticationCache"/>        <!-- 缓存AuthorizationInfo信息的缓存名称 -->        <property name="authorizationCacheName" value="authorizationCache"/>    </bean>    <!-- 记住密码Cookie -->    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">          <constructor-arg value="rememberMe"/>        <property name="httpOnly" value="true"/>        <!-- 7天,采用spring el计算方便修改[细节决定成败]! -->        <property name="maxAge" value="#{7 * 24 * 60 * 60}"/>    </bean>    <!-- rememberMe管理器  -->    <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">        <property name="cookie" ref="rememberMeCookie"/>      </bean>    <!-- Shiro Filter -->    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">        <!-- 安全管理器 -->        <property name="securityManager" ref="securityManager"/>        <!-- 默认的登陆访问url -->        <property name="loginUrl" value="/login"/>        <!-- 登陆成功后跳转的url -->        <property name="successUrl" value="/menu/index"/>        <!-- 没有权限跳转的url -->        <property name="unauthorizedUrl" value="/login"/>        <property name="filterChainDefinitions">            <value>                <!--                     anon  不需要认证                    authc 需要认证                    user  验证通过或RememberMe登录的都可以                -->                /login = anon                /favicon.ico = anon                /static/** = anon                /** = user            </value>        </property>    </bean>    <!-- 用户授权信息Cache, 采用spring-cache, 具体请查看spring-ehcache.xml、spring-redis.xml -->    <bean id="shiroSpringCacheManager" class="com.business.shiro.cache.ShiroSpringCacheManager">        <property name="cacheManager" ref="cacheManager"/>    </bean>        <!-- 会话管理器 -->    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">        <!-- 设置全局会话超时时间 半小时 -->        <property name="globalSessionTimeout" value="#{30 * 60 * 1000}"/>        <!-- url上带sessionId 默认为true --><!--         <property name="sessionIdUrlRewritingEnabled" value="false"/> -->        <property name="sessionDAO" ref="sessionDAO"/>    </bean>        <!-- 会话DAO 用于会话的CRUD -->    <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">        <!-- Session缓存名字,默认就是shiro-activeSessionCache -->        <property name="activeSessionsCacheName" value="activeSessionCache"/>        <property name="cacheManager" ref="shiroSpringCacheManager"/>    </bean>        <!-- 在方法中 注入  securityManager ,进行代理控制 -->    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">        <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>        <property name="arguments" ref="securityManager"/>    </bean>        <!-- 自定义验证 -->    <bean id="credentialsMatcher" class="com.business.shiro.CustomCredentialsMatcher"></bean>    </beans>
9.如果要再controller层中加入注解判断,还需在spring-mvc-servlet.xml中加入

    <!-- 启用shrio 控制器授权注解拦截方式 -->    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">        <property name="securityManager" ref="securityManager"/>    </bean>    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>    <!-- AOP式方法级权限检查  -->    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"          depends-on="lifecycleBeanPostProcessor">          <property name="proxyTargetClass" value="true"/>    </bean>
10.缓存的两个xml文件ehcache.xml,spring-ehcache.xml

<?xml version="1.0" encoding="UTF-8"?><ehcache updateCheck="false" dynamicConfig="false">    <diskStore path="java.io.tmpdir"/>       <cache name="authorizationCache"           maxEntriesLocalHeap="2000"           eternal="false"           timeToIdleSeconds="1800"           timeToLiveSeconds="1800"           overflowToDisk="false"           statistics="true">    </cache>    <cache name="authenticationCache"           maxEntriesLocalHeap="2000"           eternal="false"           timeToIdleSeconds="1800"           timeToLiveSeconds="1800"           overflowToDisk="false"           statistics="true">    </cache>        <cache name="activeSessionCache"           maxEntriesLocalHeap="2000"           eternal="false"           timeToIdleSeconds="1800"           timeToLiveSeconds="1800"           overflowToDisk="false"           statistics="true">    </cache>        <!-- 缓存半小时 -->    <cache name="halfHour"         maxElementsInMemory="10000"        maxElementsOnDisk="100000"         eternal="false"         timeToIdleSeconds="1800"        timeToLiveSeconds="1800"         overflowToDisk="false"         diskPersistent="false" />            <!-- 缓存一小时 -->    <cache name="hour"         maxElementsInMemory="10000"        maxElementsOnDisk="100000"         eternal="false"         timeToIdleSeconds="3600"        timeToLiveSeconds="3600"         overflowToDisk="false"         diskPersistent="false" />        <!-- 缓存一天 -->    <cache name="oneDay"         maxElementsInMemory="10000"        maxElementsOnDisk="100000"         eternal="false"         timeToIdleSeconds="86400"        timeToLiveSeconds="86400"         overflowToDisk="false"         diskPersistent="false" />        <!--        name:缓存名称。        maxElementsInMemory:缓存最大个数。        eternal:对象是否永久有效,一但设置了,timeout将不起作用。        timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。        timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。        overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。        diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。        maxElementsOnDisk:硬盘最大缓存个数。        diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.        diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。           memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。        clearOnFlush:内存数量最大时是否清除。    -->    <defaultCache name="defaultCache"        maxElementsInMemory="10000"        eternal="false"        timeToIdleSeconds="120"        timeToLiveSeconds="120"        overflowToDisk="false"        maxElementsOnDisk="100000"        diskPersistent="false"        diskExpiryThreadIntervalSeconds="120"        memoryStoreEvictionPolicy="LRU"/>        </ehcache>
<?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:cache="http://www.springframework.org/schema/cache"       xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans.xsd       http://www.springframework.org/schema/cache       http://www.springframework.org/schema/cache/spring-cache.xsd">    <!-- Spring提供的基于的Ehcache实现的缓存管理器 -->        <!-- 如果有多个ehcacheManager要在bean加上p:shared="true" -->    <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">        <property name="configLocation" value="classpath:spring/ehcache.xml"/>    </bean>        <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">        <property name="cacheManager" ref="ehcacheManager"/>        <property name="transactionAware" value="true"/>    </bean>        <!-- cache注解,和spring-redis.xml中的只能使用一个 -->    <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/></beans>
11.applicationContext.xml导入配置文件

<import resource="classpath:spring/spring-shiro.xml" /><import resource="classpath:spring/spring-ehcache.xml" />
12.LoginController控制层方法

package com.business.controller.system;import java.util.Map;import javax.annotation.Resource;import org.apache.commons.lang3.StringUtils;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.DisabledAccountException;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.UnknownAccountException;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;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.servlet.mvc.support.RedirectAttributes;import com.business.controller.BaseController;import com.business.service.sysService.UserService;import com.business.util.SessionUtil;import com.google.common.collect.Maps;@Controllerpublic class LoginController extends BaseController {    @Resource    private UserService userService;        @RequestMapping(value = "/login",method=RequestMethod.GET)    public String login() {        return "login";    }    @RequestMapping(value = "/login",method=RequestMethod.POST)    public String login(RedirectAttributes attributes, String username, String password, @RequestParam(value = "online", defaultValue = "0") Integer rememberMe) {                Map<String, Object> map = Maps.newHashMap();        if (StringUtils.isBlank(username)) {            map.put("errorInfo", "用户名不能为空");        }        if (StringUtils.isBlank(password)) {            map.put("errorInfo", "密码不能为空");        }        Subject user = SecurityUtils.getSubject();        UsernamePasswordToken token = new UsernamePasswordToken(username, username+password);        // 设置记住密码        token.setRememberMe(1 == rememberMe);        try {            user.login(token);            return "redirect:/menu/index";        } catch (UnknownAccountException e) {            map.put("errorInfo", "账号不存在!");            attributes.addFlashAttribute("error", map);            return "redirect:/login";        } catch (DisabledAccountException e) {            map.put("errorInfo", "账号未启用!");            attributes.addFlashAttribute("error", map);            return "redirect:/login";        } catch (IncorrectCredentialsException e) {            map.put("errorInfo", "密码错误!");            attributes.addFlashAttribute("error", map);            return "redirect:/login";        } catch (Throwable e) {            map.put("errorInfo", "登录异常!");            attributes.addFlashAttribute("error", map);            return "redirect:/login";        }    }        @RequestMapping(value = "/logout")    public String logout() {        SessionUtil.removeSession();        Subject subject = SecurityUtils.getSubject();        subject.logout();        return "redirect:/login";    }}
12.如何在控制层使用注解,可以在baseController中加入总的异常处理

@ExceptionHandler      public String exception(HttpServletRequest request, Exception e) {          //对异常进行判断做相应的处理          if(e instanceof AuthorizationException){              return "redirect:/logout";          }        return null;}















2 0
原创粉丝点击