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

前言

  • 小编最近正在优化权限框架,应对的需求是:在一个分布式系统中,要有单点登录功能,还得有集中的权限认证。于是技术选型就找到了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是在各个应用程序中的。

<filter>
    <filter-name>shiroFilterfilter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
    <init-param>
        <param-name>targetFilterLifecycleparam-name>
        <param-value>trueparam-value>
    init-param>
filter>

<filter-mapping>
    <filter-name>shiroFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>


<listener>
    <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListenerlistener-class>
listener>
<filter>
    <filter-name>singleSignOutFilterfilter-name>
    <filter-class>org.jasig.cas.client.session.SingleSignOutFilterfilter-class>
filter>
<filter-mapping>
    <filter-name>singleSignOutFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>

shiro与spring整合

配置spring-shiro-authority.xml


<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager" />
    
    <property name="loginUrl" value="${shiro.loginUrl}" />
    <property name="filters">
        <map>
            
            <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">
    
    <property name="successUrl" value="${shiro.successUrl}" />
    
    <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="casServerUrlPrefix" value="${shiro.cas.serverUrlPrefix}" />
    
    <property name="casService" value="${shiro.cas.service}" />
bean>


<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    
    <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"/>


  <bean id="configProperties111" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
   <property name="locations">
     <list>
       <value>classpath:conf/jdbc.propertiesvalue>
     
     list>
   property>
  bean>
  <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
      <property name="properties" ref="configProperties111" />
  bean>  

  
  <import resource="spring-mybatis-authority.xml"/>
  
  <import resource="spring-shiro-authority.xml"/>

核心Realm的实现

public class UserRealm extends CasRealm {
    @Resource
    private RoleService roleService;
    @Resource
    private UserService userService;

    protected final Map roles = new ConcurrentHashMap();

    /**
     * 设置角色和权限信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String account = (String) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = null;
        if (authorizationInfo == null) {
            authorizationInfo = new SimpleAuthorizationInfo();
            List 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对象的中拥有的资源信息进行比对,检查用户是否有权限访问该资源。

小结

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

你可能感兴趣的:(1,JavaEE,权限系列)