《权限系列shiro+cas》---封装公共验证模块

来源:互联网 发布:淘宝网起名字 编辑:程序博客网 时间:2024/05/16 04:22

前言

  • 小编最近正在优化权限框架,应对的需求是:在一个分布式系统中,要有单点登录功能,还得有集中的权限认证。于是技术选型就找到了shiro和Cas,shiro是Apache旗下的开源授权框架,而Cas是Yale 大学发起的一个企业级的、开源的项目,旨在为 Web 应用系统提供一种可靠的单点登录解决方法(属于 Web SSO)。做授权的框架还有Spring Security,置于Spring Security和Shiro的区别,大家自己去查查吧,下面小编进入正题。

源码地址

点击这里,去小编的GitHub上下载源码

shiro和cas的关系

  • 用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对象的中拥有的资源信息进行比对,检查用户是否有权限访问该资源。

小结

  • 小编并没有将代码完全贴出来,要是每条线都贴出来就太麻烦了,大家可以去下载源码(源码地址已经给出),读者可以在调试项目的时候可以加深理解。
原创粉丝点击