客户端配置

  1. 增加依赖

    maven

     <!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
     <dependency>
         <groupId>javax.servlet.jsp.jstl</groupId>
         <artifactId>jstl</artifactId>
         <version>1.2</version>
     </dependency>
     <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
     <dependency>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-core</artifactId>
         <version>1.4.0</version>
     </dependency>
     <!-- https://mvnrepository.com/artifact/org.jasig.cas.client/cas-client-core -->
     <dependency>
         <groupId>org.jasig.cas.client</groupId>
         <artifactId>cas-client-core</artifactId>
         <version>3.3.3</version>
     </dependency>
    

    Gradle:

     implementation group: 'javax.servlet', name: 'jstl'
     implementation group: 'org.apache.shiro', name: 'shiro-cas', version: '1.4.0'
     implementation group: 'org.jasig.cas.client', name: 'cas-client-core', version: '3.3.3'
    
  2. 增加MyFilter,继承CasFilter

     public class MyCasFilter extends CasFilter {
         private static final Logger logger = LoggerFactory.getLogger(MyCasFilter.class);
         private static final String TICKET_PARAMETER = "ticket";
    
         public static String CUSTOM_SESSION_KEY = "custom_session_key";
    
         private String casServerLoginUrl;
    
         private String failureUrl;
    
         public MyCasFilter() {
         }
    
         @Override
         public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
             HttpServletRequest httpRequest = (HttpServletRequest) request;
             String ticket = httpRequest.getParameter(TICKET_PARAMETER);
             logger.info("CAS login with ticket: {}.", ticket);
    
             if (StringUtils.isEmpty(ticket)) {
                 logger.info("SSO ticket not provided, redirect to CAS server.");
                 //redirect to SSO server if ticket not provided
                 WebUtils.issueRedirect(request, response, casServerLoginUrl);
                 return false;
             }
    
             return super.onPreHandle(request, response, mappedValue);
         }
    
         @Override
         protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException ae, ServletRequest request, ServletResponse response) {
             //Go to login page if CAS not verified
             Subject subject = getSubject(request, response);
             if (subject.isAuthenticated()) {
                 subject.logout();
             }
             try {
                 WebUtils.issueRedirect(request, response, failureUrl);
             } catch (IOException e) {
                 logger.error("Cannot redirect to failure url : {}", failureUrl, e);
             }
             return false;
         }
    
         @Override
         protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest req, ServletResponse resp)
                 throws Exception {
             HttpServletRequest request = (HttpServletRequest) req;
             HttpServletResponse response = (HttpServletResponse) resp;
    
             WebUtils.issueRedirect(request, response, getSuccessUrl());
             return true;
         }
    
         public String getCasServerLoginUrl() {
             return casServerLoginUrl;
         }
    
         public void setCasServerLoginUrl(String casServerLoginUrl) {
             this.casServerLoginUrl = casServerLoginUrl;
         }
    
         public String getFailureUrl() {
             return failureUrl;
         }
    
         @Override
         public void setFailureUrl(String failureUrl) {
             this.failureUrl = failureUrl;
         }
     }
    
  3. 增加MyRealm,继承CasRealm

     public class MyShiroCasRealm extends CasRealm {
    
         @Autowired
         private UserService userService;
    
         @Override
         protected void onInit() {
             super.onInit();
             //SSO doesn't need to check password
             this.setCredentialsMatcher(new AllowAllCredentialsMatcher());
         }
    
         /**
          * 权限认证,为当前登录的Subject授予角色和权限
          * 本例中该方法的调用时机为需授权资源被访问时
          * 并且每次访问需授权资源时都会执行该方法中的逻辑,这表明本例中默认并未启用AuthorizationCache
          * 如果连续访问同一个URL(比如刷新),该方法不会被重复调用,Shiro有一个时间间隔(也就是cache时间,在ehcache-shiro.xml中配置),超过这个时间间隔再刷新页面,该方法会被执行
          */
         @Override
         protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
             return new SimpleAuthorizationInfo();
         }
    
         /**
          * 1、CAS认证 ,验证用户身份
          * 2、换取token
          */
         @Override
         protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
             /**
              * 可以写自定义的验证逻辑,但是必须调用super.doGetAuthenticationInfo(token);
              */
             return  super.doGetAuthenticationInfo(token);
         }
    
     }
    
  4. 增加CasConfiguration类,填写好cas 的server地址、 后台服务器地址、前端服务器地址

     public class ShiroCasConfiguration {
         // cas 的server地址
         public String casServerUrlPrefix = "";
         // 后台服务器地址
         public String backServerUrl = "";
         // 前端服务器地址
         public String frontServerUrl = "";
         //    cas 登录页面的地址
         public String casLoginUrl = casServerUrlPrefix + "/login";
         //    casFilter cas 拦截的地址
         public final String casFilterUrlPattern = "/cas/loginSuccess";
         //    登录成功的地址
         public final String loginSuccessUrl = frontServerUrl + "/login.html";
         //  登录成功之后的转跳地址,用于校验ticket,换取token
         public final String serverPath = casLoginUrl + "?service=" + backServerUrl + casFilterUrlPattern;
    
         /**
          * 添加cas验证realm
          */
         public MyShiroCasRealm myShiroCasRealm() {
             MyShiroCasRealm myShiroCasRealm = new MyShiroCasRealm();
             myShiroCasRealm.setCasServerUrlPrefix(casServerUrlPrefix);
             myShiroCasRealm.setCasService(backServerUrl + casFilterUrlPattern);
             return myShiroCasRealm;
         }
    
         public FilterRegistrationBean filterRegistrationBean() {
             FilterRegistrationBean bean = new FilterRegistrationBean();
             bean.setFilter(new DelegatingFilterProxy("shiroFilter")); //设置的shiro的拦截器 ShiroFilterFactoryBean
             bean.addInitParameter("targetFilterLifecycle", "true");
             bean.setEnabled(true);
             bean.addUrlPatterns("/*");
             return bean;
         }
    
         //    下面两个配置主要用来开启shiro aop注解支持. 使用代理方式;所以需要开启代码支持;
         public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
             DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
             proxyCreator.setProxyTargetClass(true);
             return proxyCreator;
         }
    
         //    开启注解
         public AuthorizationAttributeSourceAdvisor attributeSourceAdvisor(SecurityManager securityManager) {
             AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
             advisor.setSecurityManager(securityManager);
             return advisor;
         }
    
         //    CAS过滤器
         public CasFilter getCasFilter() {
             MyCasFilter casFilter = new MyCasFilter();
             casFilter.setName("casFilter");
             casFilter.setEnabled(true);
             casFilter.setFailureUrl(casLoginUrl);
             casFilter.setCasServerLoginUrl(serverPath);
             casFilter.setSuccessUrl(loginSuccessUrl);
             return casFilter;
         }
     }
    
  5. 修改客户端登录逻辑,如果用户没有登录,引导用户请求CAS服务器登录地址。引导方式包括但不限于以下方式:

    (1)Java重定向

    response.sendRedirect(response.encodeRedirectURL(targetUrl));
    

    (2)JS重定向

    window.location.replace(targetUrl);
    

    (3)a标签点击事件

  6. 配置nginx,让多个客户端处于同一个域名下,配置举例方式如下:

     server {
         listen 80;
         server_name example.com;
    
         location ^~ /project1 {
             proxy_pass http://127.0.0.1:8081;
             proxy_set_header Host $host;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         }
    
         location ^~ /project2 {
             proxy_pass http://127.0.0.1:8082;
             proxy_set_header Host $host;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         }
    
         location / {
             proxy_pass http://127.0.0.1:8080;
             proxy_set_header Host $host;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         }
     }
    
  7. 启动nginx即可。

results matching ""

    No results matching ""