如何将 angularjs 路由与 CAS 身份验证重定向一起使用,或者 angular 只是不可用?

How to use angularjs routing with CAS authentication redirect, or is angular just not usable?

我的应用通常使用以下路由:

http://angularapp.com/#/page=bannanas

但是,如果用户未通过身份验证,则用户将被重定向到 CAS 登录页面,然后在登录后被重定向回:

http://angularapp.com/

请注意,重定向后,CAS 会完全删除 anchor/route“#/”,因为不支持锚标记。 https://issues.jasig.org/browse/CAS-1338

最好的解决方法是什么?有没有办法让我做这样的事情:

http://angularapp.com/?page=bannanas

触发相同的路由: http://angularapp.com/#/page=bannanas

因为 CAS 会在重定向时保留查询参数(只是不保留锚点)?或者有更好的方法来处理这个问题吗?

在重定向到您的 CAS 服务之前,您需要对目标 url 进行编码 URL。当呼叫从服务返回时,您将解码它并在您的应用程序中重定向。

如果您使用 Java 或 .NET 或类似的东西,您可以使用过滤器/servlet 在 angular 应用程序之外处理所有这些。

但这是基本的想法。根据您的示例,您的 angular 应用位于 http://angularapp.com/

  1. 用户请求页面http://angularapp.com/#/page=bannanas需要重定向到CAS服务器进行登录。您应该对 URL 进行编码并将其作为请求参数传递,例如 http://your-cas-site/login?returnUrl=http%3A%2F%2Fangularapp.com%2F%23%2Fpage%3Dbannanas

  2. CAS 处理身份验证并重定向回您的应用程序。

  3. 在您的应用中,编写一个 $http interceptor 来监视 returnUrl 的请求参数。当你找到它时,解码 returnUrl=http%3A%2F%2Fangularapp.com%2F%23%2Fpage%3Dbannanas 并重定向到它:http://angularapp.com/#/page=bannanas

如果您的应用程序服务器支持,这也可以由过滤器在外部处理。 (我在 Java 中为我的应用程序完成了此操作,但 .NET 和大多数其他服务器支持相同的东西)。

--

按要求添加此示例代码。这是我的身份验证过滤器,它处理重定向到登录页面。

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginRedirect implements Filter {

  @Override
  public void destroy() {

  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {

    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;

    // See if user has an active session.
    User currentUser = UserService.getCurrentUser(httpServletRequest.getSession());
    if (currentUser == null) {
      // No active session, need to error or redirect.
      if (httpServletRequest.getRequestURI().indexOf(httpServletRequest.getContextPath() + "/api/") == 0) {
        // For API requests, return an UNATHORIZED http response.
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
      } else {
        // For all other requests, forward the user to the login page.
        StringBuilder returnTo = new StringBuilder();
        returnTo.append(httpServletRequest.getRequestURI());
        if (httpServletRequest.getQueryString() != null) {
          returnTo.append("?");
          returnTo.append(httpServletRequest.getQueryString());
        }
        httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/login?returnTo=" +
            URLEncoder.encode(returnTo.toString(), "UTF-8"));
      }
    } else if (currentUser.isDeleted() || currentUser.isLocked()
        || (!currentUser.isRoleAdmin() && !currentUser.isRoleStaff())) {
      httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
    } else {
      chain.doFilter(httpServletRequest, httpServletResponse);
    }
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

}