【发布时间】:2020-07-20 19:49:11
【问题描述】:
我有一个小型 Spring Boot 项目,它具有用户名/密码身份验证。我在我们的 LDAP 连接中使用 spring-security 登录。我想要并且我确实设法在几个项目中做的是扩展 AbstractAuthenticationToken 类以添加我自己的字段。
在我的自定义 GenericFilterBean 类中,我想创建自己的 authentication 对象并设置到 SecurityContextHolder 中,如下所示:
KfsMsgToken kfsMsgToken = new KfsMsgToken(
kfsInMessageInfo.getObjId(),
new ArrayList<>());
SecurityContextHolder.getContext().setAuthentication(kfsMsgToken);
而且,这是我自定义的 Authentication 类:
public class KfsMsgToken extends AbstractAuthenticationToken {
String kfsInMsgOid;
public KfsMsgToken(String kfsInMsgOid, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.kfsInMsgOid = kfsInMsgOid;
}
/**
*
* @return
*/
@Override
public Object getCredentials() {
return null;
}
/**
*
* @return
*/
@Override
public Object getPrincipal() {
return null;
}
public String getKfsInMsgOid() {
return kfsInMsgOid;
}
public void setKfsInMsgOid(String kfsInMsgOid) {
this.kfsInMsgOid = kfsInMsgOid;
}
}
问题是,登录成功后,我看到 UsernamePasswordAuthenticationToken 已经设置好了。我使用自定义令牌对象重置身份验证字段,在服务层返回 null。不知道是什么原因。
感谢所有建议!
我的安全配置:
@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${ldap.urls}")
private String ldapUrl;
@Value("${ldap.domain}")
private String ldapDomain;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/fonts/**", "/img/**", "/js/**", "/pdf/**").permitAll()
.and().formLogin().defaultSuccessUrl("/index", true).loginProcessingUrl("/login").permitAll().and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.csrf().disable();
}
@Bean
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider = new
ActiveDirectoryLdapAuthenticationProvider(ldapDomain, ldapUrl);
return activeDirectoryLdapAuthenticationProvider;
}
}
我如何注册我的过滤器:
@Bean
public FilterRegistrationBean jwtFilter() {
final FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new KfsInMsgFilter(kfsInMessageService, kfsMsgToken, messageChannelService));
registrationBean.setOrder(0);
registrationBean.addUrlPatterns(SECURE);
registrationBean.setDispatcherTypes(DispatcherType.REQUEST);
return registrationBean;
}
这就是我在过滤器中所做的:
public class KfsInMsgFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
...
// at this point, Authentication holds UserNamePasswordAuthenticationToken
KfsMsgToken kfsMsgToken = new KfsMsgToken(
kfsInMessageInfo.getObjId(),
new ArrayList<>());
SecurityContextHolder.getContext().setAuthentication(kfsMsgToken);
...
}
}
【问题讨论】:
-
你的自定义
GenericFilterBean是在UsernamePasswordAuthenticationProcessingFilter之前还是之后? -
由于我没有实现 UsernamePasswordAuthenticationProcessingFilter 并且在更改之前我在 SecurityContextHolder 中看到了 UsernamePasswordAuthenticationToken ,所以似乎之前。
-
请发布您的 spring 安全配置。
-
我已经按照您的要求添加了配置文件。
-
您的自定义 GenericFilterBean 不可见?您是如何将其连接到安全过滤器链的?
标签: spring-boot spring-security