cas的验证流程看这个吧: http://www.mytju.com/classcode/news_readNews.asp?newsID=503
打算在验证ticket的时候,顺便检查下是否有权限。
具体就是CentralAuthenticationServiceImpl的validateServiceTicket方法
直接贴代码了:
//这段是原有的, final List<Authentication> chainedAuthenticationsList = serviceTicket.getGrantingTicket().getChainedAuthentications(); final Authentication authentication = chainedAuthenticationsList.get(chainedAuthenticationsList.size() - 1); final Principal principal = authentication.getPrincipal(); //下面这些是我加的: //取得用户名 String username = principal.getId(); //截取网址前半段,如http://www.a.com:8080/UserManage/xxx/bbb只截取到UserManage String url = service.toString(); int index = url.indexOf("/", url.indexOf("/", 8)+1); String myUrl = url.substring(0, index+1); // 看是否有权限 String sql = "SELECT count(*) as myCount from sub_system s inner join user_system us on s.id = us.system_id inner join user u on us.user_id = u.id where us.enable=1 and u.username = '" + username + "' and s.system_url like '" + myUrl + "%'"; List xx = getJdbcTemplate().queryForList(sql); long count = (Long)((Map) xx.get(0)).get("myCount"); if(count==0){ throw new TicketValidationException(serviceTicket.getService()); }
简单起见,直接让这个类继承 extends AbstractJdbcUsernamePasswordAuthenticationHandler
就能使用getJdbcTemplate()来操作DB了~~
对了,还得在WEB-INF\spring-configuration下的applicationContext.xml中, 找到
<bean id="centralAuthenticationService" class="org.jasig.cas.CentralAuthenticationServiceImpl" p:ticketGrantingTicketExpirationPolicy-ref="grantingTicketExpirationPolicy" p:serviceTicketExpirationPolicy-ref="serviceTicketExpirationPolicy" p:authenticationManager-ref="authenticationManager" p:ticketGrantingTicketUniqueTicketIdGenerator-ref="ticketGrantingTicketUniqueIdGenerator" p:ticketRegistry-ref="ticketRegistry" p:servicesManager-ref="servicesManager" p:persistentIdGenerator-ref="persistentIdGenerator" p:uniqueTicketIdGeneratorsForService-ref="uniqueIdGeneratorsMap" p:dataSource-ref="dataSource"/>
最后的p:dataSource-ref="dataSource"是我加的~~ 因为AbstractJdbcUsernamePasswordAuthenticationHandler需要属性dataSource。
这样就Ok了,用户对此系统无权限时,就抛出TicketValidationException了。
------------------------- 以上是Server端的处理。
客户端是在AbstractTicketValidationFilter的doFilter中调用的服务端
catch (final TicketValidationException e) { response.setStatus(HttpServletResponse.SC_FORBIDDEN); log.warn(e, e);
onFailedValidation(request, response);
if (this.exceptionOnValidationFailure) { throw new ServletException(e); }
return; }catch (final RuntimeException e) { //client去server端验证,server端抛异常,会导致client端返回ioException。 response.setStatus(HttpServletResponse.SC_FORBIDDEN); log.warn(e, e);
onFailedValidation(request, response);
if (this.exceptionOnValidationFailure) { //throw new ServletException(e); //跳转到login页面了。 response.sendRedirect(casServerUrlPrefix + "login"); }
return; }
抓RuntimeException这段是我加的,因为Server端抛TicketValidationException时,
client端是通过URLConnection访问的,会说server端返回状态500,认为是IOException,
所以被RuntimeException这段抓住,然后redirect到login页面。
变量casServerUrlPrefix是在web.xml中的filter的参数,是cas server地址的前缀
如http://10.0.103.135:8080/cas/
在Filter的initInternal方法,加上
//取cas login地址 //http://10.0.103.135:8080/cas/ casServerUrlPrefix = getPropertyFromInitParams(filterConfig, "casServerUrlPrefix", null);
就行了。
|