如何将 angularjs 路由与 CAS 身份验证重定向一起使用,或者 angular 只是不可用?
How to use angularjs routing with CAS authentication redirect, or is angular just not usable?
我的应用通常使用以下路由:
http://angularapp.com/#/page=bannanas
但是,如果用户未通过身份验证,则用户将被重定向到 CAS 登录页面,然后在登录后被重定向回:
请注意,重定向后,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/
。
用户请求页面http://angularapp.com/#/page=bannanas
需要重定向到CAS服务器进行登录。您应该对 URL 进行编码并将其作为请求参数传递,例如 http://your-cas-site/login?returnUrl=http%3A%2F%2Fangularapp.com%2F%23%2Fpage%3Dbannanas
CAS 处理身份验证并重定向回您的应用程序。
在您的应用中,编写一个 $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 {
}
}
我的应用通常使用以下路由:
http://angularapp.com/#/page=bannanas
但是,如果用户未通过身份验证,则用户将被重定向到 CAS 登录页面,然后在登录后被重定向回:
请注意,重定向后,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/
。
用户请求页面
http://angularapp.com/#/page=bannanas
需要重定向到CAS服务器进行登录。您应该对 URL 进行编码并将其作为请求参数传递,例如http://your-cas-site/login?returnUrl=http%3A%2F%2Fangularapp.com%2F%23%2Fpage%3Dbannanas
CAS 处理身份验证并重定向回您的应用程序。
在您的应用中,编写一个
$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 {
}
}