shiro 对接 Cas 无法获取用户名之外的属性值
springboot 项目: Cas 版本 5.3.16 / shiro-cas版本1.2.4
Cas 已经返回自定义属性
shrio 接收 永远只有用户名
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;
}
}
就是不知道怎么获取 我自定义的属性值,感谢各位指点