SpringSecurity+jwt自定义认证每次都需要认证的问题

1、先说出现的问题:

  项目需要app自定义登录认证,按照SpringSecurity默认的用户名和密码认证方式自定义了token,provider,UserService,UserDetails;登录成功返回token后,app拿着token去访问后台资源时,一直提示403未认证,调试代码发现,每次访问都要走provider的authcatication方法去数据库认证;按理说jwtfilter校验token通过后就不需要再次去数据库查用户了,但是现在是每次都要去查一次,这个时候jwt设置的token中是没有密码的,当provider去验证的时候发现没有密码就报403认证失败(认证过后,再次拿token去访问资源是不应该去数据库认证的);

2、解决问题:

  通过断点发现,SpringSecurity的认证拦截器中有个方法调用的是Authentication接口的isAuthentication方法,这个方法如果返回的是true,就不去provider中认证了,而这个方法就是在AbstractAuthenticationToken 中定义,这个时候我们看一下自定义的Authentication

public class AppAuthenticationToken extends AbstractAuthenticationToken {
private final Object principal;
private Object credentials;
public AppAuthenticationToken( Object principal, Object credentials,Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true); // must use super, as we override
}

public AppAuthenticationToken(Object principal, Object credentials) {
super(null);
this.principal = principal;
this.credentials = credentials;
setAuthenticated(false);
}


public Object getCredentials() {
return this.credentials;
}

public Object getPrincipal() {
return this.principal;
}
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException(
"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
}

super.setAuthenticated(false);
}

@Override
public void eraseCredentials() {
super.eraseCredentials();
credentials = null;
}
}

  看到上面的构造方法中都有setAuthenticated这个方法,这个方法就是给Authentication接口的isAuthentication方法提供参数的;我们只要在jwtfilter中验证通过了token,就要调用AppAuthenticationToken( Object principal, Object credentials,Collection<? extends GrantedAuthority> authorities)这个构造,告诉SpringScurity认证拦截器,我已经在jwtfilter中校验过了,你不需要检验。这样就ok了。


posted @ 2021-05-20 11:16  550  阅读(1456)  评论(0编辑  收藏  举报