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

为君一笑 提交于 2020-02-19 04:39:42

问题


My app usually uses the following for routing:

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

However, if the user is not authenticated, the user is redirected to a CAS login page, then after login, is redirected back to:

http://angularapp.com/

Notice after redirect, CAS completely strips out the anchor/route "#/" since the anchor tag is not supported. https://issues.jasig.org/browse/CAS-1338

What is the best way around this? Is there a way I can do something like this:

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

That triggers the same routing of: http://angularapp.com/#/page=bannanas

Since CAS will preserve query parameters (just not anchors) on redirection? Or is there a better way to handle this?


回答1:


You will need to url-encode the destination URL before redirecting to your CAS service. When the call comes back from the service you'd decode it and redirect within your application.

If you are using Java or .NET or something similar you could handle all this outside of your angular app with a filter / servlet.

But here's the basic idea. From your example your angular app is at http://angularapp.com/.

  1. User requests page http://angularapp.com/#/page=bannanas which needs to redirect to the CAS server for sign-in. You should encode that URL and pass it along as a request parameter, such as http://your-cas-site/login?returnUrl=http%3A%2F%2Fangularapp.com%2F%23%2Fpage%3Dbannanas

  2. CAS handles authentication and redirects back to your application.

  3. In your app, write an $http interceptor that watches for a request parameter of returnUrl. When you find it, decode the returnUrl=http%3A%2F%2Fangularapp.com%2F%23%2Fpage%3Dbannanas and redirect to it: http://angularapp.com/#/page=bannanas

This could also be handled externally by a filter if your application server supports that. (I've done this in Java for my app, but .NET and most other servers support the same thing).

--

Adding this example code as requested. Here's my auth filter that handles redirects to a login page.

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 {

  }

}


来源:https://stackoverflow.com/questions/28323747/how-to-use-angularjs-routing-with-cas-authentication-redirect-or-is-angular-jus

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!