配置说明:
服务端:4.0
tomcat:8
JDK:1.8
协议:由于领导要求,所以关闭了https协议,也没有使用证书(不知道有木有影响)
客户端:spring boot + shiro(所以要与cas整合)
JDK:1.7
由于一直报错,验证不通过,所以我下载了源码,进入到源码中,还是不理解问题,所以问问大家。希望可以给个思路,谢谢。
首先,在访问客户端时,重定向到了服务端的登录界面
输入完用户名和密码后,客户端被casFilter拦截,进入到CasFilter中的onAccessDenied(ServletRequest request, ServletResponse response){return executeLogin(request, response);}
进入到executeLogin(request, response)的实现方法中,进入到AuthenticatingFilter实现的executeLogin方法中,相应代码如下:
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
AuthenticationToken token = createToken(request, response);
if (token == null) {
String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +
"must be created in order to execute a login attempt.";
throw new IllegalStateException(msg);
}
try {
Subject subject = getSubject(request, response);
subject.login(token);
return onLoginSuccess(token, subject, request, response);
} catch (AuthenticationException e) {
return onLoginFailure(token, e, request, response);
}
}
往下走,首先创建一个CasToken,只有一个参数trick(ST-1-1ZAXXNbLLKfsbB1h5Glz-cas01.example.org),代码如下:
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String ticket = httpRequest.getParameter(TICKET_PARAMETER);
return new CasToken(ticket);
}
下一步,根据token开始执行subject.login(token); 走到这一步,我不知道我的客户端配置有没有问题,继续往下看,在DelegatingSubject中实现的login方法:
public void login(AuthenticationToken token) throws AuthenticationException {
clearRunAsIdentities();
Subject subject = securityManager.**login(this, token)**;
PrincipalCollection principals;
String host = null;
继续securityManager.login(this, token);进入到类DefaultSecurityManager实现方法中:
public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {
AuthenticationInfo info;
try {
info = **authenticate(token)**;
} catch (AuthenticationException ae) {
try {
onFailedLogin(token, ae, subject);
} catch (Exception e) {
if (log.isInfoEnabled()) {
log.info("onFailedLogin method threw an " +
"exception. Logging and propagating original AuthenticationException.", e);
}
}
throw ae; //propagate
}
继续看:info = authenticate(token); 进入到类AuthenticatingSecurityManager实现的方法中:
public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
return this.authenticator.**authenticate(token)**;
}
继续进入实现方法中,在类AbstractAuthenticator中实现的代码如下:
public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
if (token == null) {
throw new IllegalArgumentException("Method argumet (authentication token) cannot be null.");
}
log.trace("Authentication attempt received for token [{}]", token);
AuthenticationInfo info;
try {
info = **doAuthenticate(token)**;
if (info == null) {
String msg = "No account information found for authentication token [" + token + "] by this " +
"Authenticator instance. Please check that it is configured correctly.";
throw new AuthenticationException(msg);
}
} catch (Throwable t) {
继续进入到doAuthenticate(token)的实现类ModularRealmAuthenticator中,代码如下,大家注意看我加粗的地方, realm.supports(token) :
protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) {
if (!**realm.supports(token)**) {
String msg = "Realm [" + realm + "] does not support authentication token [" +
token + "]. Please ensure that the appropriate Realm implementation is " +
"configured correctly or that the realm accepts AuthenticationTokens of this type.";
throw new UnsupportedTokenException(msg);
}
AuthenticationInfo info = realm.getAuthenticationInfo(token);
if (info == null) {
String msg = "Realm [" + realm + "] was unable to find account data for the " +
"submitted AuthenticationToken [" + token + "].";
throw new UnknownAccountException(msg);
}
return info;
}
继续进入到 realm.supports(token) ;实现类AuthenticatingRealm,方法如下:
public boolean supports(AuthenticationToken token) {
return token != null && getAuthenticationTokenClass().isAssignableFrom(token.getClass());
}
问题就出在这里,在上面的supports方法中两个class对比一直不匹配, 由于CasRealmh中:
public CasRealm() {
setAuthenticationTokenClass(CasToken.class);
}
而我们之前在刚进入CasFilter中时根据trick新生成的Token也是CasToken。一下图片是我调试时截取的:
根据调试结果显示两个class是一模一样的,可是偏偏返回false,
最后在类ModularRealmAuthenticator的方法中报错:
protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) {
if (!realm.supports(token)) {
**String msg = "Realm [" + realm + "] does not support authentication token [" +
token + "]. Please ensure that the appropriate Realm implementation is " +
"configured correctly or that the realm accepts AuthenticationTokens of this type.";
throw new UnsupportedTokenException(msg);**
}
AuthenticationInfo info = realm.getAuthenticationInfo(token);
if (info == null) {
String msg = "Realm [" + realm + "] was unable to find account data for the " +
"submitted AuthenticationToken [" + token + "].";
throw new UnknownAccountException(msg);
}
return info;
}
报错内容:
String msg = "Realm [" + realm + "] does not support authentication token [" +
token + "]. Please ensure that the appropriate Realm implementation is " +
"configured correctly or that the realm accepts AuthenticationTokens of this type.";
这里困了我好久了, 实在是不知道怎么解决了, 希望大家可以帮我看看。