概述
企業(yè)內(nèi)部一般都有一套單點登錄系統(tǒng)(常用的實現(xiàn)有apereo cas)锅风,所有的內(nèi)部系統(tǒng)的登錄認證都對接它。本文介紹spring boot的程序如何對接CAS服務(wù)线婚。
常用的安全框架有spring security和apache shiro遏弱。shiro的配置和使用相對簡單,本文使用shrio對接CAS服務(wù)塞弊。
部署單點登錄系統(tǒng)
部署一個cas系統(tǒng),后端數(shù)據(jù)使用ad
https://github.com/willwu1984/sso
配置
新增依賴
pom.xml新增:
<properties>
<shiro.version>1.2.4</shiro.version>
</properties>
<dependencies>
<!--Apache Shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-cas</artifactId>
<version>${shiro.version}</version>
</dependency>
</dependencies>
spring boot配置
application.properties
shiro.cas=https://cas.xxx.com # 這是CAS服務(wù)的地址
shiro.server=http://127.0.0.1:8080 # 自己應(yīng)用的地址,測試使用127即可
應(yīng)用配置
初始化shiro bean游沿,將文件放到任意子包下即可饰抒,比如xxx.config,spring boot會自動掃描加載
@Configuration
public class ShiroCasConfiguration {
private static final String casFilterUrlPattern = "/shiro-cas";
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
filterRegistration.addInitParameter("targetFilterLifecycle", "true");
filterRegistration.setEnabled(true);
filterRegistration.addUrlPatterns("/*");
return filterRegistration;
}
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Value("${shiro.cas}") String casServerUrlPrefix,
@Value("${shiro.server}") String shiroServerUrlPrefix) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
CasRealm casRealm = new CasRealm();
casRealm.setDefaultRoles("ROLE_USER");
casRealm.setCasServerUrlPrefix(casServerUrlPrefix);
casRealm.setCasService(shiroServerUrlPrefix + casFilterUrlPattern);
securityManager.setRealm(casRealm);
securityManager.setCacheManager(new MemoryConstrainedCacheManager());
securityManager.setSubjectFactory(new CasSubjectFactory());
return securityManager;
}
private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean) {
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put(casFilterUrlPattern, "casFilter");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/bower_components/**", "anon");//可以將不需要攔截的靜態(tài)文件目錄加進去
filterChainDefinitionMap.put("/logout","logout");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
}
/**
* CAS Filter
*/
@Bean(name = "casFilter")
public CasFilter getCasFilter(@Value("${shiro.cas}") String casServerUrlPrefix,
@Value("${shiro.server}") String shiroServerUrlPrefix) {
CasFilter casFilter = new CasFilter();
casFilter.setName("casFilter");
casFilter.setEnabled(true);
String loginUrl = casServerUrlPrefix + "/login?service=" + shiroServerUrlPrefix + casFilterUrlPattern;
casFilter.setFailureUrl(loginUrl);
return casFilter;
}
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager,
CasFilter casFilter,
@Value("${shiro.cas}") String casServerUrlPrefix,
@Value("${shiro.server}") String shiroServerUrlPrefix) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
String loginUrl = casServerUrlPrefix + "/login?service=" + shiroServerUrlPrefix + casFilterUrlPattern;
shiroFilterFactoryBean.setLoginUrl(loginUrl);
shiroFilterFactoryBean.setSuccessUrl("/");
Map<String, Filter> filters = new HashMap<>();
filters.put("casFilter", casFilter);
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setRedirectUrl(casServerUrlPrefix + "/logout?service=" + shiroServerUrlPrefix);
filters.put("logout",logoutFilter);
shiroFilterFactoryBean.setFilters(filters);
loadShiroFilterChain(shiroFilterFactoryBean);
return shiroFilterFactoryBean;
}
}
程序中獲取登錄的用戶名
上述配置完成后诀黍,就可以找程序中獲取登錄用戶的名字了
public String getUsername() {
Subject subject = SecurityUtils.getSubject();
if (subject == null || subject.getPrincipals() == null) {
return DEFAULTUSER;
}
return (String) subject.getPrincipals().getPrimaryPrincipal();
}
總結(jié)
shiro使用還是比較簡單的袋坑,使用的時候只需要修改application.properties即可
github地址:
https://github.com/willwu1984/springboot-cas-shiro