springmvc 功能 登出_CAS5.3 单点登录/登出/springboot/springmvc

环境:

jdk:1.8

cas server:5.3.14 + tomcat 8.5

cas client:3.5.1

客户端1:springmvc 传统web项目(使用web.xml)

客户端2:springboot

为了方便,没配置https.如果需要参考上面博客

一.CAS 服务端搭建

1.下载源码包:cas overlay github地址:https://github.com/apereo/cas-overlay-template/tree/5.3

2.部署:

在根目录下执行mvn clean package,下载依赖需要一段时间,如果有的包下载失败就要修改pom.xml比如xmlsectool的jar包要先从maven中央仓库手动下载,然后加进去,我的放到了图中的maven目录下

springmvc 功能 登出_CAS5.3 单点登录/登出/springboot/springmvc_第1张图片

以下是我修改的pom.xml,对xmlselectool依赖路径进行了更改,增加了json注册服务,jdbc验证等依赖包

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1

2

3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd ">

5

6

7 4.0.0

8 org.apereo.cas

9 cas-overlay

10 war

11 1.0

12

13

14

15

16 com.rimerosolutions.maven.plugins

17 wrapper-maven-plugin

18 0.0.5

19

20 true

21 MD5

22

23

24

25 org.springframework.boot

26 spring-boot-maven-plugin

27 ${springboot.version}

28

29 ${mainClassName}

30 true

31 ${isExecutable}

32 WAR

33

34

35

36

37 repackage

38

39

40

41

42

43 org.apache.maven.plugins

44 maven-war-plugin

45 2.6

46

47 cas

48 false

49 false

50

51 false

52 ${manifestFileToUse}

53

54

55

56 org.apereo.cas

57 cas-server-webapp${app.server}

58

59

60

61

62

63 org.apache.maven.plugins

64 maven-compiler-plugin

65 3.3

66

67

68 cas

69

70

71

72 5.3.14

73 1.5.18.RELEASE

74 1.3.2

75 3.4.6

76

77 -tomcat

78

79 org.springframework.boot.loader.WarLauncher

80 false

81 ${project.build.directory}/war/work/org.apereo.cas/cas-server-webapp${app.server}/META-INF/MANIFEST.MF

82

83 1.8

84 1.8

85 UTF-8

86

87

88

89

90 net.shibboleth.tool

91 xmlsectool

92 2.0.0

93 system

94 ${pom.basedir}/maven/xmlsectool-2.0.0.jar

95

96

97

98 org.apereo.cas

99 cas-server-support-jdbc

100 ${cas.version}

101

102

103 jul-to-slf4j

104 org.slf4j

105

106

107

108

109

110

111 org.apereo.cas

112 cas-server-core-cookie

113 ${cas.version}

114

115

116

117 org.apereo.cas

118 cas-server-support-jdbc-drivers

119 ${cas.version}

120 runtime

121

122

123

124 org.apereo.cas

125 cas-server-core-configuration

126 ${cas.version}

127

128

129

130

131 org.apereo.cas

132 cas-server-core-authentication-api

133 ${cas.version}

134

135

136

137

138 org.apereo.cas

139 cas-server-core-configuration-api

140 ${cas.version}

141

142

143

144

145 org.apereo.cas

146 cas-server-support-json-service-registry

147 ${cas.version}

148

149

150

151

152 org.apereo.cas

153 cas-server-core-authentication-attributes

154 ${cas.version}

155

156

157

158 com.alibaba

159 fastjson

160 1.2.56

161

162

163

164

165

166 org.projectlombok

167 lombok

168 1.18.10

169 provided

170

171

172

173 org.apereo.cas

174 cas-server-core-webflow

175 ${cas.version}

176

177

178

179

180

181

182

183

184

185

186 true

187

188 default

189

190

191 org.apereo.cas

192 cas-server-webapp${app.server}

193 ${cas.version}

194 war

195 runtime

196

197

200

201

202

203

204

205 false

206

207 exec

208

209 org.apereo.cas.web.CasWebApplication

210 true

211

212

213

214

215

216 com.soebes.maven.plugins

217 echo-maven-plugin

218 0.3.0

219

220

221 prepare-package

222

223 echo

224

225

226

227

228

229 Executable profile to make the generated CAS web application executable.

230

231

232

233

234

235

236

237

238

239 false

240

241 bootiful

242

243 -tomcat

244 false

245

246

247

248 org.apereo.cas

249 cas-server-webapp${app.server}

250 ${cas.version}

251 war

252 runtime

253

254

255

256

257

258

259 false

260

261 pgp

262

263

264

265 com.github.s4u.plugins

266 pgpverify-maven-plugin

267 1.1.0

268

269

270

271 check

272

273

274

275

276 hkp://pool.sks-keyservers.net

277 ${settings.localRepository}/pgpkeys-cache

278 test

279 true

280 false

281

282

283

284

285

286

287

View Code

导入idea,导入的时候可以看到实际导入的是

springmvc 功能 登出_CAS5.3 单点登录/登出/springboot/springmvc_第2张图片

新建src/main/java和resources,鼠标放到项目上,然后F4,把java目录标记为sources,resources标记为resources

springmvc 功能 登出_CAS5.3 单点登录/登出/springboot/springmvc_第3张图片

从overlays目录下的WEB-INF拷贝services,META-INF文件夹已经application.properties到我们新建的resources目录下

先说下services文件夹,该文件夹下的json文件定义了哪些应用要接入cas,命名格式为 app-id.json如

703470eefd321c568ba5518d25671e21.png

重点讲下两个属性:1.serviceId定义哪些服务可以接入,可以写统配符,也可以用项目名2.attributeReleaseStrategy定义返回哪些属性,比如登录后返回的用户信息,其他的参考

springmvc 功能 登出_CAS5.3 单点登录/登出/springboot/springmvc_第4张图片

application.properties,端口号,项目名,开启json服务识别

1 ##2 # CAS Server Context Configuration3 #4 server.context-path=/cas5 #server.port=8443

6 server.port=8090

7 server.ssl.enabled=false

8 #server.ssl.key-store=file:/etc/cas/thekeystore9 #server.ssl.key-store-password=changeit10 #server.ssl.key-password=changeit11

12 cas.tgc.secure=false

13

14 spring.devtools.restart.enabled=true

15

16

17 server.max-http-header-size=2097152

18 server.use-forward-headers=true

19 server.connection-timeout=20000

20 server.error.include-stacktrace=ALWAYS21

22 server.compression.enabled=true

23 server.compression.mime-types=application/javascript,application/json,application/xml,text/html,text/xml,text/plain24

25 server.tomcat.max-http-post-size=2097152

26 server.tomcat.basedir=build/tomcat27 server.tomcat.accesslog.enabled=true

28 server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms)29 server.tomcat.accesslog.suffix=.log30 server.tomcat.min-spare-threads=10

31 server.tomcat.max-threads=200

32 server.tomcat.port-header=X-Forwarded-Port33 server.tomcat.protocol-header=X-Forwarded-Proto34 server.tomcat.protocol-header-https-value=https35 server.tomcat.remote-ip-header=X-FORWARDED-FOR36 server.tomcat.uri-encoding=UTF-8

37

38 spring.http.encoding.charset=UTF-8

39 spring.http.encoding.enabled=true

40 spring.http.encoding.force=true

41

42 ##43 # CAS Cloud Bus Configuration44 #45 spring.cloud.bus.enabled=false

46

47 # Indicates that systemPropertiesOverride can be used.48 # Set to false to prevent users from changing the default accidentally. Default true.49 spring.cloud.config.allow-override=true

50

51 # External properties should override system properties.52 spring.cloud.config.override-system-properties=false

53

54 # When allowOverride is true, external properties should take lowest priority, and not override any55 # existing property sources (including local config files).56 spring.cloud.config.override-none=false

57

58 # spring.cloud.bus.refresh.enabled=true

59 # spring.cloud.bus.env.enabled=true

60 # spring.cloud.bus.destination=CasCloudBus61 # spring.cloud.bus.ack.enabled=true

62

63 endpoints.enabled=false

64 endpoints.sensitive=true

65

66 endpoints.restart.enabled=false

67 endpoints.shutdown.enabled=false

68

69 # Control the security of the management/actuator endpoints70 # The 'enabled' flag below here controls the rendering of details forthe health endpoint amongst other things.71 management.security.enabled=true

72 management.security.roles=ACTUATOR,ADMIN73 management.security.sessions=if_required74 management.context-path=/status75 management.add-application-context-header=false

76

77 # Define a CAS-specific "WARN"status code and its order78 management.health.status.order=WARN, DOWN, OUT_OF_SERVICE, UNKNOWN, UP79

80 # Control the security of the management/actuator endpoints81 # With basic authentication, assuming Spring Security and/or relevant modules are on the classpath.82 security.basic.authorize-mode=role83 security.basic.path=/cas/status/**

84 security.basic.enabled=true85 security.user.name=casuser86 security.user.password=12387

88 ##89 # CAS Web Application Session Configuration90 #91 server.session.timeout=300092 server.session.cookie.http-only=false93 server.session.tracking-modes=COOKIE94

95 ##96 # CAS Thymeleaf View Configuration97 #98 spring.thymeleaf.encoding=UTF-899 spring.thymeleaf.cache=true100 spring.thymeleaf.mode=HTML101 spring.thymeleaf.template-resolver-order=100102 ##103 # CAS Log4j Configuration104 #105 # logging.config=file:/etc/cas/log4j2.xml106 server.context-parameters.isLog4jAutoInitializationDisabled=true107

108 ##109 # CAS AspectJ Configuration110 #111 spring.aop.auto=true112 spring.aop.proxy-target-class=true113

114 ##115 # CAS Authentication Credentials116 #117 #cas.authn.accept.users=wangyuancheng::Baizhu7958118

119

120

121 ##122 # Service Registry(服务注册)123 #124 # 开启识别Json文件,默认false125 cas.serviceRegistry.initFromJson=true126

127 #自动扫描服务配置,默认开启128 #cas.serviceRegistry.watcherEnabled=true129

130 #120秒扫描一遍131 cas.serviceRegistry.schedule.repeatInterval=120000132

133 #延迟15秒开启134 # cas.serviceRegistry.schedule.startDelay=15000135

136 ##137 # Json配置138 cas.serviceRegistry.json.location=classpath:/services139

140

141 cas.ticket.tgt.maxTimeToLiveInSeconds=28800142 cas.ticket.tgt.timeToKillInSeconds=7200143 cas.ticket.tgt.rememberMe.enabled=true144 # 使用次数145 cas.ticket.st.numberOfUses=1146 # 过期时间100秒147 cas.ticket.st.timeToKillInSeconds=100148

149 cas.httpClient.allowLocalLogoutUrls=true150

151

152 cas.slo.disabled=false153 cas.logout.followServiceRedirects=true154 cas.logout.removeDescendantTickets=true155 cas.slo.asynchronous=true

默认情况下cas会提供一个jdbc的验证方式,把sql写在application.properties,但这种方式无法提供返回的用户信息,因此需要定义验证处理器及配置信息

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecn.bz.bzsso.authentication;2

3 importcn.bz.bzsso.entity.User;4 importcn.bz.bzsso.handler.MyAuthenticationHandler;5 importcn.bz.bzsso.mapper.UserMapper;6 importorg.apereo.cas.authentication.AuthenticationEventExecutionPlan;7 importorg.apereo.cas.authentication.AuthenticationEventExecutionPlanConfigurer;8 importorg.apereo.cas.authentication.AuthenticationHandler;9 importorg.apereo.cas.authentication.principal.DefaultPrincipalFactory;10 importorg.apereo.cas.configuration.CasConfigurationProperties;11 importorg.apereo.cas.services.ServicesManager;12 importorg.springframework.beans.factory.annotation.Autowired;13 importorg.springframework.beans.factory.annotation.Qualifier;14 importorg.springframework.boot.context.properties.EnableConfigurationProperties;15 importorg.springframework.context.annotation.Bean;16 importorg.springframework.context.annotation.Configuration;17

18 /**

19 *@authortele20 * @Description21 * @create 2019-12-0422 */

23 @Configuration("myAuthenticationConfiguration")24 @EnableConfigurationProperties(CasConfigurationProperties.class)25 public class MyAuthenticationConfiguration implementsAuthenticationEventExecutionPlanConfigurer {26

27 @Autowired28 privateCasConfigurationProperties casProperties;29

30 @Autowired31 @Qualifier("servicesManager")32 privateServicesManager servicesManager;33

34

35 /**

36 * 将自定义验证器注册为Bean37 *@return

38 */

39 @Bean40 publicAuthenticationHandler myAuthenticationHandler() {41 MyAuthenticationHandler handler = new MyAuthenticationHandler(MyAuthenticationHandler.class.getSimpleName(), servicesManager, new DefaultPrincipalFactory(), 1);42 returnhandler;43 }44

45 /**

46 * 注册验证器47 *@paramplan48 */

49 @Override50 public voidconfigureAuthenticationExecutionPlan(AuthenticationEventExecutionPlan plan) {51 plan.registerAuthenticationHandler(myAuthenticationHandler());52 }53 }

View Code

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecn.bz.bzsso.handler;2

3 importcn.bz.bzsso.entity.LoginCode;4 importcn.bz.bzsso.entity.LoginStatus;5 importcn.bz.bzsso.entity.User;6 importcom.alibaba.fastjson.JSON;7 importcom.alibaba.fastjson.serializer.SerializerFeature;8 importorg.apereo.cas.authentication.AuthenticationHandlerExecutionResult;9 importorg.apereo.cas.authentication.PreventedException;10 importorg.apereo.cas.authentication.UsernamePasswordCredential;11 importorg.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;12 importorg.apereo.cas.authentication.principal.PrincipalFactory;13 importorg.apereo.cas.services.ServicesManager;14 importorg.springframework.jdbc.core.BeanPropertyRowMapper;15 importorg.springframework.jdbc.core.JdbcTemplate;16 importorg.springframework.jdbc.datasource.DriverManagerDataSource;17 importjava.security.GeneralSecurityException;18 importjava.util.ArrayList;19 importjava.util.HashMap;20 importjava.util.Map;21

22 /**

23 *@authortele24 * @Description25 * @create 2019-12-0426 */

27 public class MyAuthenticationHandler extendsAbstractUsernamePasswordAuthenticationHandler {28

29

30 publicMyAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) {31 super(name, servicesManager, principalFactory, order);32 }33

34 @Override35 protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential, String originalPassword) throwsGeneralSecurityException, PreventedException {36 String username =credential.getUsername();37 String password =credential.getPassword();38

39

40 DriverManagerDataSource dataSource = newDriverManagerDataSource();41 dataSource.setDriverClassName("com.mysql.jdbc.Driver");42 dataSource.setUrl("xx");43 dataSource.setUsername("xx");44 dataSource.setPassword("xx");45

46 //创建JDBC模板

47 JdbcTemplate jdbcTemplate = newJdbcTemplate();48 jdbcTemplate.setDataSource(dataSource);49

50 String sql = "select id,username,nickname,password from tb_user where username = ?";51

52 User user = (User) jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper(User.class));53

54 LoginStatus loginStatus = newLoginStatus();55 loginStatus.setId(user.getId());56 loginStatus.setUsername(user.getUserName());57 loginStatus.setNickname(user.getNickName());58

59 if(user.getPassword().equals(password)) {60 loginStatus.setCode(LoginCode.LOGIN_SUCCESS);61 loginStatus.setMessage(LoginCode.MSG_LOGIN_SUCCESS);62 }else{63 loginStatus.setCode(LoginCode.ERROR_OF_USER_PWD);64 loginStatus.setMessage(LoginCode.MSG_ERROR_OF_USER_PWD);65 }66

67 Map resultMap = new HashMap<>(4);68

69 resultMap.put("loginStatus", JSON.toJSONString(loginStatus,SerializerFeature.WriteNullStringAsEmpty));70

71 return createHandlerResult(credential, this.principalFactory.createPrincipal(credential.getUsername(),resultMap), new ArrayList<>(0));72

73 }74 }

View Code

修改MATA-INF下的spring.factoriesorg.springframework.boot.autoconfigure.EnableAutoConfiguration=xx.MyAuthenticationConfiguration

ok,服务端配置到此结束,你可以自定义返回的信息,状态码等

二.客户端接入

既然接入了cas,那么所有的客户端都应该关闭登录与退出接口,扒了下官网,看到一句话大概意思是cas不是一个session管理器,每个应用应当对自己的session负责,cas只会在退出时给接入的应用发通知,然后移除内部维护的tgt对象

,换句话说,每个应用内部应当调用session.invalidate()来销毁各自的session

1.传统web项目接入.这种指的是带有web.xml的web

加入cas-client 版本3.5.1依赖

1

2

3 org.jasig.cas.client

4 cas-client-core

5 ${cas-client.version}

6

7

8

9 org.jasig.cas.client

10 cas-client-integration-tomcat-common

11 ${cas-client.version}

12

在web.xml中加入如下配置,本机环境不建议使用localhost,使用127.0.0.1(5.1版本使用localhost会有退出失效无法通信的问题,浏览器存储cookie时127.0.0.1和localhost是两个不同的文件夹)

servername指的是客户端地址

1

2 org.jasig.cas.client.session.SingleSignOutHttpSessionListener

3

4

5

6

7

8 CAS Single Sign Out Filter

9 org.jasig.cas.client.session.SingleSignOutFilter

10

11 casServerUrlPrefix

12 http://127.0.0.1:8090/cas/

13

14

15

16 CAS Single Sign Out Filter

17 /*18 19

20

21

22 23 24 CAS Authentication Filter25 org.jasig.cas.client.authentication.AuthenticationFilter26 27 casServerLoginUrl28 http://127.0.0.1:8090/cas/login29 30 31 serverName32 33 http://127.0.0.1:808034 35 36 37 CAS Authentication Filter38 /*39 40

41

42 43 44 CAS Validation Filter45 org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter46 47 casServerUrlPrefix48 http://127.0.0.1:8090/cas/49 50 51 serverName52 http://127.0.0.1:808053 54 55 redirectAfterValidation56 true57 58 59 useSession60 true61 62 63 authn_method64 mfa-duo65 66 67 68 CAS Validation Filter69 /*70 71

72 73 74 CASAssertion Thread LocalFilter75 org.jasig.cas.client.util.AssertionThreadLocalFilter76 77 78 CASAssertion Thread LocalFilter79 /*80 81

82

83 84 85 CAS HttpServletRequest Wrapper Filter86 org.jasig.cas.client.util.HttpServletRequestWrapperFilter87 88

89 90 CAS HttpServletRequest Wrapper Filter91 /*92

客户端获得cas返回的登录信息的api,或者使用AssertionHolder.getAssertion().getPrincipal().getAttributes("xx");,严谨一点可以先判空,避免NPE

1 @RequestMapping("/login")2 @ResponseBody3 publicString login() {4 AttributePrincipal userPrincipal =(AttributePrincipal)request.getUserPrincipal();5 return userPrincipal.getAttributes().get("loginStatus").toString();6 }

下面讲下退出

@RequestMapping(value = "logout")public String logout(HttpSession session) throwsInterruptedException {

session.invalidate();return "redirect:" +CASConstant.LOGOUT_URL;

}

我在做的时候发现退出请求总是无法触发,后来发现是项目中有拦截器,于是加了一个excluedUrl,然后在对应的拦截器init的时候filterConfig.getInitParameter("excludedUrl");接下来dofilter时判断如果含有该路径重定向即可,但这样实际相当于重定向两次

b30b49836c8b70087bbf966d7ba0cb43.png

springmvc 功能 登出_CAS5.3 单点登录/登出/springboot/springmvc_第5张图片

还有一个问题是上面redirect的地址如果需要spring静态注入,(当然写死可以),在applicationContext.xml中引入对应的url.properties,然后需要注入的常量类提供set方法即可,需要注意的是spring的注入是基于对象的.所以该set方法不能有static

springmvc 功能 登出_CAS5.3 单点登录/登出/springboot/springmvc_第6张图片

2.springboot 项目接入cas.springboot内置tomcat,不再需要加入tomcat

pom.xml

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1

2 1.8

3 3.5.1

4

5

6

7

8

9

10 org.jasig.cas.client

11 cas-client-core

12 ${cas.client.version}

13

14

15

16

17 org.springframework.boot

18 spring-boot-devtools

19 true

20

21

22

23 org.springframework.boot

24 spring-boot-configuration-processor

25

26

27

28

29 org.springframework.boot

30 spring-boot-starter-web

31

32

33

34 org.springframework.boot

35 spring-boot-autoconfigure

36 2.2.0.RELEASE

37

38

39

40 org.mybatis.spring.boot

41 mybatis-spring-boot-starter

42 2.1.1

43

44

45

46 mysql

47 mysql-connector-java

48 runtime

49

50

51

52 com.alibaba

53 druid

54 1.1.10

55

56

57

58 org.projectlombok

59 lombok

60 true

61

62

63 org.springframework.boot

64 spring-boot-starter-test

65 test

66

67

68 org.junit.vintage

69 junit-vintage-engine

70

71

72

73

View Code

在你的application.properties加入如下配置,依然建议使用127.0.0.1

1 # 监听退出的接口,即所有接口都会进行监听2 spring.cas.sign-out-filters=/*

3 # 需要拦截的认证的接口4 spring.cas.auth-filters=/*5 spring.cas.validate-filters=/*6 spring.cas.request-wrapper-filters=/*7 spring.cas.assertion-filters=/*8 # 表示忽略拦截的接口,也就是不用进行拦截9 spring.cas.ignore-filters=/test10 spring.cas.cas-server-login-url=http://127.0.0.1:8090/cas/login11 spring.cas.cas-server-url-prefix=http://127.0.0.1:8090/cas/12 spring.cas.redirect-after-validation=true13 spring.cas.use-session=true14 spring.cas.redirectAfterValidation=true15 # 客户端地址16 spring.cas.server-name=http://127.0.0.1:8081

下面要注入之前在web.xml中配置的各种拦截器

代码与参考的博客类似,做了些修改,@ConfigurationProperties依赖spring-boot-configuration-processor

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 @Configuration2 public classCasCustomConfig {3 @Autowired4 SpringCasAutoconfig autoconfig;5

6 private static boolean casEnabled = true;7

8 publicCasCustomConfig() {9 }10

11 @Bean12 publicSpringCasAutoconfig getSpringCasAutoconfig() {13 return newSpringCasAutoconfig();14 }15

16 @Bean17 public ServletListenerRegistrationBeansingleSignOutHttpSessionListener() {18 ServletListenerRegistrationBean listener = new ServletListenerRegistrationBean();19 listener.setEnabled(casEnabled);20 listener.setListener(newSingleSignOutHttpSessionListener());21 listener.setOrder(1);22 returnlistener;23 }24

25

26

27 /**

28 * 该过滤器用于实现单点登出功能,单点退出配置,一定要放在其他filter之前29 *@return

30 */

31 @Bean32 publicFilterRegistrationBean singleSignOutFilter() {33 FilterRegistrationBean filterRegistration = newFilterRegistrationBean();34 filterRegistration.setFilter(newSingleSignOutFilter());35 filterRegistration.setEnabled(casEnabled);36 if (autoconfig.getSignOutFilters().size() > 0) {37 filterRegistration.setUrlPatterns(autoconfig.getSignOutFilters());38 } else{39 filterRegistration.addUrlPatterns("/*");40 }41 filterRegistration.addInitParameter("casServerUrlPrefix", autoconfig.getCasServerUrlPrefix());42 filterRegistration.addInitParameter("serverName",autoconfig.getServerName());43 filterRegistration.setOrder(1);44 returnfilterRegistration;45 }46

47

48 /**

49 * 该过滤器负责用户的认证工作50 *51 *@return

52 */

53 @Bean54 publicFilterRegistrationBean authenticationFilter() {55 FilterRegistrationBean filterRegistration = newFilterRegistrationBean();56 filterRegistration.setFilter(newAuthenticationFilter());57 filterRegistration.setEnabled(casEnabled);58 if (autoconfig.getAuthFilters().size() > 0) {59 filterRegistration.setUrlPatterns(autoconfig.getAuthFilters());60 } else{61 filterRegistration.addUrlPatterns("/*");62 }63 if (autoconfig.getIgnoreFilters() != null) {64 filterRegistration.addInitParameter("ignorePattern", autoconfig.getIgnoreFilters());65 }66 filterRegistration.addInitParameter("casServerLoginUrl", autoconfig.getCasServerLoginUrl());67 filterRegistration.addInitParameter("serverName", autoconfig.getServerName());68 //filterRegistration.addInitParameter("useSession", autoconfig.isUseSession() ? "true" : "false");69 //filterRegistration.addInitParameter("redirectAfterValidation", autoconfig.isRedirectAfterValidation() ? "true" : "false");

70 filterRegistration.setOrder(2);71 returnfilterRegistration;72 }73

74 /**

75 * 该过滤器负责对Ticket的校验工作,使用CAS 3.0协议76 *77 *@return

78 */

79 @Bean80 publicFilterRegistrationBean cas30ProxyReceivingTicketValidationFilter() {81 FilterRegistrationBean filterRegistration = newFilterRegistrationBean();82 filterRegistration.setFilter(newCas30ProxyReceivingTicketValidationFilter());83 filterRegistration.setEnabled(casEnabled);84 if (autoconfig.getValidateFilters().size() > 0) {85 filterRegistration.setUrlPatterns(autoconfig.getValidateFilters());86 } else{87 filterRegistration.addUrlPatterns("/*");88 }89 filterRegistration.addInitParameter("casServerUrlPrefix", autoconfig.getCasServerUrlPrefix());90 filterRegistration.addInitParameter("serverName", autoconfig.getServerName());91 filterRegistration.addInitParameter("useSession", autoconfig.isUseSession() ? "true" : "false");92 filterRegistration.addInitParameter("redirectAfterValidation", autoconfig.isRedirectAfterValidation() ? "true" : "false");93 filterRegistration.addInitParameter("authn_method", "mfa-duo");94 filterRegistration.setOrder(3);95 returnfilterRegistration;96 }97

98

99 /**

100 * 该过滤器使得可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。101 * 比如AssertionHolder.getAssertion().getPrincipal().getName()。102 * 这个类把Assertion信息放在ThreadLocal变量中,这样应用程序不在web层也能够获取到当前登录信息103 *104 *@return

105 */

106 @Bean107 publicFilterRegistrationBean assertionThreadLocalFilter() {108 FilterRegistrationBean filterRegistration = newFilterRegistrationBean();109 filterRegistration.setFilter(newAssertionThreadLocalFilter());110 filterRegistration.setEnabled(true);111 if (autoconfig.getAssertionFilters().size() > 0) {112 filterRegistration.setUrlPatterns(autoconfig.getAssertionFilters());113 } else{114 filterRegistration.addUrlPatterns("/*");115 }116 filterRegistration.setOrder(4);117 returnfilterRegistration;118 }119

120

121 @Bean122 publicFilterRegistrationBean httpServletRequestWrapperFilter() {123 FilterRegistrationBean filterRegistration = newFilterRegistrationBean();124 filterRegistration.setFilter(newHttpServletRequestWrapperFilter());125 filterRegistration.setEnabled(true);126 if (autoconfig.getRequestWrapperFilters().size() > 0) {127 filterRegistration.setUrlPatterns(autoconfig.getRequestWrapperFilters());128 } else{129 filterRegistration.addUrlPatterns("/*");130 }131 filterRegistration.setOrder(5);132 returnfilterRegistration;133 }134 }

View Code

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 @ConfigurationProperties(prefix = "spring.cas")2 public classSpringCasAutoconfig {3

4 static final String separator = ",";5

6 privateString validateFilters;7 privateString signOutFilters;8 privateString authFilters;9 privateString assertionFilters;10 privateString requestWrapperFilters;11 private String ignoreFilters; //需要放行的url,多个可以使用|分隔,遵循正则

12

13 privateString casServerUrlPrefix;14 privateString casServerLoginUrl;15 privateString serverName;16 private boolean useSession = true;17 private boolean redirectAfterValidation = true;18

19 publicString getIgnoreFilters() {20 returnignoreFilters;21 }22

23 public voidsetIgnoreFilters(String ignoreFilters) {24 this.ignoreFilters =ignoreFilters;25 }26

27 public ListgetValidateFilters() {28 returnArrays.asList(validateFilters.split(separator));29 }30

31 public voidsetValidateFilters(String validateFilters) {32 this.validateFilters =validateFilters;33 }34

35 public ListgetSignOutFilters() {36 returnArrays.asList(signOutFilters.split(separator));37 }38

39 public voidsetSignOutFilters(String signOutFilters) {40 this.signOutFilters =signOutFilters;41 }42

43 public ListgetAuthFilters() {44 returnArrays.asList(authFilters.split(separator));45 }46

47 public voidsetAuthFilters(String authFilters) {48 this.authFilters =authFilters;49 }50

51 public ListgetAssertionFilters() {52 returnArrays.asList(assertionFilters.split(separator));53 }54

55 public voidsetAssertionFilters(String assertionFilters) {56 this.assertionFilters =assertionFilters;57 }58

59 public ListgetRequestWrapperFilters() {60 returnArrays.asList(requestWrapperFilters.split(separator));61 }62

63 public voidsetRequestWrapperFilters(String requestWrapperFilters) {64 this.requestWrapperFilters =requestWrapperFilters;65 }66

67 publicString getCasServerUrlPrefix() {68 returncasServerUrlPrefix;69 }70

71 public voidsetCasServerUrlPrefix(String casServerUrlPrefix) {72 this.casServerUrlPrefix =casServerUrlPrefix;73 }74

75 publicString getCasServerLoginUrl() {76 returncasServerLoginUrl;77 }78

79 public voidsetCasServerLoginUrl(String casServerLoginUrl) {80 this.casServerLoginUrl =casServerLoginUrl;81 }82

83 publicString getServerName() {84 returnserverName;85 }86

87 public voidsetServerName(String serverName) {88 this.serverName =serverName;89 }90

91 public booleanisRedirectAfterValidation() {92 returnredirectAfterValidation;93 }94

95 public void setRedirectAfterValidation(booleanredirectAfterValidation) {96 this.redirectAfterValidation =redirectAfterValidation;97 }98

99 public booleanisUseSession() {100 returnuseSession;101 }102

103 public void setUseSession(booleanuseSession) {104 this.useSession =useSession;105 }106 }

View Code

接下来时登录和登出,不要直接丢个@RestController就完事了,这个主解会让redirect失效,当成字符串转成json返回了,最好的方式是使用@Controller,需要转json的加上@ResponseBody

1 @Controller2 public classLoginController {3

4 @Autowired5 privateUserMapper userMapper;6

7 @Autowired8 privateHttpServletRequest request;9

10 @RequestMapping("/login")11 @ResponseBody12 publicString login() {13 AttributePrincipal userPrincipal =(AttributePrincipal)request.getUserPrincipal();14 return userPrincipal.getAttributes().get("loginStatus").toString();15 }16

17 @RequestMapping("/logout")18 publicString logout(HttpSession session) {19 session.removeAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);20 session.invalidate();21 return "redirect:http://127.0.0.1:8090/cas/logout?service=http://127.0.0.1:8081/spring_boot/login/";22 }23

24 private voidprintln(Object object) {25 System.out.println(object);26 }27 }

三.验证

springmvc 功能 登出_CAS5.3 单点登录/登出/springboot/springmvc_第7张图片

三.关于源码

源码看了下客户端的拦截器与处理器,大概流程如下,在浏览器输入http://127.0.0.1:8081/spring_boot/login/会被重定向到http://127.0.0.1:8090/cas/login?service=http://127.0.0.1:8081/spring_boot/login/,也就是cas的登录页,点击登录之后,cas server进行验证,之后会进入客户端的拦截器SingleSignOutFilter,拦截器判断请求类型,如果是tokenrequest(带token的请求),保存session和st,如果是登出请求,将st,session从map中移除,在destroySession中session.invalidate(),但是其他接入的客户端并没有销毁session,退出时,cas只会给接入的客户端发通知,当然从哪个客户端发起的退出该客户端的session会被destroy,但其他客户端要在登出接口中session.invalidate(),

springmvc 功能 登出_CAS5.3 单点登录/登出/springboot/springmvc_第8张图片

你可能感兴趣的:(springmvc,功能,登出)