从 loadUserByUsername 访问证书内容
Access certificate content from loadUserByUsername
我正在开发一个 spring mvc 应用程序,它需要进行以下身份验证
- 通过 tomcat 证书存储
验证客户端证书
- 验证客户端证书的附加属性
我尝试使用 loadUserByUsername() 实现 #2,但不知道如何访问 loadUserByUsername() 中的证书内容?
我发现 this 相关。发布的答案是阅读HttpServletRequest
。我可以从 loadUserByUsername()
访问 HttpServletRequest
吗?
我试过了
SecurityContextHolder.getContext().getAuthentication().getCredentials();
但身份验证对象未在 loadUserByUsername()
中设置。
更新
经过一些挖掘,我发现 Java 配置提供了一种非常简单的方法来获取 X509Certificate,只需简单地实现 AuthenticationUserDetailsService:
@Configuration
protected static class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.x509()
.authenticationUserDetailsService(new X509AuthenticatedUserDetailsService());
}
protected static class X509AuthenticatedUserDetailsService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
@Override
public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token)
throws UsernameNotFoundException {
X509Certificate certificate = (X509Certificate)token.getCredentials();
// do your extra checking here...
// add granted authorities, etc.
Collection<GrantedAuthority> authorities = Collections.EMPTY_LIST;
// generate your user how you deem fit
User user = new User(certificate.getSubjectX500Principal().getName(), null, authorities);
return user;
}
}
}
请注意,在 loadUserDetails 方法中,您所做的实际上与实现 UserDetailsService
时所做的相同,只是此方法采用整个 Authentication
对象。
原版
我不确定这是否是预期的方式;然而,X509Certificate
是通过在 X509AuthenticationFilter
中生成的身份验证令牌传递的。调用 PreAuthenticatedAuthenticationToken#getCredentials
应该会为您获取证书。
深入研究 API 表明 PreAuthenticatedAuthenticationProvider
可以配置自定义 UserDetailsChecker
和 AuthenticatedUserDetailsService
。这些可能足以让您从 X509Certificate
中提取详细信息并进行验证。
在我的例子中,我确实在 UserDetailsService 的以下实现中从 id 获取了证书 ID。 security.xml中的简单配置
public UserDetails loadUserByUsername(String id) throws UsernameNotFoundException {
Security.xml
但以防万一 public class 中未调用证书 onAuthenticationSuccess myAuthSuccessHandler implements AuthenticationSuccessHandler {
有什么建议吗?想法?
我正在开发一个 spring mvc 应用程序,它需要进行以下身份验证
- 通过 tomcat 证书存储 验证客户端证书
- 验证客户端证书的附加属性
我尝试使用 loadUserByUsername() 实现 #2,但不知道如何访问 loadUserByUsername() 中的证书内容?
我发现 this 相关。发布的答案是阅读HttpServletRequest
。我可以从 loadUserByUsername()
访问 HttpServletRequest
吗?
我试过了
SecurityContextHolder.getContext().getAuthentication().getCredentials();
但身份验证对象未在 loadUserByUsername()
中设置。
更新
经过一些挖掘,我发现 Java 配置提供了一种非常简单的方法来获取 X509Certificate,只需简单地实现 AuthenticationUserDetailsService:
@Configuration
protected static class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.x509()
.authenticationUserDetailsService(new X509AuthenticatedUserDetailsService());
}
protected static class X509AuthenticatedUserDetailsService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
@Override
public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token)
throws UsernameNotFoundException {
X509Certificate certificate = (X509Certificate)token.getCredentials();
// do your extra checking here...
// add granted authorities, etc.
Collection<GrantedAuthority> authorities = Collections.EMPTY_LIST;
// generate your user how you deem fit
User user = new User(certificate.getSubjectX500Principal().getName(), null, authorities);
return user;
}
}
}
请注意,在 loadUserDetails 方法中,您所做的实际上与实现 UserDetailsService
时所做的相同,只是此方法采用整个 Authentication
对象。
原版
我不确定这是否是预期的方式;然而,X509Certificate
是通过在 X509AuthenticationFilter
中生成的身份验证令牌传递的。调用 PreAuthenticatedAuthenticationToken#getCredentials
应该会为您获取证书。
深入研究 API 表明 PreAuthenticatedAuthenticationProvider
可以配置自定义 UserDetailsChecker
和 AuthenticatedUserDetailsService
。这些可能足以让您从 X509Certificate
中提取详细信息并进行验证。
在我的例子中,我确实在 UserDetailsService 的以下实现中从 id 获取了证书 ID。 security.xml中的简单配置 public UserDetails loadUserByUsername(String id) throws UsernameNotFoundException { Security.xml
但以防万一 public class 中未调用证书 onAuthenticationSuccess myAuthSuccessHandler implements AuthenticationSuccessHandler {
有什么建议吗?想法?