Shiro系列教程拦截器Filter源码分析_当前用户


AnonymousFilter

//允许匿名访问
public class AnonymousFilter extends PathMatchingFilter {

@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) {
// 返回true 允许匿名用户访问
return true;
}

}



UserFilter

//登录用户与记住我的用户均可通过
public class UserFilter extends AccessControlFilter {


protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
//如果访问登录
if (isLoginRequest(request, response)) {
return true;
} else {
Subject subject = getSubject(request, response);
//如果没有登录账户或记住我的用户则拒绝继续执行
return subject.getPrincipal() != null;
}
}

//如果isAccessAllowed返回false 则执行这个方法
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
//保存请求路径调转到登录页面
saveRequestAndRedirectToLogin(request, response);
return false;
}
}


AuthenticationFilter

//必须登录才能通过此filter
public abstract class AuthenticationFilter extends AccessControlFilter {

//成功后回调URL
public static final String DEFAULT_SUCCESS_URL = "/";

private String successUrl = DEFAULT_SUCCESS_URL;

public String getSuccessUrl() {
return successUrl;
}

public void setSuccessUrl(String successUrl) {
this.successUrl = successUrl;
}

//只有登录成功后的用户才能继续访问
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
Subject subject = getSubject(request, response);
return subject.isAuthenticated();
}

//跳转到之前被拦截的URL
protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception {
WebUtils.redirectToSavedRequest(request, response, getSuccessUrl());
}

}



FormAuthenticationFilter

public class FormAuthenticationFilter extends AuthenticatingFilter {

public static final String DEFAULT_ERROR_KEY_ATTRIBUTE_NAME = "shiroLoginFailure";

//表单属性
public static final String DEFAULT_USERNAME_PARAM = "username";
public static final String DEFAULT_PASSWORD_PARAM = "password";
public static final String DEFAULT_REMEMBER_ME_PARAM = "rememberMe";

private static final Logger log = LoggerFactory.getLogger(FormAuthenticationFilter.class);

private String usernameParam = DEFAULT_USERNAME_PARAM;
private String passwordParam = DEFAULT_PASSWORD_PARAM;
private String rememberMeParam = DEFAULT_REMEMBER_ME_PARAM;

private String failureKeyAttribute = DEFAULT_ERROR_KEY_ATTRIBUTE_NAME;

public FormAuthenticationFilter() {
setLoginUrl(DEFAULT_LOGIN_URL);
}

@Override
public void setLoginUrl(String loginUrl) {
String previous = getLoginUrl();
if (previous != null) {
this.appliedPaths.remove(previous);
}
super.setLoginUrl(loginUrl);
if (log.isTraceEnabled()) {
log.trace("Adding login url to applied paths.");
}
this.appliedPaths.put(getLoginUrl(), null);
}


//如果父类isAccessAllowed返回false 则执行下面逻辑
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
//判断当前请求是否访问登页面
if (isLoginRequest(request, response)) {
//如果是post提交
if (isLoginSubmission(request, response)) {
if (log.isTraceEnabled()) {
log.trace("Login submission detected. Attempting to execute login.");
}
//调用自动登录逻辑
return executeLogin(request, response);
} else {
if (log.isTraceEnabled()) {
log.trace("Login page view.");
}
//allow them to see the login page ;)
//返回true放用户可以看见登录页面
return true;
}
} else {
if (log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the " +
"Authentication url [" + getLoginUrl() + "]");
}
//保存请求页面 调转到登录页
saveRequestAndRedirectToLogin(request, response);
return false;
}
}

//判断当前请求是否post提交数据
@SuppressWarnings({"UnusedDeclaration"})
protected boolean isLoginSubmission(ServletRequest request, ServletResponse response) {
return (request instanceof HttpServletRequest) && WebUtils.toHttp(request).getMethod().equalsIgnoreCase(POST_METHOD);
}

//创建token 拿到用户名密码等参数
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
String username = getUsername(request);
String password = getPassword(request);
return createToken(username, password, request, response);
}

//用户是否选择了记住我
protected boolean isRememberMe(ServletRequest request) {
return WebUtils.isTrue(request, getRememberMeParam());
}

//登录成功则跳转到上次拦截的页面
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
ServletRequest request, ServletResponse response) throws Exception {
issueSuccessRedirect(request, response);
return false;
}

protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e,
ServletRequest request, ServletResponse response) {
if (log.isDebugEnabled()) {
log.debug( "Authentication exception", e );
}
setFailureAttribute(request, e);
//login failed, let request continue back to the login page:
return true;
}

protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {
String className = ae.getClass().getName();
request.setAttribute(getFailureKeyAttribute(), className);
}

protected String getUsername(ServletRequest request) {
return WebUtils.getCleanParam(request, getUsernameParam());
}

protected String getPassword(ServletRequest request) {
return WebUtils.getCleanParam(request, getPasswordParam());
}


}



RolesAuthorizationFilter

public class RolesAuthorizationFilter extends AuthorizationFilter {


@SuppressWarnings({"unchecked"})
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {

Subject subject = getSubject(request, response);
String[] rolesArray = (String[]) mappedValue;
//判断是否设置需要角色
if (rolesArray == null || rolesArray.length == 0) {
//no roles specified, so nothing to check - allow access.
return true;
}

Set<String> roles = CollectionUtils.asSet(rolesArray);
//判断当前用户是否需要角色
return subject.hasAllRoles(roles);
}

}



PermissionsAuthorizationFilter

public class PermissionsAuthorizationFilter extends AuthorizationFilter {


public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {

Subject subject = getSubject(request, response);
String[] perms = (String[]) mappedValue;
//判断当前用户是否拥有权限
boolean isPermitted = true;
if (perms != null && perms.length > 0) {
if (perms.length == 1) {
if (!subject.isPermitted(perms[0])) {
isPermitted = false;
}
} else {
if (!subject.isPermittedAll(perms)) {
isPermitted = false;
}
}
}

return isPermitted;
}
}



PortFilter

public class PortFilter extends AuthorizationFilter {

public static final int DEFAULT_HTTP_PORT = 80;
public static final String HTTP_SCHEME = "http";

private int port = DEFAULT_HTTP_PORT;

public int getPort() {
return port;
}

public void setPort(int port) {
this.port = port;
}

protected int toPort(Object mappedValue) {
String[] ports = (String[]) mappedValue;
if (ports == null || ports.length == 0) {
return getPort();
}
if (ports.length > 1) {
throw new ConfigurationException("PortFilter can only be configured with a single port. You have " +
"configured " + ports.length + ": " + StringUtils.toString(ports));
}
return Integer.parseInt(ports[0]);
}

//根据客户端请求端口判断是否拦截
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
int requiredPort = toPort(mappedValue);
int requestPort = request.getServerPort();
return requiredPort == requestPort;
}

protected String getScheme(String requestScheme, int port) {
if (port == DEFAULT_HTTP_PORT) {
return HTTP_SCHEME;
} else if (port == SslFilter.DEFAULT_HTTPS_PORT) {
return SslFilter.HTTPS_SCHEME;
} else {
return requestScheme;
}
}


//跳转到指定端口
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {

//just redirect to the specified port:
int port = toPort(mappedValue);

String scheme = getScheme(request.getScheme(), port);

StringBuilder sb = new StringBuilder();
sb.append(scheme).append("://");
sb.append(request.getServerName());
if (port != DEFAULT_HTTP_PORT && port != SslFilter.DEFAULT_HTTPS_PORT) {
sb.append(":");
sb.append(port);
}
if (request instanceof HttpServletRequest) {
sb.append(WebUtils.toHttp(request).getRequestURI());
String query = WebUtils.toHttp(request).getQueryString();
if (query != null) {
sb.append("?").append(query);
}
}

WebUtils.issueRedirect(request, response, sb.toString());

return false;
}
}



SslFilter

public class SslFilter extends PortFilter {

public static final int DEFAULT_HTTPS_PORT = 443;
public static final String HTTPS_SCHEME = "https";

public SslFilter() {
setPort(DEFAULT_HTTPS_PORT);
}

@Override
protected String getScheme(String requestScheme, int port) {
if (port == DEFAULT_HTTP_PORT) {
return PortFilter.HTTP_SCHEME;
} else {
return HTTPS_SCHEME;
}
}


@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
//调用父类方法判断请求端口 并且是SSL连接
return super.isAccessAllowed(request, response, mappedValue) && request.isSecure();
}
}