Because existing systems require external access, single sign-on needs the support of three parties. Because the system itself is a micro-service architecture, a plurality of operational independence of subsystems, so has its own micro user authentication service (not cas, we have enough infrastructure, and now can not be increased without increasing). But because customers and other access (public cloud network) reasons, can not be achieved by token + redis, it also needs the support of an external cas.
Existing authentication system using shiro achieve, shiro + token service subsystem using fake sign-on implementation. Cas Login now to support tripartite system configuration settings through their authentication subsystem is enabled. Whether this is to use your own authentication implementation, or tripartite CAS, the whole process is completely different.
CAS server set up
Cas 4 from the start, it no longer provides official release war, in turn, need to download the source code package, online a lot, not described here (download depend a bit slow). 4.x and before the war can be downloaded from https://mvnrepository.com/artifact/org.jasig.cas/cas-server-webapp. After downloading, extract it to tomcat webapp directory:
start up:
Modify the following configuration:
Certification removal https:
In tomcat \ webapps \ cas \ WEB- INF \ deployerConfigContext.xml file p's: httpClient-ref = "httpClient" add back p: requireSecure = "false" the tomcat \ webapps \ cas \ WEB- INF \ spring-configuration of ticketGrantingTicketCookieGenerator .xml file inside the p: cookieSecure = "true" changed to false; the p-: the cookie cookieMaxAge = "- 1" was changed to 3600 (-1 does not save cookie, 3600 seconds is the one hour, save login information) to tomcat \ webapps \ cas \ WEB-INF \ spring- configuration of warnCookieGenerator.xml of p: cookieSecure = "true" read false the p-: the cookie cookieMaxAge = "- 1" was changed to 3600
Configuring single out:
The tomcat \ webapps cas WEB-INF cas-servlet.xml in $ {cas.logout.followServiceRedirects: false} \ \ \ Values in parenthesis to true
Authentication can be configured simple test (remove <bean class = "org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /> Note) or based on data origin authentication (refer https://www.cnblogs.com/wlwl/ p / 10056067.html).
spring boot cas client integration
Library dependencies:
<dependency> <groupId>net.unicon.cas</groupId> <artifactId>cas-client-autoconfig-support</artifactId> <version>1.5.0-GA</version> </dependency> <dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <version>3.2.1</version> <exclusions> <exclusion> <artifactId>servlet-api</artifactId> <groupId>javax.servlet</groupId> </exclusion> </exclusions> </dependency>
application.properties add in the following configurations:
cas.server-url-prefix = http: // localhost: 8080 / cas
cas.server-login-url = http: // localhost: 8080 / cas / login
cas.client-host-url = http: // localhost: 18080 /
cas.use-session = true
cas.validation-type = cas
casClientLogoutUrl = http: // localhost: 8080 / cas / logout service = http: // localhost: 18080 / tabase / logout.html
import net.unicon.cas.client.configuration.EnableCasClient; @EnableCasClient //启用cas client @CloudApplication public class ConsumerStarter { public static void main(String[] args) { CloudBootstrap.run(ConsumerStarter.class, args); } } package com.hs; import java.util.HashMap; import java.util.Map; import org.jasig.cas.client.authentication.AuthenticationFilter; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class CASAutoConfig { @Value("${cas.server-url-prefix}") private String serverUrlPrefix; @Value("${cas.server-login-url}") private String serverLoginUrl; @Value("${cas.client-host-url}") private String clientHostUrl; /** * 授权过滤器 * @return */ @Bean public FilterRegistrationBean filterAuthenticationRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new AuthenticationFilter()); // 设定匹配的路径 registration.addUrlPatterns("/*"); Map<String,String> initParameters = new HashMap<String, String>(); initParameters.put("casServerLoginUrl", serverUrlPrefix); initParameters.put("serverName", clientHostUrl); //忽略的url,"|"Separate multiple url initParameters.put ( "ignorePattern", "/ Zimbabwe Logout / Success | / index" ); registration.setInitParameters (the InitParameters); // set load order registration.setOrder (. 1 ); return Registration; } }
shiro analog login (shiro does not modify the existing authentication framework)
After cas login is successful, the application will return ticket, which contains the user name. At this time, the application will be UserFilter Home intercepted shiro filter, where you can determine whether a user name on the ticket HttpServletRequest, there is, and a valid user name, you can use that username simulation logged. So that the entire certification process shiro almost no change, no need to modify FormAuthenticationFilter.
cas obtain a user name 2.x and 3.x versions are not the same, it should be noted.
Version 2.x client acquisition method the user name CAS passed over:
// 以下三者都可以 session.getAttribute(CASFilter.CAS_FILTER_USER); session.getAttribute("edu.yale.its.tp.cas.client.filter.user"); CASFilterRequestWrapper reqWrapper=new CASFilterRequestWrapper(request); reqWrapper.getRemoteUser());
3.x version client acquisition method the user name CAS passed over:
HttpServletRequest request = ServletActionContext.getRequest(); AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal(); String username = principal.getName(); Long orgnId = Long.parseLong(principal.getAttributes().get("orgnId").toString());
After the get, we can simulate the landing.
boolean isAllowed = super.isAccessAllowed(request, response, mappedValue); // if (isAllowed) { } else if (Boolean.valueOf(BaseConfig.getConfig("ta.casEnable","false"))) { AttributePrincipal principal = (AttributePrincipal)((HttpServletRequest) request).getUserPrincipal(); String username = principal.getName(); Subject subject = getSubject(request, response); AuthenticationToken token = new UsernamePasswordToken(); ((UsernamePasswordToken) token).setUsername(username); ((UsernamePasswordToken) token).setPassword(new char[] {'1'}); subject.login(token); isAllowed = super.isAccessAllowed(request, response, mappedValue); }
shiro NoboriIzuru
Call session.invalidate in shiro's logoutFilter in () can be. Then return address casClientLogoutUrl configured to withdraw cas.
/** * CAS添加开始 */ if (StringUtils.isNotBlank(BaseConfig.getConfig("casClientLogoutUrl"))) { ((HttpServletRequest)request).getSession().invalidate(); redirectUrl = BaseConfig.getConfig("casClientLogoutUrl"); } // CAS添加结束 return redirectUrl;
Sincerely, on complete implementation of the cas + shiro simulate login.
CAS ticket expiration policy, refer to: https: //www.cnblogs.com/gao241/p/3367869.html
CAS process description, refer to: https: //www.cnblogs.com/xiatian0721/p/8136305.html
CAS official Schema Reference: https: //apereo.github.io/cas/5.3.x/planning/Architecture.html