Shiro集成Cas单点登录

前言

因为前段时间工作需要,需要使用Shiro来集成单点登录系统,本篇文章记录一下集成中如何使用。
关于Shiro的基本使用,在这里也有一篇文章来介绍:超详细springboot+apache shiro+redis
有需要的朋友可以看看。
下面就直接附上代码,关键地方代码中都有注释。

@Configuration
public class ShiroCasConfiguration {

	private Logger log = LoggerFactory.getLogger(ShiroCasConfiguration.class);
	
	//Cas服务器地址
	@Value("${sso_server}")
	private String casServerUrlPrefix;
	//触发本地进行Cas认证的地址
	@Value("${self_server}")
	private String casService;
	//成功后需要返回的页面
	@Value("${cas_successUrl}")
	private String successUrl;
	// 登录地址
	public static String loginUrl;

	@Bean(name = "casRealm")
	public CasRealm myShiroCasRealm() {
		// 如需要可以自定义认证Realm来继承CasRealm
		// CustomCasRealm realm = new CustomCasRealm();
		CasRealm realm = new CasRealm();
		realm.setCachingEnabled(true);
		realm.setAuthenticationCachingEnabled(true);
		realm.setAuthenticationCacheName("authenticationCache");
		realm.setAuthorizationCachingEnabled(true);
		realm.setAuthorizationCacheName("authorizationCache");
		//此出的IP地址一定是CAS 认证的地址。
		realm.setCasServerUrlPrefix("http://xx.xx.xx/cas");
		realm.setCasService(casService);
		loginUrl = casServerUrlPrefix + "/login?service=" + casService;
		log.info("loginUrl:[{}]", loginUrl);
		return realm;
	}

	@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(CasRealm casRealm) {
		DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
		dwsm.setRealm(casRealm);
//      
		// dwsm.setCacheManager(getEhCacheManager());
		// 指定 SubjectFactory
		dwsm.setSubjectFactory(new CasSubjectFactory());
		return dwsm;
	}

	/**
	 * 不配置也行,看需要
	 *
	 * @param securityManager
	 * @return
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(
			DefaultWebSecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
		aasa.setSecurityManager(securityManager);
		return aasa;
	}

	@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(successUrl);
		shiroFilterFactoryBean.setUnauthorizedUrl(loginUrl);
		// 添加casFilter到shiroFilter中
		Map<String, Filter> filters = new HashMap<String, Filter>();
		//触发进行本地cas认证Filter的url
		filters.put("casFilter", casFilter);
		// authcFilter
		FormAuthenticationFilter authcFilter = new FormAuthenticationFilter();
		authcFilter.setLoginUrl(loginUrl);
		authcFilter.setSuccessUrl(successUrl);
		filters.put("authc", authcFilter);
		// logoutFilter
		LogoutFilter logoutFilter = new LogoutFilter();
		logoutFilter.setRedirectUrl(loginUrl);
		filters.put("logout", logoutFilter);

		shiroFilterFactoryBean.setFilters(filters);
		loadShiroFilterChain(shiroFilterFactoryBean);
		return shiroFilterFactoryBean;
	}

	@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;
	}

	private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean) {
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
		filterChainDefinitionMap.put("/cas", "casFilter");// shiro集成cas后,首先添加该规则
		filterChainDefinitionMap.put("/**", "authc");// authc /anon /可以理解为不拦截
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
	}

	@Bean
	public ServletListenerRegistrationBean singleSignOutHttpSessionListener() {
		ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean();
		bean.setListener(new SingleSignOutHttpSessionListener());
//        bean.setName(""); //默认为bean name
		bean.setEnabled(true);
		// bean.setOrder(Ordered.HIGHEST_PRECEDENCE); //设置优先级
		return bean;
	}

	/**
	 * 注册单点登出filter
	 *
	 * @return
	 */
	@Bean
	public FilterRegistrationBean singleSignOutFilter() {
		FilterRegistrationBean bean = new FilterRegistrationBean();
		bean.setName("singleSignOutFilter");
		bean.setFilter(new SingleSignOutFilter());
		bean.addUrlPatterns("/*");
		bean.setEnabled(true);
		bean.setOrder(Ordered.HIGHEST_PRECEDENCE);// 防止其他filter冲突
		return bean;
	}

}

你可能感兴趣的:(JAVA,shiro,shiro,java,Cas,单点登录,SSO)