Ancher253 2022-12-19 15:20 采纳率: 0%
浏览 50
已结题

shiro 对接 Cas 无法获取用户名之外的属性值

shiro 对接 Cas 无法获取用户名之外的属性值
springboot 项目: Cas 版本 5.3.16 / shiro-cas版本1.2.4
Cas 已经返回自定义属性

img

img

img

shrio 接收 永远只有用户名

img

shiro配置文件

package com.metinform.common.core.cas;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.cas.CasFilter;
import org.apache.shiro.cas.CasSubjectFactory;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.DelegatingFilterProxy;

import javax.servlet.Filter;
import java.util.*;

/**
 * 
 * @date 2020-05-26 下午2:30
 */
@Configuration
@SuppressWarnings("all")
@ConditionalOnProperty(name = "project.cas-login-switch", havingValue = "true")
public class ShiroCasConfiguration {

    //CasServerUrlPrefix
    @Value("${cas.server.host.url}")
    public String casServerUrlPrefix;
    // Cas登录页面地址
    @Value("${cas.server.host.login_url}")
    public String casLoginUrl;
    // Cas登出页面地址
    @Value("${cas.server.host.logout_url}")
    public String casLogoutUrl;
    @Value("${app.server.host.url}")
    public String shiroServerUrlPrefix;
    // casFilter UrlPattern
    @Value("${cas.filter.url.pattern}")
    public String casFilterUrlPattern;
    // 登录地址
    @Value("${app.server.host.login.url}")
    public String loginUrl;
    //退出地址
    @Value("${app.server.host.logout.url}")
    public String logoutUrl;

    @Bean
    public EhCacheManager getEhCacheManager() {
        EhCacheManager em = new EhCacheManager();
        em.setCacheManagerConfigFile("classpath:ehcache/ehcache-shiro.xml");
        return em;
    }

    @Bean(name = "shiroCasRealm")
    public MyShiroCasRealm shiroCasRealm(EhCacheManager cacheManager) {
        MyShiroCasRealm realm = new MyShiroCasRealm();
        realm.setCacheManager(cacheManager);
        return realm;
    }

    /**
     * 注册DelegatingFilterProxy(Shiro)
     *
     * @return
     * @author SHANHY
     * @create 2016年1月13日
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
        //  该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
        filterRegistration.addInitParameter("targetFilterLifecycle", "true");
        filterRegistration.setEnabled(true);
        filterRegistration.addUrlPatterns("/*");
        return filterRegistration;
    }

    @Bean(name = "lifecycleBeanPostProcessor")
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
        daap.setProxyTargetClass(true);
        return daap;
    }

    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(MyShiroCasRealm shiroCasRealm) {
        DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
        dwsm.setCacheManager(getEhCacheManager());
        dwsm.setSubjectFactory(new CasSubjectFactory());
        dwsm.setRealm(shiroCasRealm);
        return dwsm;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean) {
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        // shiro集成cas后,首先添加该规则
        filterChainDefinitionMap.put(casFilterUrlPattern, "casFilter");
        filterChainDefinitionMap.put("/logout", "anon");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/assets/**", "anon");
        filterChainDefinitionMap.put("/favicon.ico", "anon");
        filterChainDefinitionMap.put("/api/**", "anon");
        filterChainDefinitionMap.put("/upload/**", "anon");
        filterChainDefinitionMap.put("/error", "anon");
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    }

    @Bean(name = "casFilter")
    public CasFilter getCasFilter() {
        CasFilter casFilter = new CasFilter();
        casFilter.setName("casFilter");
        casFilter.setEnabled(true);
        // 登录失败后跳转的URL,也就是 Shiro 执行 CasRealm 的 doGetAuthenticationInfo 方法向CasServer验证tiket
        casFilter.setFailureUrl(loginUrl);
        return casFilter;
    }

    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager, CasFilter casFilter) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl(loginUrl);
        // 登录成功后要跳转的连接
        shiroFilterFactoryBean.setSuccessUrl("/index");
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        // 添加casFilter到shiroFilter中
        Map<String, Filter> filters = new HashMap<>();
        filters.put("casFilter", casFilter);

        shiroFilterFactoryBean.setFilters(filters);

        loadShiroFilterChain(shiroFilterFactoryBean);
        return shiroFilterFactoryBean;
    }

    /**
     * 注册单点登出的listener
     *
     * @return
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)// 优先级需要高于Cas的Filter
    public ServletListenerRegistrationBean<?> singleSignOutHttpSessionListener() {
        ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean();
        bean.setListener(new SingleSignOutHttpSessionListener());
        bean.setEnabled(true);
        return bean;
    }

    /**
     * 注册单点登出filter
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean singleSignOutFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setName("singleSignOutFilter");
        bean.setFilter(new SingleSignOutFilter());
        bean.addUrlPatterns("/*");
        bean.setEnabled(true);
        return bean;
    }

}


Realm文件

package com.metinform.common.core.cas;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.metinform.module.system.entity.Role;
import com.metinform.module.system.entity.User;
import com.metinform.module.system.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * 
 * @date 2020-05-26 下午2:29
 */
public class MyShiroCasRealm extends CasRealm {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private UserService userService;

    @Value("${cas.server.host.url}")
    public String casServerUrlPrefix;

    @Value("${app.server.host.url}")
    public String shiroServerUrlPrefix;

    @Value("${cas.filter.url.pattern}")
    public String casFilterUrlPattern;

    @PostConstruct
    public void initProperty() {
        setCasServerUrlPrefix(casServerUrlPrefix);
        // 客户端回调地址
        setCasService(shiroServerUrlPrefix + casFilterUrlPattern);
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String loginName = (String) super.getAvailablePrincipal(principalCollection);
        SimpleAuthorizationInfo info = null;
        try {
            //查询用户
            User user = userService.getOne(new QueryWrapper<User>().eq("username", loginName));
            if (user != null) {
                info = new SimpleAuthorizationInfo();
                userService.selectRoleAndAuth(user);
                // 角色
                Set<String> roles = new HashSet<>();
                for (Role r : user.getRoles()) {
                    if (r.getDeleted() == 0) {
                        roles.add(r.getRoleCode());
                    }
                }
                info.setRoles(roles);
                // 权限
                Set<String> permissions = new HashSet<>();
                for (String auth : user.getAuthorities()) {
                    if (auth != null && !auth.trim().isEmpty()) {
                        permissions.add(auth);
                    }
                }
                info.setStringPermissions(permissions);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return info;
    }

    /**
     * 登录认证
     *
     * @param authenticationToken
     * @return
     */
    @Override
    @SuppressWarnings("all")
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
        User user = null;
        // 获取用户的输入的账号.
        AuthenticationInfo atoken = super.doGetAuthenticationInfo(authenticationToken);
        if (atoken != null) {
            String account = (String) atoken.getPrincipals().getPrimaryPrincipal();
            try {
                //通过该集合获取用户信息
                List list = atoken.getPrincipals().asList();

                HashMap hashMap = (HashMap) list.get(1);

                user = userService.getOne(new QueryWrapper<User>().eq("username", account));
                //该用户不存在
                if (user == null) {
                    user = new User();
                    user.setUsername(account);
                    user.setNickName(valueList.get(userNameInx));
                    //设置默认密码
                    user.setPassword(valueList.get(pwdInx));
                    //第一次进入系统,设置为角色为普通用户
                    List<Integer> roleList = new ArrayList<>();
                    roleList.add(2);
                    user.setRoleIds(roleList);
                    userService.saveUser(user);
                }
                Session session = SecurityUtils.getSubject().getSession();
                session.setAttribute("userSession", user);
            } catch (Exception e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            }
        }
        return atoken;
    }
}


就是不知道怎么获取 我自定义的属性值,感谢各位指点

  • 写回答

2条回答 默认 最新

  • 卡布奇诺-海晨 Java领域优质创作者 2022-12-19 16:25
    关注

    改造下

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 12月19日
  • 修改了问题 12月19日
  • 创建了问题 12月19日

悬赏问题

  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来