Ⅰ shiro验证成功后 重定向到 /undefined,怎么解决
多种情况会导致【循环重定向】即302报错。你提到了shiro,在shiro最常见的情况是过滤器循环触发,检查思路:
通过浏览器debug, 找到循环访问了哪个请求【状态为302】, 根据这个请求url,修改shiro配置文件中:
bean名为[org.apache.shiro.spring.web.ShiroFilterFactoryBean]中
property名为[filterChainDefinitions]中的[value]对应的过滤值
当然也有可能是其他filter、controller类中的代码反复触发了这个url。
Ⅱ Shiro中的filter
DefaultFilter
shiro中提供的默认filter
FilterChainManager
通过配置创建对应的filterChain
Shiro通过此配置可初始化FilterChainManager中的filterChain,结构为 url ->filter列表
SpringShiroFilter
入口filter,拦截所有请求,通过请求的url匹配到对应的filterChain,然后通过Chain对请求进行,认证或者授权的处理
OncePerRequestFilter
OncePerRequestFilter 用于防止多次执行 Filter;也就是说一次请求只会走一次拦截器链;
另外提供 enabled 属性,表示是否开启该拦截器实例
实现了 doFilter 方法,提供了抽象方法 doFilterInternal 。
在doFilter中验证当前的Filter有没有执行过,如果已经执行过一次或者当前filter被禁用,则直接执行下一个Filter。如果没有执行过则执行 doFilterInternal 方法
AbstractShiroFilter
创建Subject,绑定subject到当前线程,根据url获取filterChain并执行filterChain
通过请求的url来匹配FilterChainManager中的FilterChain,这个方法会返回一个 ProxiedFilterChain
ProxiedFilterChain
存储了tomcat的Filter 和shiro内部的filter
shiro内部的过滤器执行完后会切换到tomcat的过滤器继续执行
默认filter
除了LogoutFilter,其他都继承了AdviceFilter
AdviceFilter
AdviceFilter 提供了 AOP 风格的支持,类似于 SpringMVC 中的 Interceptor:
权限验证在preHandle中实现
PathMatchingFilter
PathMatchingFilter 提供了基于 Ant 风格的请求路径匹配功能及拦截器参数解析的功能,如
“ /admin roles[admin,user] ”自动根据 “,” 分割,解析成 /admin -> [admin,user] 存入 appliedPaths 中
实现了 preHandle 方法,通过请求的url匹配url对应的权限,解析权限串 调用子类的 onPreHandle 对权限进行处理
AnonymousFilter
提供匿名访问功能,实现了 onPreHandle 直接返回true,所以配置 anon 的url任何人都可以访问
AccessControlFilter
提供了资源访问控制的基础功能
实现了 onPreHandle ,这里拆分出了
isAccessAllowed (是否允许访问)和 onAccessDenied (访问被拒绝时)这两个方法供子类实现
AuthenticationFilter
实现了 isAccessAllowed 方法,验证用户是否已经登录,没有登录将被拒绝
FormAuthenticationFilter
继承自 AuthenticationFilter 只有用户登录过后才能通过
实现了 onAccessDenied 方法,如果请求的地址是登录地址,这里会尝试自动登录,否则跳转到登录页面
BasicHttpAuthenticationFilter
提供了基于 HttpBasic认证的方式
AuthorizationFilter
实现了 onAccessDenied 方法,如果没有认证通过,则跳转到登录或者认证失败的页面
对用户所访问资源的权限进行认证
HttpMethodPermissionFilter
将HTTP请求的方法(例如GET、POST等)转换为相应的动作并构造一个相应的权限
如get 被转换为 read,put 转换为 update,post转换为create等
权限配置:/users perms[users]
请求: get /users
将会验证 用户是否拥有users:read权限
RolesAuthorizationFilter
验证用户是否用对对应的角色
UserFilter
实现了 isAccessAllowed 和 onAccessDenied 方法,验证用户是否登录过,如果验证未通过则跳转到登录页面
Ⅲ shiro过滤器/* = authc把自己写的都拦截了,走了上面的拦截器后还是会被/*拦截
我也碰到这种情来况了,,自,发现filters.put("authc", filter_Authc());这种方式注入filter的时候,拦截顺序会失效,,,要改成new xx()这种方式才可以filters.put("authc", new Filter_Authc());
Ⅳ springMvc+shiro做权限管理,页面上的静态资源,样式图片等没有出现,用几种方式过滤试过,还是不行
正常情况是不会出现这样的,shiro对于静态资源的处理,不用特殊配置。
只需要在shiroFilter过滤器filterChainDefinitions项中增加一个静态资源处理规则就可以,例如允许/css/开头的资源匿名访问,只需要这样一句配置就足矣。
/css/** = anon
配置完成后,未登录就可以在浏览器中直接访问css下的资源,新项目用的shiro,简单而又实用的权限框架。
Ⅳ spring mvc拦截器与shiro拦截器有什么区别
奉献,分享他们的经验与心得,才能让像我这样的小白有机会站一下你们这些巨人的肩膀,才能少走些弯路)。
过滤器和拦截器的区别:
①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
Ⅵ shiro原理之过滤器
这几天一直在研究Shiro到底是如何工作的,即一个请求过来了,它是如何做到知道这个请求应该用什么方式来鉴权的?应该调用哪个过滤器?自己定义的过滤器该如何才能生效?
带着这样的疑问,我做了一些测试与研究,并记录于此文。
Shiro对于请求的鉴权的实现也是通过过滤器(或者说是拦截器)来实现的,但是Spring项目中有拦截链机制,会有多个拦截器生效,包括系统内置的以及Shiro注入的,所以需要搞懂他的过滤的实现机制就需要去弄明白这些过滤器是如何过滤的。
在 ApplicationFilterChain 的 doFilter 方法下打上断点
默认过滤器
我们来看看 AbstractShiroFilter 的部分源码:
返回的是一个 ProxiedFilterChain 的实例,该实例包含了 所匹配出来的过滤器,如下图,匹配的是系统内置的名为 anon 过滤器,至于它所对应的过滤器是什么可以见上面默认过滤器的表。
接着,在 AbstractShiroFilter 中的 executeChain 就会执行它的 doFilter 方法。
刚开始学习看源码,IDEA的调试工具也不是很会用,好在确实IDEA很强大,不然这么多过滤链跳来跳去是真的难懂。经过这次的阅读以及网上的博客的研究,Shiro的过滤链如果有自定义的过滤链的话,一定不能像平常的拦截器那样注入,必须要在注入 ShiroFilterFactoryBean 时使用如下方式注入才能生效。
因为很可能像平常注入过滤器那样注入先后顺序可能会存在问题。
Ⅶ Shiro入门之拦截器机制
Shiro使用了与Servlet一样的Filter接口进行扩展,下图是 Shiro 拦截器的基础类图:
(1) NameableFilter:该拦截器的作用就是给 Filter 起一个名字,如果没有设置默认就是 FilterNmae.比如在 shiro.ini文件中[main]中的配置: authc.loginUrl=/login ,其中 authc 就是拦截器名称,当我们组装拦截器链时,会根据这个名称找到相应的拦截器实例。
(2)OncePerRequestFilter:用来防止对此执行 Filter,也就是一次请求最多只会经过该过滤器一次,另外提供 enabled 属性,表示是否开启该拦截器实例,默认 enabled=true 表示开启,如果不想让某个拦截器工作,可以设置为 false 即可。
(3) ShiroFilter:是整个 Shiro的入口点,用于拦截需要安全控制的请求。
(4)AdviceFilter:类似于 Spring中的AOP。
(5)PathMatchingFilter:提供了用于Ant 风格的请求路径匹配功能及拦截器参数解析的功能,如 “roles[admin,user]”自动根据“,”分割解析到一个路径参数配置并绑定到相应的路径(路径和对应所需要的权限)。
(6)AccessControlFilter:该过滤器提供了访问控制的基础功能,比如是否允许访问,访问拒绝之后如何处理等。
如果我们想进行访问的控制就可以继承AccessControlFilter;如果我们要添加一些通用数据我们可以直接继承 PathMatchingFilter。
Shiro 对 Servlet 容器的 FilterChain 进行了代理,即 ShiroFilter 在继续Servlet容器的Filter链的执行之前,通过 ProxiedFilterChain 对Servlet 容器的 FilterChain 进行了代理;即先走Shiro 自己的Filter体系,然后才会委托给 Servlet 容器的 FilterChain 进行 Servlet 容器级别 的 Filter 链执行;Shiro ProxiedFilterChain 执行流程:先执行 Shiro 自己的 Filter 链; 再执行 Servlet 容器的 Filter 链(即原始的 Filter)。
ProxiedFilterChain 是通过 FilterChainResolver 对 shiro.ini文件[urls]中的配置获取每个路径对应的拦截器链的。Shiro提供了一个 FilterChainResolver 的默认实现类 ,而 内部通过 FilterChainManager 维护拦截器链,比如 DefaultFilterChainManager 实现维护着 url 模式与拦截器链的关系。因此我们可以通过获取 FilterChainManager 实例进行动态动态增加 url 模式与拦截器链的关系。
DefaultFilterChainManager类会默认添加枚举类DefaultFilter中定义的拦截器。
如果要注册自定义拦截器, IniSecurityManagerFactory / WebIniSecurityManagerFactory 在启动时会自动扫描 ini 配置文件中的 [filters]/[main] 部分并注册这些拦截器到 DefaultFilterChainManager中,且创建相应的 url 模式与其拦截器关系链。
如果想要自定义拦截器链解析器 FilterChainResolver ,需要实现 WebEnvironment 接口。
Shiro 内置了很多默认的拦截器,比如身份验证、授权等相关的。默认拦截器可以参考org.apache.shiro.web.filter.mgt.DefaultFilter 中的枚举拦截器:
这些默认的拦截器可以注册,可以在 ini 文件中设置这些拦截器的属性,比如:
自定义拦截器案例
(1)自定义拦截器
(2) shiro.ini中的配置
Ⅷ 怎么自定义shiro中的过滤器来允许ajax请求后台数据
自定义过滤器:
public class extends FormAuthenticationFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
if (isLoginRequest(request, response)) {
if (isLoginSubmission(request, response)) {
return executeLogin(request, response);
} else {
// 放行 allow them to see the login page ;)
return true;
}
} else {
HttpServletRequest httpRequest = WebUtils.toHttp(request);
if (ShiroFilterUtils.isAjax(httpRequest)) {
HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
httpServletResponse.sendError(ShiroFilterUtils.HTTP_STATUS_SESSION_EXPIRE);
return false;
} else {
saveRequestAndRedirectToLogin(request, response);
}
return false;
}
}
/**
* 判断ajax请求
* @param request
* @return
*/
boolean isAjax(HttpServletRequest request){
return (request.getHeader("X-Requested-With") != null && "XMLHttpRequest".equals( request.getHeader("X-Requested-With").toString()) ) ;
}
}
封装ajax
var Error = function () {
return {
// 初始化各个函数及对象
init: function () {
},
// 显示或者记录错误
displayError: function(response, ajaxOptions, thrownError) {
if (response.status == 404) {// 页面没有找到
pageContent.load($("#hdnContextPath").val() + "/page/404.action");
} else if (response.status == 401) {// session过期
SweetAlert.errorSessionExpire();
} else if (response.status == 507) {// 用户访问次数太频繁
SweetAlert.error("您的访问次数太频繁, 请过一会再试...");
} else {//其他错误
window.location = $("#hdnContextPath").val() + "/page/500.action";
}
console.log(thrownError);
}
};
}();
jQuery(document).ready(function() {
Error.init();
});
JS的引用处如下:
App.blockUI();
$.ajax({
url: $("#hdnContextPath").val() + "/feedback/queryFeedBackDetail.action",
type: "POST",
async: false,
data: {"feedbackId": feedbackId, "userId": userId, "status": status},
success: function(data) {
// 忽略
Ⅸ 怎么不让shiro拦截所有请求
#全部不用拦截
/**=anon
推荐一套完整的Shiro Demo,免费的。
Shiro介绍文档:http://www.sojson.com/shiro
Demo已经部署到线上,ShiroDemo:http://shiro.itboy.net
管理员帐号:admin,密码:sojson.com 如果密码错误,请用sojson。PS:你可以注册自己的帐号,然后用管理员赋权限给你自己的帐号,但是,每20分钟会把数据初始化一次。建议自己下载源码,让Demo跑起来,然后跑的更快。
Ⅹ Spring Security自定义拦截器
HttpSecurity实际上就是在配置Spring security的过滤器链,比如:CSRF,CORS,表单登录等,每个配置器对应一个过滤器,可以通过HttpSecurity配置过滤器的行为。
甚至可以像CRSF一样直接关闭过滤器,例如:SessionManagement
Spring Security通过SessionManagermentConfigurer来配置SessionManagerment的行为,与SessionManagermentConfigurer类似的配置器还有CorsConfigurer,RememberMeConfigurer等,他们都实现了SecurityConfigurer的标准接口。
SessionManagementConfigurer是在configure方法中将最终的SessionManagementFilter插入过滤器链来实现会话管理的。
除了Spring security提供的过滤器外,我们还可以添加自己的过滤器以实现更多的功能,这些都是可以在HttpSecurity中实现
虽然Spring Security 的过滤器链对过滤器没有特殊要求,只要继承了Filter即可,但是在Spring体系中,推荐使用OnePerRequestFilter来实现,它可以确保一次请求只会通过一次该过滤器(Filter实际并不能保证这一点)
其实关于这个自定义Filter,我个人感觉有个比较danteng的地方,比如:我们在实现图片验证码或者一些其他的登录相关的验证码的时候,我们可能会做到在账号跟密码验证了之后对这个验证码进行验证,然后我就必须有个这种操作: http.addFilterBefore(filter,.class); 因为如果验证码验证错误,我们就不需要也没必要再往后验证了,所以我们得知道我们定义的这个验证码过滤器得在什么时候验证在哪个过滤器之前或者之后验证,那么问题来了,或许我们并不知道Spring Security给我们提供了哪些或者什么样的过滤器,我们得去记住这些过滤器,这就有点不友好了。在HttpSecurityBuilder接口中,有一段这样的注释:
非常爽眼~