SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
本篇文章不讲解cas-server端的搭建哦,只有springboot项目整合cas-client的代码实现。
客户端的搭建,首先是pom.xml文件:
<!-- https://mvnrepository.com/artifact/org.jasig.cas.client/cas-client-core -->
<!--引入cas client-->
<dependency>
<groupId>net.unicon.cas</groupId>
<artifactId>cas-client-autoconfig-support</artifactId>
<version>2.2.0-GA</version>
<exclusions>
<exclusion>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.5.0</version>
</dependency>
然后application.yml配置文件:
#单点登陆配置
cas:
#cas服务端的登录地址
server-login-url: http://127.0.0.1:3216/sso/login
#cas服务端的地址
server-url-prefix: http://127.0.0.1:3216/sso
#当前服务器的地址(客户端)
client-host-url: http://127.0.0.1:8899
#Ticket校验器使用Cas3
validation-type: cas3
单点登录配置文件:
import lombok.Data;
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Data
@Configuration
@ConfigurationProperties(prefix = "cas")
public class CASAutoConfig {
private String serverUrlPrefix;
private String serverLoginUrl;
private String clientHostUrl;
private String validationType;
private String ignoreHostUrl;
/**
* 配置登出过滤器
* @return
*/
@Bean
public FilterRegistrationBean filterSingleRegistration() {
final FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new SingleSignOutFilter());
// 设定匹配的路径
registration.addUrlPatterns("/*");
Map<String,String> initParameters = new HashMap<String, String>();
initParameters.put("casServerUrlPrefix", serverUrlPrefix);
registration.setInitParameters(initParameters);
// 设定加载的顺序
registration.setOrder(1);
return registration;
}
/**
* 配置授权过滤器
* @return
*/
@Bean
public FilterRegistrationBean filterAuthenticationRegistration() {
final FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new AuthenticationFilter());
// 设定匹配的路径
registration.addUrlPatterns("/*");
Map<String,String> initParameters = new HashMap<String, String>();
initParameters.put("casServerLoginUrl", serverLoginUrl);
initParameters.put("serverName", clientHostUrl);
if(ignoreHostUrl != null && !"".equals(ignoreHostUrl)){
initParameters.put("ignorePattern", ignoreHostUrl);
}
registration.setInitParameters(initParameters);
// 设定加载的顺序
registration.setOrder(2);
return registration;
}
/**
* 配置过滤验证器 这里用的是Cas20ProxyReceivingTicketValidationFilter
* @return
*/
@Bean
public FilterRegistrationBean filterValidationRegistration() {
final FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new Cas20ProxyReceivingTicketValidationFilter());
// 设定匹配的路径
registration.addUrlPatterns("/*");
Map<String,String> initParameters = new HashMap<String, String>();
initParameters.put("casServerUrlPrefix", serverUrlPrefix);
initParameters.put("serverName", clientHostUrl);
initParameters.put("encoding","UTF-8");
initParameters.put("useSession", "true");
registration.setInitParameters(initParameters);
// 设定加载的顺序
registration.setOrder(3);
return registration;
}
/**
* request wraper过滤器
* @return
*/
@Bean
public FilterRegistrationBean filterWrapperRegistration() {
final FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new HttpServletRequestWrapperFilter());
// 设定匹配的路径
registration.addUrlPatterns("/*");
// 设定加载的顺序
registration.setOrder(4);
return registration;
}
}
主类上需要开启单点登录:
获取用户信息的工具类:
import javax.servlet.http.HttpServletRequest;
/**
* 类 {@code CasUtil} <br> 获取登录后的用户信息工具类.
*
* <p>详细描述
* <p>
* @author <a href="mailto:lz2392504@gmail.com">CN華少</a>
* @since v1.0.0
*/
public class CasUtil {
/**
* Principal principal = request.getUserPrincipal();
* if (principal != null && principal instanceof AttributePrincipal) {
* AttributePrincipal aPrincipal = (AttributePrincipal) principal;
* //获取用户信息中公开的Attributes部分
* Map<String, Object> map = aPrincipal.getAttributes();
* // 获取姓名,可以根据属性名称获取其他属性
* cn = (String) map.get("cn");
* System.out.println("cn");
* }
* 从cas中获取用户名
* @param request
* @return
*/
public static String getAccountNameFromCas(HttpServletRequest request) {
Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
if(assertion!= null){
AttributePrincipal principal = assertion.getPrincipal();
return principal.getName();
}else{
return null;
}
}
}
在接口上简单使用,先访问/hello接口,跳转登录成功后,访问第/inner则无需再登录:
import com.haileer.hlapi.util.CasUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
public class HelloController {
/**
* 无权限
* @return
*/
@GetMapping(value = "hello")
public String hello(HttpServletRequest request){
String userName = CasUtil.getAccountNameFromCas(request);
return "hello-running:"+userName;
}
/**
* 需要权限
* @return
*/
@GetMapping(value = "inner")
public String innner(HttpServletRequest request){
String userName = CasUtil.getAccountNameFromCas(request);
return "inner-resource-running:"+userName;
}
}
以上就是客户端主要代码。