版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35608780/article/details/71703176
就是自定义过滤规则 一些特殊的请求路径 需要进过自定义的过滤器 在自定义的过滤器中 认证规则是自己定的
spring文件:
<!-- 引入数据源 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 配置数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="5" />
</bean>
<!-- 自定义的shiro 过滤器 -->
<bean id="phoneFilter" class="cn.neusoft.filter.UserPhoneFilter">
<property name="userdao" ref="userDao"></property>
</bean>
<!-- Shiro的过滤器工厂BEAN : 间接地加载9个内置过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 安全管理器 :Shiro的核心组件,相当于大脑 -->
<property name="securityManager" ref="securityManager" />
<!-- 认证相关: 指定登陆页面,当用户未登陆时访问资源,则自动跳转到此页面 -->
<property name="loginUrl" value="/login.jsp" />
<!-- 授权相关:指定错误页面,当用户登陆后访问没有权限的资源时,自动跳转到此页面 -->
<property name="unauthorizedUrl" value="/error.html" />
<property name="filters">
<map>
<entry key="phone" value-ref="phoneFilter" />
</map>
</property>
<!-- 过滤器链定义:指定页面的访问规则 -->
<property name="filterChainDefinitions">
<value>
/userphone/login.action =anon
/user/login.action = anon
/login.jsp =anon
/user/all.action = authc
<!-- 添加的权限 -->
/user/goadd.action =perms["add"]
/user/add.action =perms["add"]
<!-- 修改的权限 -->
/user/goedit.action =perms["update"]
/user/update.action =perms["update"]
<!-- 删除的权限 -->
/user/delete.action =perms["delete"]
/userphone/* =phone
/userphone/select.action =authc
/userphone/add.action=perms["add"]
/userphone/update.action =perms["update"]
/userphone/delete.action =perms["delete"]
/*.html = authc
/*.action = authc
/* = authc
</value>
</property>
</bean>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="userRealm"></property>
</bean>
<!-- 自定义Realm -->
<bean id="userRealm" class="cn.neusoft.realm.UserRealm">
<property name="userService" ref="userService"></property>
<property name="user" ref="user"></property>
</bean>
</beans>
我们自定义了一个phoneFilter 在过滤器链中匹配到时 就会到该过滤器中执行
public class UserPhoneFilter extends AuthenticationFilter{
private UserDao userdao;
public void setUserdao(UserDao userdao) {
this.userdao = userdao;
}
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
String sessionid = request.getParameter("sessionid");
//1.没有sessionid 2.有sessionid 数据库没数据 3.有sessionid 数据库有数据 没有用户 4.有用户 没权限执行
//判断sessionid是否存在 如不存在返回路径错误
if(sessionid.equals("")){
Map map = jsonReturn(false,"没有登录记录,请重新登陆");
try {
response.getWriter().print(JSON.toJSONString(map));
return false;
} catch (IOException e) {
e.printStackTrace();
}
}
PhoneId phoneId = userdao.getsession(sessionid);
if(phoneId==null){
//如果sessionid存在 数据库没查到 返回身份过期
Map map = jsonReturn(false,"登录信息过期,请重新登录");
try {
response.getWriter().print(JSON.toJSONString(map));
return false;
} catch (IOException e) {
e.printStackTrace();
}
}
//数据库中根据sessionid取登陆对象
//不为空 从数据库查到当前登陆对象
User user = userdao.selectone(phoneId.getUid().toString());
if(user==null){
//通过用户ID查不到 可能已删除
Map map = jsonReturn(false,"用户信息有问题,请重新登陆");
try {
response.getWriter().print(JSON.toJSONString(map));
return false;
} catch (IOException e) {
e.printStackTrace();
}
}
//------------------------------------------------------------------------------
Subject subject = getSubject(request, response);
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword());
subject.login(token);
//------------------------------------------------------------------------------
String path = getPathWithinApplication(request);
String string = path.substring(11, path.length());
String caozuo = string.substring(0, string.indexOf("."));
//------------------------------------------------------------------------------
System.out.println(caozuo);
System.out.println("第二过滤器!!");
//对象也从数据库查到了 出错的唯一可能就是当前对象没有权限执行
if(subject.isPermitted(caozuo)){
return true;
}else{
Map map = jsonReturn(false,"该用户没有权限执行当前资源");
try {
response.getWriter().print(JSON.toJSONString(map));
} catch (IOException e) {
}
return false;
}
}
//isAccessAllowed 方法返回false 执行
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse reponse) throws Exception {
System.out.println("没成功!!!!!!!!!");
return false;
}
public Map jsonReturn(boolean type,String message){
Map map = new HashMap<Boolean, String>();
map.put("success", type);
map.put("value", message);
return map;
}
}
在自定义的过滤器中 有两个方法会先执行isAccessAllowed()方法 这个方法中如果放回false才会执行onAccessDenied() 如果放回true的话程序就会无条件执行 我们一般在isAccessAllowed()方法中执行授权
方法 subject.isPermitted(caozuo) 这个方法会执行授权方法执行成功的话放回true 执行失败的话放回false 执行onAccessDenied()方法