《权限系列shiro+cas》---封装公共验证模块
- 小编最近正在优化权限框架,应对的需求是:在一个分布式系统中,要有单点登录功能,还得有集中的权限认证。于是技术选型就找到了shiro和Cas,shiro是Apache旗下的开源授权框架,而Cas是Yale 大学发起的一个企业级的、开源的项目,旨在为 Web 应用系统提供一种可靠的单点登录解决方法(属于 Web SSO)。做授权的框架还有Spring Security,置于Spring Security和Shiro的区别,大家自己去查查吧,下面小编进入正题。
点击这里,去小编的GitHub上下载源码
- 用cas实现认证(登录),用shiro实现授权。
项目之间的依赖关系
- shiro-cas-authority是公共验证模块,它是一个jar工程,主要让各个应用程序来引用,应用程序一(applicationOne)和应用程序二(applicationTwo)引用shiro-cas-authority,当各个应用程序访问访问需要权限的资源时,程序就会跳到shiro-cas-authority来进行权限验证,其实就是利用shiro来授权。
配置shiro的核心过滤器和cas单点登出过滤器
- 在公共验证模块:shiro-cas-authority是没有web.xml的,我们将这个模块打包成jar包供各个应用程序使用,所以web.xml是在各个应用程序中的。
<!-- shiro的核心过滤器----------begin -->
<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>
<!-- shiro的核心过滤器----------end -->
<!-- 配置单点登出 begin-->
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<filter>
<filter-name>singleSignOutFilter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>singleSignOutFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 单点登出----------------end -->
shiro与spring整合
配置spring-shiro-authority.xml
<!-- Shiro Filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- 设定用户的登录链接,这里为cas登录页面的链接地址可配置回调地址 -->
<property name="loginUrl" value="${shiro.loginUrl}" />
<property name="filters">
<map>
<!-- 添加casFilter到shiroFilter -->
<entry key="casFilter" value-ref="casFilter" />
<entry key="logoutFilter" value-ref="logoutFilter" />
</map>
</property>
<property name="filterChainDefinitions">
<value>
/shiro-cas = casFilter
/logout = logoutFilter
/**=user
</value>
</property>
</bean>
<bean id="casFilter" class="org.apache.shiro.cas.CasFilter">
<!-- 配置验证成功是的URL -->
<property name="successUrl" value="${shiro.successUrl}" />
<!-- 配置验证错误时的失败URL -->
<property name="failureUrl" value="${shiro.failureUrl}" />
</bean>
<bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
<!-- 配置验证错误时的失败页面 -->
<property name="redirectUrl" value="${shiro.logoutUrl}" />
</bean>
<bean id="casRealm" class="com.spring.mybatis.realm.UserRealm">
<!-- 认证通过后的默认角色 -->
<!-- <property name="defaultRoles" value="ROLE_USER" /> -->
<!-- cas服务端地址前缀 -->
<property name="casServerUrlPrefix" value="${shiro.cas.serverUrlPrefix}" />
<!-- 应用服务地址,用来接收cas服务端票据 -->
<property name="casService" value="${shiro.cas.service}" />
</bean>
<!-- Shiro"s main business-tier object for web-enabled applications -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- <property name="sessionManager" ref="sessionManager" /> -->
<property name="subjectFactory" ref="casSubjectFactory"></property>
<property name="realm" ref="casRealm" />
</bean>
<bean id="casSubjectFactory" class="org.apache.shiro.cas.CasSubjectFactory"></bean>
<bean
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>
<bean
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod"
value="org.apache.shiro.SecurityUtils.setSecurityManager"></property>
<property name="arguments" ref="securityManager"></property>
</bean>
spring核心配置文件spring-context-authority.xml
<context:component-scan base-package="com.spring.mybatis"/>
<!-- 自动注入properties属性文件 -->
<bean id="configProperties111" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:conf/jdbc.properties</value>
<!-- <value>classpath:conf/shiro.properties</value> -->
</list>
</property>
</bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
<property name="properties" ref="configProperties111" />
</bean>
<!-- mybatis配置 -->
<import resource="spring-mybatis-authority.xml"/>
<!-- shiro配置 -->
<import resource="spring-shiro-authority.xml"/>
核心Realm的实现
public class UserRealm extends CasRealm {
@Resource
private RoleService roleService;
@Resource
private UserService userService;
protected final Map<String, SimpleAuthorizationInfo> roles = new ConcurrentHashMap<String, SimpleAuthorizationInfo>();
/**
* 设置角色和权限信息
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String account = (String) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = null;
if (authorizationInfo == null) {
authorizationInfo = new SimpleAuthorizationInfo();
List<String> permissions = roleService.getPermissions(account);
authorizationInfo.addStringPermissions(permissions);
authorizationInfo.addRoles(roleService.getRoles(account));
roles.put(account, authorizationInfo);
}
return authorizationInfo;
}
/**
* 1、CAS认证 ,验证用户身份
* 2、将用户基本信息设置到会话中
*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
AuthenticationInfo authc = super.doGetAuthenticationInfo(token);
String account = (String) authc.getPrincipals().getPrimaryPrincipal();
User user = userService.getUserByAccount(account);
SecurityUtils.getSubject().getSession().setAttribute("user", user);
return authc;
}
}
- 这个核心UserRealm是shiro控制权限的核心,在这个类中,我们将某个用户的拥有的资源查询出来,放到SimpleAuthorizationInfo的对象中,当我们访问后台方法时,shiro会自动根据SimpleAuthorizationInfo对象的中拥有的资源信息进行比对,检查用户是否有权限访问该资源。
- 小编并没有将代码完全贴出来,要是每条线都贴出来就太麻烦了,大家可以去下载源码(源码地址已经给出),读者可以在调试项目的时候可以加深理解。
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: PyQt中QLabel背景与字体的一些设置
- 下一篇: VC中调用并获取外部程序输出