spring-security-cas-demo

This commit is contained in:
mjh 2024-01-10 14:36:27 +08:00
parent 1550e996a5
commit 5eabd4892c
17 changed files with 1121 additions and 0 deletions

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.unicom.sso</groupId>
<artifactId>sso-springboot-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>sso-bigdata-cas-starter-demo</artifactId>
<description>cas 单点登录demo</description>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--单点登录依赖-->
<!-- <dependency>-->
<!-- <groupId>com.unicom.sso</groupId>-->
<!-- <artifactId>unicom-sso-bigdata-cas-springboot-starter</artifactId>-->
<!-- <version>0.0.1-SNAPSHOT</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,17 @@
package com.unicom.sso.bigdata.cas.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* cas 单点
* @author baihz10
* @date 2023/7/7 15:18
*/
//@EnableCasClient
@SpringBootApplication
public class CasApplication {
public static void main(String[] args) {
SpringApplication.run(CasApplication.class, args);
}
}

View File

@ -0,0 +1,25 @@
package com.unicom.sso.bigdata.cas.demo.config;
import org.springframework.security.core.GrantedAuthority;
public class AuthorityInfo implements GrantedAuthority {
private static final long serialVersionUID = -175781100474818800L;
/**
* 权限CODE
*/
private String authority;
public AuthorityInfo(String authority) {
this.authority = authority;
}
@Override
public String getAuthority() {
return authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
}

View File

@ -0,0 +1,120 @@
package com.unicom.sso.bigdata.cas.demo.config;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
import org.jasig.cas.client.validation.Cas30ProxyTicketValidator;
import org.jasig.cas.client.validation.Cas30ServiceTicketValidator;
import org.jasig.cas.client.validation.TicketValidator;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationEntryPoint;
import org.springframework.security.cas.web.CasAuthenticationFilter;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Configuration
public class CasConfig {
@Value("${cas.server.url}")
private String casServerUrl;
@Value("${base.url}")
private String baseUrl;
@Bean
public AuthenticationEntryPoint authenticationEntryPoint() {
CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint();
entryPoint.setLoginUrl(casServerUrl + "/login");
entryPoint.setServiceProperties(this.serviceProperties());
return entryPoint;
}
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
return new ProviderManager(this.casAuthenticationProvider());
}
@Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
CasAuthenticationFilter filter = new CasAuthenticationFilter();
filter.setAuthenticationManager(this.authenticationManager());
filter.setServiceProperties(this.serviceProperties());
filter.setAuthenticationFailureHandler(this.authenticationFailureHandler());
filter.setAuthenticationSuccessHandler(this.authenticationSuccessHandler());
return filter;
}
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
AuthenticationSuccessHandler authenticationSuccessHandler = new SimpleUrlAuthenticationSuccessHandler();
return authenticationSuccessHandler;
}
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
AuthenticationFailureHandler authenticationFailureHandler = new SimpleUrlAuthenticationFailureHandler();
return authenticationFailureHandler;
}
@Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService(baseUrl);
serviceProperties.setSendRenew(false);
return serviceProperties;
}
@Bean
public TicketValidator ticketValidator() {
return new Cas30ProxyTicketValidator(casServerUrl);
}
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider provider = new CasAuthenticationProvider();
provider.setServiceProperties(this.serviceProperties());
provider.setTicketValidator(this.ticketValidator());
provider.setAuthenticationUserDetailsService(new UserDetailsServiceImpl());
provider.setKey("CAS_PROVIDER_LOCALHOST");
return provider;
}
@Bean
public SecurityContextLogoutHandler securityContextLogoutHandler() {
return new SecurityContextLogoutHandler();
}
@Bean
public LogoutFilter logoutFilter() {
LogoutFilter logoutFilter = new LogoutFilter(casServerUrl + "/logout?service=" + baseUrl,
securityContextLogoutHandler());
logoutFilter.setFilterProcessesUrl("/logout/cas");
return logoutFilter;
}
@Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
singleSignOutFilter.setIgnoreInitConfiguration(true);
return singleSignOutFilter;
}
}

View File

@ -0,0 +1,96 @@
package com.unicom.sso.bigdata.cas.demo.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* CAS的配置参数
*/
@Component
public class CasProperties {
@Value("${cas.server.host.url}")
private String casServerUrl;
@Value("${cas.server.host.login_url}")
private String casServerLoginUrl;
@Value("${cas.server.host.logout_url}")
private String casServerLogoutUrl;
@Value("${app.casEnable}")
private boolean casEnable;
@Value("${app.server.host.url}")
private String appServerUrl;
@Value("${app.login_url}")
private String appLoginUrl;
@Value("${app.logout_url}")
private String appLogoutUrl;
@Value("${app.web_url}")
private String webUrl;
public String getWebUrl() {
return webUrl;
}
public String getCasServerUrl() {
return casServerUrl;
}
public void setCasServerUrl(String casServerUrl) {
this.casServerUrl = casServerUrl;
}
public String getCasServerLoginUrl() {
return casServerLoginUrl;
}
public void setCasServerLoginUrl(String casServerLoginUrl) {
this.casServerLoginUrl = casServerLoginUrl;
}
public String getCasServerLogoutUrl() {
return casServerLogoutUrl;
}
public void setCasServerLogoutUrl(String casServerLogoutUrl) {
this.casServerLogoutUrl = casServerLogoutUrl;
}
public boolean isCasEnable() {
return casEnable;
}
public void setCasEnable(boolean casEnable) {
this.casEnable = casEnable;
}
public String getAppServerUrl() {
return appServerUrl;
}
public void setAppServerUrl(String appServerUrl) {
this.appServerUrl = appServerUrl;
}
public String getAppLoginUrl() {
return appLoginUrl;
}
public void setAppLoginUrl(String appLoginUrl) {
this.appLoginUrl = appLoginUrl;
}
public String getAppLogoutUrl() {
return appLogoutUrl;
}
public void setAppLogoutUrl(String appLogoutUrl) {
this.appLogoutUrl = appLogoutUrl;
}
}

View File

@ -0,0 +1,17 @@
package com.unicom.sso.bigdata.cas.demo.config;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
// 可自定义获取用户信息
return new User("admin", "admin", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_ADMIN"));
}
}

View File

@ -0,0 +1,37 @@
package com.unicom.sso.bigdata.cas.demo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
{
@Autowired
private TokenService tokenService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException
{
LoginUser loginUser = tokenService.getLoginUser(request);
if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
{
tokenService.verifyToken(loginUser);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
chain.doFilter(request, response);
}
}

View File

@ -0,0 +1,233 @@
package com.unicom.sso.bigdata.cas.demo.config;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class LoginUser implements UserDetails
{
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
private Long userId;
/**
* 部门ID
*/
private Long deptId;
/**
* 用户唯一标识
*/
private String token;
/**
* 登录时间
*/
private Long loginTime;
/**
* 过期时间
*/
private Long expireTime;
/**
* 登录IP地址
*/
private String ipaddr;
/**
* 登录地点
*/
private String loginLocation;
/**
* 浏览器类型
*/
private String browser;
/**
* 操作系统
*/
private String os;
/**
* 权限列表
*/
private Set<String> permissions;
public Long getUserId()
{
return userId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
public String getToken()
{
return token;
}
public void setToken(String token)
{
this.token = token;
}
public LoginUser()
{
}
/**
* 账户是否未过期,过期无法验证
*/
@JsonIgnore
@Override
public boolean isAccountNonExpired()
{
return true;
}
/**
* 指定用户是否解锁,锁定的用户无法进行身份验证
*
* @return
*/
@JsonIgnore
@Override
public boolean isAccountNonLocked()
{
return true;
}
/**
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
*
* @return
*/
@JsonIgnore
@Override
public boolean isCredentialsNonExpired()
{
return true;
}
/**
* 是否可用 ,禁用的用户不能身份验证
*
* @return
*/
@JsonIgnore
@Override
public boolean isEnabled()
{
return true;
}
public Long getLoginTime()
{
return loginTime;
}
public void setLoginTime(Long loginTime)
{
this.loginTime = loginTime;
}
public String getIpaddr()
{
return ipaddr;
}
public void setIpaddr(String ipaddr)
{
this.ipaddr = ipaddr;
}
public String getLoginLocation()
{
return loginLocation;
}
public void setLoginLocation(String loginLocation)
{
this.loginLocation = loginLocation;
}
public String getBrowser()
{
return browser;
}
public void setBrowser(String browser)
{
this.browser = browser;
}
public String getOs()
{
return os;
}
public void setOs(String os)
{
this.os = os;
}
public Long getExpireTime()
{
return expireTime;
}
public void setExpireTime(Long expireTime)
{
this.expireTime = expireTime;
}
public Set<String> getPermissions()
{
return permissions;
}
public void setPermissions(Set<String> permissions)
{
this.permissions = permissions;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities()
{
return new HashSet();
}
@Override
public String getPassword() {
return null;
}
@Override
public String getUsername() {
return null;
}
}

View File

@ -0,0 +1,251 @@
package com.unicom.sso.bigdata.cas.demo.config;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationEntryPoint;
import org.springframework.security.cas.web.CasAuthenticationFilter;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.web.filter.CorsFilter;
import javax.annotation.Resource;
/**
* spring security配置
*
* @author ruoyi
*/
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Autowired
private CasProperties casProperties;
@Autowired
private CasUserDetailsService customUserDetailsService;
@Autowired
private CasAuthenticationSuccessHandler casAuthenticationSuccessHandler;
/**
* 自定义用户认证逻辑
*/
@Autowired
private UserDetailsService userDetailsService;
/**
* 认证失败处理类
*/
@Autowired
private AuthenticationEntryPointImpl unauthorizedHandler;
/**
* 退出处理类
*/
@Autowired
private LogoutSuccessHandlerImpl logoutSuccessHandler;
/**
* token认证过滤器
*/
@Autowired
private JwtAuthenticationTokenFilter authenticationTokenFilter;
/**
* 跨域过滤器
*/
@Autowired
private CorsFilter corsFilter;
/**
* 解决 无法直接注入 AuthenticationManager
*
* @return
* @throws Exception
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/**
* anyRequest | 匹配所有请求路径
* access | SpringEl表达式结果为true时可以访问
* anonymous | 匿名可以访问
* denyAll | 用户不能访问
* fullyAuthenticated | 用户完全认证可以访问非remember-me下自动登录
* hasAnyAuthority | 如果有参数参数表示权限则其中任何一个权限可以访问
* hasAnyRole | 如果有参数参数表示角色则其中任何一个角色可以访问
* hasAuthority | 如果有参数参数表示权限则其权限可以访问
* hasIpAddress | 如果有参数参数表示IP地址如果用户IP和参数匹配则可以访问
* hasRole | 如果有参数参数表示角色则其角色可以访问
* permitAll | 用户可以任意访问
* rememberMe | 允许通过remember-me登录的用户访问
* authenticated | 用户登录后可访问
*/
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
//开启cas
if (casProperties.isCasEnable()) {
httpSecurity
// CSRF禁用因为不使用session
.csrf().disable()
// 基于token所以不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// 过滤请求
.authorizeRequests()
// 对于登录login 验证码captchaImage 允许匿名访问
//.antMatchers("/login", "/captchaImage").anonymous()
.antMatchers(
HttpMethod.GET,
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js"
).permitAll()
.antMatchers("/profile/**").anonymous()
.antMatchers("/common/download**").anonymous()
.antMatchers("/common/download/resource**").anonymous()
.antMatchers("/swagger-ui.html").anonymous()
.antMatchers("/swagger-resources/**").anonymous()
.antMatchers("/webjars/**").anonymous()
.antMatchers("/*/api-docs").anonymous()
.antMatchers("/druid/**").anonymous()
.antMatchers("/websocket/**").anonymous()
.antMatchers("/magic/web/**").anonymous()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated()
.and()
.headers().frameOptions().disable();
//单点登录登出
httpSecurity.logout().permitAll().logoutSuccessHandler(logoutSuccessHandler);
// Custom JWT based security filter
httpSecurity.addFilter(casAuthenticationFilter())
.addFilterBefore(authenticationTokenFilter, CasAuthenticationFilter.class)
//.addFilterBefore(casLogoutFilter(), LogoutFilter.class)
.addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class).exceptionHandling()
//认证失败
.authenticationEntryPoint(casAuthenticationEntryPoint());
// 添加CORS filter
httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
// disable page caching
httpSecurity.headers().cacheControl();
}
}
/**
* 强散列哈希加密实现
*/
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 身份认证接口
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// cas
if (casProperties.isCasEnable()) {
super.configure(auth);
auth.authenticationProvider(casAuthenticationProvider());
}
}
/**
* 认证的入口
*/
@Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
casAuthenticationEntryPoint.setLoginUrl(casProperties.getCasServerLoginUrl());
casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
return casAuthenticationEntryPoint;
}
/**
* 指定service相关信息
*/
@Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService(casProperties.getAppServerUrl() + casProperties.getAppLoginUrl());
serviceProperties.setAuthenticateAllArtifacts(true);
return serviceProperties;
}
/**
* CAS认证过滤器
*/
@Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
casAuthenticationFilter.setAuthenticationManager(authenticationManager());
casAuthenticationFilter.setFilterProcessesUrl(casProperties.getAppLoginUrl());
casAuthenticationFilter.setAuthenticationSuccessHandler(casAuthenticationSuccessHandler);
return casAuthenticationFilter;
}
/**
* cas 认证 Provider
*/
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
casAuthenticationProvider.setAuthenticationUserDetailsService(customUserDetailsService);
casAuthenticationProvider.setServiceProperties(serviceProperties());
casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
casAuthenticationProvider.setKey("casAuthenticationProviderKey");
return casAuthenticationProvider;
}
@Bean
public Cas20ServiceTicketValidator cas20ServiceTicketValidator() {
return new Cas20ServiceTicketValidator(casProperties.getCasServerUrl());
}
/**
* 单点登出过滤器
*/
@Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
singleSignOutFilter.setCasServerUrlPrefix(casProperties.getCasServerUrl());
singleSignOutFilter.setIgnoreInitConfiguration(true);
return singleSignOutFilter;
}
/**
* 请求单点退出过滤器
*/
@Bean
public LogoutFilter casLogoutFilter() {
LogoutFilter logoutFilter = new LogoutFilter(casProperties.getCasServerLogoutUrl(),
new SecurityContextLogoutHandler());
logoutFilter.setFilterProcessesUrl(casProperties.getAppLogoutUrl());
return logoutFilter;
}
}

View File

@ -0,0 +1,4 @@
package com.unicom.sso.bigdata.cas.demo.config;
public class TokenService {
}

View File

@ -0,0 +1,30 @@
package com.unicom.sso.bigdata.cas.demo.config;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Primary;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.HashSet;
import java.util.Set;
public class UserDetailsServiceImpl implements AuthenticationUserDetailsService<CasAssertionAuthenticationToken> {
@Override
public UserDetails loadUserDetails(CasAssertionAuthenticationToken token) throws UsernameNotFoundException {
System.out.println("getCredentials:" + token.getCredentials());
String username = token.getName();
System.out.println(username);
UserInfo userInfo = new UserInfo();
userInfo.setUsername("admin");
userInfo.setName("admin");
Set<AuthorityInfo> authorities = new HashSet<AuthorityInfo>();
AuthorityInfo authorityInfo = new AuthorityInfo("TEST");
authorities.add(authorityInfo);
userInfo.setAuthorities(authorities);
return userInfo;
}
}

View File

@ -0,0 +1,98 @@
package com.unicom.sso.bigdata.cas.demo.config;
import lombok.Getter;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.HashSet;
import java.util.Set;
public class UserInfo implements UserDetails {
private static final long serialVersionUID = -1041327031937199938L;
/**
* 用户ID
*/
@Getter
private Long id;
/**
* 用户名称
*/
@Getter
private String name;
/**
* 登录名称
*/
@Getter
private String username;
/**
* 登录密码
*/
@Getter
private String password;
private boolean isAccountNonExpired = true;
private boolean isAccountNonLocked = true;
private boolean isCredentialsNonExpired = true;
private boolean isEnabled = true;
@Getter
private Set<AuthorityInfo> authorities = new HashSet<AuthorityInfo>();
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isAccountNonExpired() {
return isAccountNonExpired;
}
public void setAccountNonExpired(boolean accountNonExpired) {
isAccountNonExpired = accountNonExpired;
}
public boolean isAccountNonLocked() {
return isAccountNonLocked;
}
public void setAccountNonLocked(boolean accountNonLocked) {
isAccountNonLocked = accountNonLocked;
}
public boolean isCredentialsNonExpired() {
return isCredentialsNonExpired;
}
public void setCredentialsNonExpired(boolean credentialsNonExpired) {
isCredentialsNonExpired = credentialsNonExpired;
}
public boolean isEnabled() {
return isEnabled;
}
public void setEnabled(boolean enabled) {
isEnabled = enabled;
}
public void setAuthorities(Set<AuthorityInfo> authorities) {
this.authorities = authorities;
}
}

View File

@ -0,0 +1,63 @@
package com.unicom.sso.bigdata.cas.demo.controller;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.validation.Assertion;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* cas 回调地址
* @author baihz10
* @date 2023/7/7 15:44
*/
@Controller
public class HelloController {
@GetMapping("/hello")
public String home(Model model, HttpServletRequest request) {
// String token =request.getParameter("token");
// System.out.println("token : "+token);
// Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
//
// String username= assertion.getPrincipal().getName();
// System.out.println("cas user:"+username);
//
// username = Optional.ofNullable(username).orElse("anonymous");
// Map<String, Object> attributes = Optional.ofNullable(assertion.getPrincipal().getAttributes()).orElse(new HashMap<>());
//
// model.addAttribute("username", username);
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
System.out.println("当前用户信息:" + auth.getPrincipal());
return "home";
}
@GetMapping("/hello2")
public String home2(Model model, HttpServletRequest request) {
String token =request.getParameter("token");
System.out.println("token : "+token);
Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
String username= assertion.getPrincipal().getName();
System.out.println("cas user:"+username);
username = Optional.ofNullable(username).orElse("anonymous");
Map<String, Object> attributes = Optional.ofNullable(assertion.getPrincipal().getAttributes()).orElse(new HashMap<>());
model.addAttribute("username", username);
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
System.out.println("当前用户信息:" + auth.getPrincipal());
return "home";
}
}

View File

@ -0,0 +1,29 @@
package com.unicom.sso.bigdata.cas.demo.controller;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.validation.Assertion;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
/**
* 控制类
* @author baihz10
* @date 2023/7/7 15:44
*/
@Controller
public class SsoLoginController {
@GetMapping("/caslogin")
public String home(Model model,HttpServletRequest request) {
Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
String username= assertion.getPrincipal().getName();
username = Optional.ofNullable(username).orElse("anonymous");
model.addAttribute("username", username);
return "cas/login";
}
}

View File

@ -0,0 +1,25 @@
server.port=10002
#spring.profiles.active=cas-test
base.url=http://cas.demo.maxkey.top:10002
cas.server.url=http://192.168.202.102:8080/sign/authz/cas
#CAS
cas.server.host.url=http://192.168.202.102:8080/sign/authz/cas
#CAS????
#CAS??????
cas.server.host.login_url=${cas.server.host.url}/login
#CAS??????
cas.server.host.logout_url=${cas.server.host.url}/logout?service=${app.server.host.url}
# ??????
app.casEnable=true
app.server.host.url=http://192.168.202.102:${server.port}
#??????
app.server.host.login_url=/
#??????
app.server.host.logout_url=/logout
#??????
app.server.host.web_url=http://192.168.202.102/index

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>sso cas demo</title>
</head>
<body>
<h2 >Login with CAS</h2>
login user : [[${username}]]
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>home</title>
</head>
<body>
hello cas
<br>
hello [[${username}]]
userInfo: [[${userInfo}]]
</body>
</html>