• -------------------------------------------------------------
  • ====================================

springMVC集成shiro与cas实现SSO单点登录

技能 dewbay 5年前 (2019-04-12) 2505次浏览 已收录 0个评论 扫描二维码

一、前言

Apache Shiro 与 Spring Security 一样是 Java 的一个安全框架。那为什么与 Spring 整合却用 Shiro?其实我个人是认为 Spring Security 太过于笨重,要写太多的过滤器,Shiro 的配置简单这就是我选择的理由,何况 Spring 官方自己都推荐使用 Shiro。Shiro 最主要的就是认证与授权,而 CAS 的重点在于单点登录,其实 CAS 与 Shiro 整合的话就是关于认证那块的整合。

二、配置

第一步、添加 Maven 依赖

    <!-- shiro 依赖包 -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>1.2.4</version>
    </dependency>

    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.2.3</version>
    </dependency>

    <!-- shiro-cas 集成依赖包 -->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-cas</artifactId>
        <version>1.2.3</version>
    </dependency>

第二步、web.xml 中添加shiro过滤器

shiroFilter org.springframework.web.filter.DelegatingFilterProxy targetFilterLifecycle true
shiroFilter /*
第三步、添加 applicationContext-shiro.xml 配置文件

<description>Shiro 配置</description>

<!-- CasFilter 为自定义的单点登录 Fileter -->
<!--shiroFilter 的 bean Name 必须与 web.xml 中 shiro filter 的名字一致-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <!-- Shiro 的核心安全接口,这个属性是必须的 -->  
    <property name="securityManager" ref="securityManager"/>
    <!-- 要求登录时的链接(可根据项目的 URL 进行替换),非必须的属性,默认会自动寻找 Web 工程根目录下的"/login.jsp"页面 --> 
    <property name="loginUrl" value="http://cas.uat.qa.nt.ctripcorp.com/caso/login?service=http://127.0.0.1:8080/springdemo/shiro-cas"/>
    <property name="successUrl" value="/"/>
    <!-- 用户访问未对其授权的资源时,所显示的连接 -->
    <property name="unauthorizedUrl" value="/static/no-permission.jsp"/>

    <!-- The 'filters' property is usually not necessary unless performing 
        an override, which we want to do here (make authc point to a PassthruAuthenticationFilter 
        instead of the default FormAuthenticationFilter: -->
    <property name="filters">
        <util:map>
            <!-- 添加 casFilter 到 shiroFilter 整合 -->
            <entry key="casFilter" value-ref="casFilter"/>
           <!--  <entry key="perms">
                <bean
                    class="com.lora.shiro.filter.MyPermissionsAuthorizationFilter" />
            </entry>  -->
        </util:map>
    </property>

    <!-- 读取自定义权限内容-->
    <property name="filterChainDefinitions">
        <value>
            /shiro-cas = casFilter
            /addUser/** = authc
            /show/** = authc
            /login = anon
            /toLogin/login = anon
            /static/** = anon
            /static/no-permission.jsp = anon
            /greeting** = authc,perms[admin:manage]
            /** = anon
            <!-- /home* = roles["adminHome"] -->
        </value>
    </property>
</bean>

 <!-- 单点登录下的配置 -->
 <bean id="casRealm" class="com.lora.shiro.MyCasRealm">
    <property name="defaultRoles" value="ROLE_USER"/>
    <!-- cas 服务端地址前缀 -->
    <property name="casServerUrlPrefix" value="http://cas.uat.qa.nt.ctripcorp.com/caso" />
    <!-- 应用服务地址,用来接收 cas 服务端票据 -->
    <!-- 客户端的回调地址设置,必须和上面的 shiro-cas 过滤器 casFilter 拦截的地址一致 -->
    <property name="casService" value="http://127.0.0.1:8080/springdemo/shiro-cas" />
</bean>

<!-- 这里主要是设置自定义的单 Realm 应用,若有多个 Realm,可使用'realms'属性代替 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
   <!--  设置自定义 realm  ref="iniRealm,mySecurityRealm" -->
    <!-- <property name="realm" ref="myRealm"/> -->
     <property name="realm" ref="casRealm"/>
</bean>

<!--保证实现了 Shiro 内部 lifecycle 函数的 bean 执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  

<!-- 相当于调用 SecurityUtils.setSecurityManager(securityManager) -->
<bean
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="staticMethod"
        value="org.apache.shiro.SecurityUtils.setSecurityManager" />
    <property name="arguments" ref="securityManager" />
</bean>

<!-- 用于开启 Shiro Spring AOP 权限注解的支持 -->
<bean
    class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager" />
</bean>


第四步、 添加自定义 realm 配置的实现类 MyCasRealm
package com.lora.shiro;

import java.util.Iterator;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cas.CasRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;

import com.lora.model.User;

public class MyCasRealm extends CasRealm {

/**
 * 授权,获取用户的角色、权限
 */
@SuppressWarnings("rawtypes")
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
        PrincipalCollection principals) {
    if (principals == null) {
        throw new AuthorizationException("Principal 对象不能为空");
    }
    Iterator it = principals.fromRealm(getName()).iterator();
    String username = null;
    if (it.hasNext()) {
        username = (String) it.next();
    } else {
        username = principals.toString();
    }
    //获取用户响应的 permission
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    if (username != null) {
        // 添加一个角色,不是配置意义上的添加,而是证明该用户拥有 admin 角色
        info.addRole("admin");
        // 添加权限
        info.addStringPermission("admin:manage");
        System.out.println("已为用户赋予了[admin]角色和[admin:manage]权限");
        return info;
    }
    return info;
}

/**
 * 认证,登录验证。
 */
@SuppressWarnings("rawtypes")
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
        AuthenticationToken token) throws AuthenticationException {
    AuthenticationInfo authenticationInfo = super
            .doGetAuthenticationInfo(token);
    PrincipalCollection principalCollection = authenticationInfo
            .getPrincipals();
    Map loginDataMap = (Map) principalCollection.asList().get(1);
    String userAccount = (String) loginDataMap.get("name");
    String userCode = (String) loginDataMap.get("employee");
    String fullName = (String) loginDataMap.get("sn");
    String department = (String) loginDataMap.get("department");
    String email = (String) loginDataMap.get("mail");
    User user = new User();
    user.setUserCode(userCode);
    user.setUserAccount(userAccount);
    user.setUname(fullName);
    user.setDepartment(department);
    user.setEmail(email);
    // 将用户保存在 SESSION 回话中
    Session session = SecurityUtils.getSubject().getSession();
    session.setAttribute("currentUser", user);
    return authenticationInfo;
}

}

以上步骤完成,shiro 集成 cas 的步骤就完成了,实现了单点登录。

作者:疯丫头 666
来源:CSDN
原文:https://blog.csdn.net/wangli61289/article/details/79224943
版权声明:本文为博主原创文章,转载请附上博文链接!


露水湾 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:springMVC集成shiro与cas实现SSO单点登录
喜欢 (0)
[]
分享 (0)
关于作者:
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址