shiro 做为一个轻量级的安全认证,权限框架,与spring有很好的兼容性 具体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>
</filter-mapping>
上面实在web.xml中配置shiro 的过滤器 这里需要注意的是filter-name 标签 里面的名字必须和之后用到shiro 的bean 名字保持一致
既然用到这当然少不了 spring 的配置
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param><listener>spring.xml 文件配置
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener><?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<import resource="spring-shiro.xml"/>
</beans>
这里是将spring.xml 和spring-shiro.xml 配置文件写在src 目录下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-3.0.xsd" default-lazy-init="true"> <!-- shiro安全管理器 设置cacheManage,下列属性有实现CacheManagerAware接口的,都会自动注入缓存管理器--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="myRealm" /> <property name="cacheManager" ref="cacheManager" /> </bean> <!-- 項目自定义的Realm --> <bean id="myShiroRealm" class="com.zyc.shiro.realm.MyRealm"> <property name="cacheManager" ref="cacheManager" /> </bean> <!-- Shiro Filter --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> //此属性必须存在 <property name="loginUrl" value="/login.do" /> //如果不存在默认调用web-inf 文件下的login.jsp <property name="successUrl" value="/loginsuccess.do" /> //登录成功跳转路径 <property name="unauthorizedUrl" value="/error.html" /> //没有权限跳转路径 <property name="filters"> //此属性可以省略 这里配置主要可以通过直接提交表单验证,就可以不用subject.login(token)手动调用了<map><!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中 --><entry key="authc" value-ref="formAuthenticationFilter" /></map></property> <property name="filterChainDefinitions"> <value> //这里你可以设置是否需要认证 /js/*=anon /logout = logout /** = authc </value> </property> </bean> <!-- 用户授权信息Cache --> <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" /> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean> </beans> 如果上面配置了filter 自定义的属性那么就需要实现一个bean<bean id="formAuthenticationFilter"class="com.zyc.interceptor.shiro.CustomFormAuthenticationFilter "> //自己实现的filter 需要继承其他类FormAuthenticationFilter<!-- 表单中账号的input名称 --><property name="usernameParam" value="loginname" /> //这里的value 需要和登录的表单中的名称保存一直<!-- 表单中密码的input名称 --><property name="passwordParam" value="password" /><!-- 记住我input的名称 --><property name="rememberMeParam" value="saveid" /></bean>
下面看myRelam 类package com.zyc.shiro.realm;import java.util.HashSet;import java.util.Set;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;public class MyRealm extends AuthorizingRealm {/* * 授权 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { Set<String> roleNames = new HashSet<String>(); Set<String> permissions = new HashSet<String>(); roleNames.add("administrator");//添加角色 permissions.add("user:all"); //添加权限 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames); info.setStringPermissions(permissions); return info; }/* * 登录验证 */@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {UsernamePasswordToken token = (UsernamePasswordToken) authcToken; //连接数据库从后台获取用户信息这里就不连接数据库了 if(token.getUsername().equals("用户名")){return new SimpleAuthenticationInfo("用户名", "密码"(此密码是从数据库中获得的), getName()); //如果验证通过则返回信息}else{throw new AuthenticationException(); }}}
这里就不在配置"com.zyc.interceptor.shiro.CustomFormAuthenticationFilter类了 我们才用手动登录
及subject.login(token) 的方式登录如在你要登录的地方调用
UsernamePasswordToken token = new UsernamePasswordToken(username, DecriptUtil.MD5(password)); //这里需要将密码进行加密 如果你在配置文件中配置了加密则这里就不 用了如果没有 就需要加密
Subject currentShiro= SecurityUtils.getSubject();
if (!currentShiro.isAuthenticated()){
//使用shiro来验证
currentShiro.login(token);//验证角色和权限
}
最后在说一句退出的方法 currentShiro.logout(); 即可