cas认证过滤器shiro
1. shiro过滤器/* = authc把自己写的都拦截了,走了上面的拦截器后还是会被/*拦截
我也碰到这种情况了,,,发现filters.put("authc", filter_Authc());这种方式注入filter的时候,拦截顺序会失效回,,,要改成答new xx()这种方式才可以filters.put("authc", new Filter_Authc());
2. springside4.1的shiro+cas会陷入认证死循环,跳到cas服务器登陆后无法打开页面.Firefox提示请求循环重定
尊敬的用户,您好!很高兴为您答疑。
您在利用cas开发单点登录系统时,不应该使用跨域的跳转,如果因为服务器部署架构的问题,不得不跨域也该考虑利用接口进行数据传递。而您贴出来的实例bean亦或滤镜等代码,并不会对于您浏览器的跳转产生实质的影响。您的主要问题是在地址重定向上出现了逻辑上的死循环。
希望我的回答对您有所帮助,如有疑问,欢迎继续咨询我们。
3. shiro cas 重定向循环 怎么解决的 哥们
多种情况会导致【循环重定向】即302报错。你提到了shiro,在shiro最常见的情况是过滤器循环触发,检查思路:
通过浏览器debug, 找到循环访问了哪个请求【状态为302】, 根据这个请求url,修改shiro配置文件中:
bean名为[org.apache.shiro.spring.web.ShiroFilterFactoryBean]中
property名为[filterChainDefinitions]中的[value]对应的过滤值
当然也有可能是其他filter、controller类中的代码反复触发了这个url。
【建议写一个能够捕获所有请求的类,例如HandlerInterceptorAdapter类,在preHandle方法中,获取每次请求的url,有助于快速定位存在问题的uri,再找到触发这个请求的源头。】
4. sso和shiro的区别
SSO是单点登录,Shiro是权限管理,但是配合CAS可以实现SSO
推荐一套完整的Shiro Demo,免费的。
Shiro介绍文档:http://www.sojson.com/shiro
Demo已经部署到线上,ShiroDemo:http://shiro.itboy.net
管理员帐号:admin,密码:sojson.com 如果密码错误,请用sojson。PS:你可以注册自己的帐号,然后用管理员赋权限给你自己的帐号,但是,每20分钟会把数据初始化一次。建议自己下载源码,让Demo跑起来,然后跑的更快。
5. shiro和cas整合,web.xml怎么配置
一、前言
Apache Shiro与Spring Security一样是Java的一个安全框架。那为什么与Spring整合却用Shiro?不要问为什么,任性!开个玩笑:D 其实我个人是认为Spring Security太过于笨重,要写太多的过滤器。我是个怕麻烦的人,Shiro的配置简单这就是我选择的理由,何况Spring官方自己都推荐使用Shiro。而Shiro权限控制与CAS单点登录的组合更是堪称Java安全中的***~( ̄_, ̄ )……但本文只介绍它们三者的整合配置(说白了就是给自己留个学习笔记啦),若对此方面内容感兴趣的可以到网上搜索学习,在此推荐开涛大神的:《跟我学shiro》。
再次强调,以下内容仅为个人学习笔记,不是篇教程。
二、配置
Shiro最主要的就是认证与授权,而CAS的重点在于单点登录,其实CAS与Shiro整合的话就是关于认证那块的整合。
我们先来看web.xml中Shiro与CAS的配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!-- 引入详情配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/cas-client-shiro.xml
</param-value>
</context-param>
<!-- shiro配置 (需写在Spring MVC Servlet配置之前)-->
<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>
spring mvc servlet配置……
<!-- 退出 -->
<filter>
<filter-name>logoutFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>logoutFilter</filter-name>
<url-pattern>/logout</url-pattern>
</filter-mapping>
<!-- 该过滤器用于实现单点登出功能,可选配置。-->
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>singleSignOutFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
………………其它配置省略………………
在上面的配置中是否有留意到这货:DelegatingFilterProxy,它会自动的把filter请求交给相应名称的bean处理。例如在启动时,spring会有一个filter请求,这个请求转交给了shiroFilter这个bean去处理了。so^接下来我们就得去找找看shiroFilter在哪?
此为上文加载的cas-client-shiro.xml配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<!-- shiro配置 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<!-- 设定角色的登录链接,这里为cas登录页面的链接和可配置回调地址 -->
<property name="loginUrl" value="${cas.casServerLoginUrl}?service=${cas.service}login/" />
<property name="successUrl" value="/" />
<property name="filters">
<util:map>
<!-- 添加casFilter到shiroFilter整合 -->
<entry key="casFilter" value-ref="casFilter"/>
</util:map>
</property>
<property name="filterChainDefinitions">
<value>
/login/ = casFilter
/logout = anon
/** = authc
</value>
</property>
</bean>
<!-- CasFilter为自定义的单点登录Fileter -->
<bean id="casFilter" class="com.test.shiro.filter.CasFilter">
<!-- 配置验证错误时的失败页面 -->
<property name="failureUrl" value="${cas.casServerLogoutUrl}?service=${cas.logoutRedirectUrl}"/>
<property name="realm" ref="casRealm"/>
</bean>
<!-- MyRealm为自定义的Realm -->
<bean id="casRealm" class="com.test.shiro.realm.MyRealm">
<property name="cacheManager" ref="shiroMemcacheManager" />
<property name="appId" value="${roomy.uap.client.appId}"/>
<property name="casServerUrlPrefix" value="${cas.host}"/>
<!-- 客户端的回调地址设置 -->
<property name="casService" value="${cas.service}login/"/>
</bean>
<!-- 缓存管理器 -->
………………
<!-- 会话sessionDAO -->
………………
<!-- 会话管理器sessionManager -->
………………
<!-- 会话验证调度器sessionValidationScheler -->
………………
<!-- 安全管理器securityManager -->
………………
<!-- Shiro生命周期处理器lifecycleBeanPostProcessor-->
………………
<!-- 退出 -->
<bean name="logoutFilter" class="com.test.cas.client.filter.LogoutFilterWithShiro">
<property name="casServerLogoutUrl" value="${cas.casServerLogoutUrl}"></property>
<property name="redirectUrl" value="${cas.logoutRedirectUrl}"></property>
</bean>
<!-- 单点登出 -->
<bean name="singleSignOutFilter"
class="com.test.cas.client.session.SingleSignOutFilter">
<property name="sessionMappingStorage" ref="sessionMappingStorage">
</property>
</bean>
<bean id="sessionMappingStorage" class="com.test.cas.client.session.">
<property name="cacheManager" ref="shiroMemcacheManager" />
<property name="sessionManager" ref="sessionManager" />
</bean>
以上内容众多省略,其实我想强调的是MyRealm。恩,我们要实现的认证、预授权操作都在此自定义的Realm中实现操作。MyRealm继承了CasRealm,CasRealm又继承了AuthorizingRealm。所以,MyRealm中具体写了授权实现逻辑,而认证则调用了CasRealm中的方法……
三、结语
为什么不好好的写一篇博文教程?首先,这方面的东西内容非常多,不是一两篇能说的清楚的。其次,自己也是刚开始学习,并未完全掌握。最后,本人特别懒,目前只是想给自己留个学习笔记而已。
6. 怎么自定义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) {
// 忽略
7. 过滤器里获得shiro登陆与否
Shiro的过滤器的配置是结合使用Spring的DelegatingFilterProxy与FactoryBean2种技术来完成自身过滤器的植入的,所以理专解Shiro的过滤器首先要理属解这2者的使用。
DelegatingFilterProxy :
Spring提供的一个简便的过滤器的处理方案,它将具体的操作交给内部的Filter对象delegate去处理,而这个delegate对象通过Spring IOC容器获取,这里采用的是Spring的FactoryBean的方式获取这个对象。
ShiroFilterFactoryBean:
配置如下 :
[html] view plainprint?
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
..
</bean>
由于它是个FactroyBean,所以上面的delegate真正的对象是通过它的getObject()获取的。
8. shiro基于form表单的身份验证过滤器可否配置两个成功页面
Shiro的过滤器的抄配置是结合使用Spring的DelegatingFilterProxy与FactoryBean2种技术来完成自身袭过滤器的植入的,所以理解Shiro的过滤器首先要理解这2者的使用。
DelegatingFilterProxy :
Spring提供的一个简便的过滤器的处理方案,它将具体的操作交给内部的Filter对象delegate去处理,而这个delegate对象通过Spring IOC容器获取,这里采用的是Spring的FactoryBean的方式获取这个对象。
9. shiro 可以有多个过滤器吗
可以的呢。中间用“,”分割即可,从前到后,依次执行!
推荐一套完整的Shiro Demo,免费的。
Shiro介绍文档:http://www.sojson.com/shiro
Demo已经部署到线上,地址是http://shiro.itboy.net
管理员帐号:admin,密码:sojson.com 如果密码错误,请用sojson。PS:你可以注册自己的帐号,然后用管理员赋权限给你自己的帐号,但是,每20分钟会把数据初始化一次。建议自己下载源码,让Demo跑起来,然后跑的更快。
10. cas有些请求路径不需要单点登录过滤器拦截
业务系统web应用在使用单点登录组件时,有些请求路径不需要单点登录过滤器拦截,比如公共开放的路径,不需要认证都可以自由访问的路径,单点登录过滤器配置的映射路径一般以通配符匹配路径,但要把这些路径单独提取出来,让过滤器不拦截做单点登录处理,就需要对原有过滤器进行扩展改造,才能实现这个功能。
扩展实现代码如下:
public class CASFilter implements Filter {
public static enum ResponseType {
BREAK, GOON, RETURN
}
...
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain fc){
。。。
CASReceipt receipt = (CASReceipt) session.getAttribute(CAS_FILTER_RECEIPT);
if (receipt != null && isReceiptAcceptable(receipt)) {
log.trace("CAS_FILTER_RECEIPT attribute was present and acceptable - passing request through filter..");
fc.doFilter(request, response);
return;
}else{
responeType = beforeDoSSOFilter(request, response);
if(ResponseType.RETURN==responeType){
return ;
}else if(ResponseType.BREAK==responeType) {
fc.doFilter(request, response);
return;
} //else go on
}
}
//过滤器的前置处理
public ResponseType beforeDoSSOFilter(ServletRequest request,
ServletResponse response) {
return ResponseType.GOON;
}
}
注:主要看原CASFilter 类红字部分扩展代码。
扩展实现类BMCASFilter
package com.sitechasia.sso.bmext;
public class BMCASFilter extends CASFilter {
private final Log log = LogFactory.getLog(this.getClass());
private static String ssoclient_passedPathSet;//设置不被sso过滤器拦截的请求路径,需要符合url路径通配符,多个路径可以","分割
public static final String PASSEDPATHSET_INIT_PARAM="passedPathSet";//web.xml配置文件中的参数
@Override
public void init(FilterConfig config) throws ServletException {
super.init(config);
ssoclient_passedPathSet = SSOClientPropertiesSingleton.getInstance().getProperty(ClientConstants.SSOCLIENT_PASSEDPATHSET)==null?config.getInitParameter(PASSEDPATHSET_INIT_PARAM):SSOClientPropertiesSingleton.getInstance().getProperty(ClientConstants.SSOCLIENT_PASSEDPATHSET);
}
@Override
public ResponseType beforeDoSSOFilter(ServletRequest request,
ServletResponse response) {
if (ssoclient_passedPathSet != null) {//路径过滤
HttpServletRequest httpRequest =(HttpServletRequest)request;
String requestPath = httpRequest.getRequestURI();
// String ls_requestPath = UrlUtils.buildFullRequestUrl(httpRequest.getScheme(), httpRequest.getServerName(), httpRequest.getServerPort(), requestPath, null);
PathMatcher matcher = new AntPathMatcher();
String passedPaths[]=null;
passedPaths =ssoclient_passedPathSet.split(",");
if(passedPaths!=null){
boolean flag;
for (String passedPath : passedPaths) {
flag = matcher.match(passedPath, requestPath);//ls_requestPath
if(flag){
log.info("sso client request path '"+requestPath+"'is matched,filter chain will be continued.");
return ResponseType.BREAK;
}
}
}
}
return ResponseType.GOON;
}
}
web.xml文件中配置修改如下:
<filter>
<description>单点登陆请求过滤器</description>
<filter-name>CASFilter</filter-name>
<filter-class>com.sitechasia.sso.dmext.filter.DMCASFilter</filter-class>
...
<init-param>
<description>排除路径</description>
<param-name>passedPathSet</param-name>
<param-value>
/**/restful/userLogin/findPassword,
/**/restful/userLogin/findIllegalLoginCount,
/**/restful/tenantManager/**,
/**/restful/lock/**,
/**/restful/export/**
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CASFilter</filter-name>
<url-pattern>/index.jsp</url-pattern>
< /filter-mapping>
。。。
注:红字部分为相应配置内容扩展部分
经过上述这样扩展,配置的排除路径作为请求时,单点登录过滤拦截就会忽略处理,实现了目标功能要求。