doFilter() 重写方法 httpRequest.getUserPrincipal() 总是返回 NullPoint 异常
Posted
技术标签:
【中文标题】doFilter() 重写方法 httpRequest.getUserPrincipal() 总是返回 NullPoint 异常【英文标题】:doFilter() overridden method httpRequest.getUserPrincipal() always return NullPoint Exception 【发布时间】:2019-04-17 00:57:10 【问题描述】:我创建了 Spring Boot 应用程序。我使用了以下依赖项。 Spring Boot 版本为 2.1.0.RELEASE
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-servlet-filter-adapter</artifactId>
<version>4.5.0.Final</version>
</dependency>
安全配置类如下所示。
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http.authorizeRequests().antMatchers("/actuator").authenticated();
http.headers().cacheControl().disable();
http.csrf().disable();
http.logout().logoutSuccessUrl("/assets/logout.html");
过滤器类如下所示:
@WebFilter(urlPatterns = "/*", initParams =
@WebInitParam(
name = "keycloak.config.file",
value = "./config/saml.xml"
))
public class SingleSignOnFilter extends SamlFilter
private static final String loginGc = "/gc/";
private static final String logoutUrl = "/gc/assets/logout.html";
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)throws IOException, ServletException
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String requestPath = httpRequest.getRequestURI();
boolean needAuthentication = !requestPath.equals(logoutUrl);
boolean alreadyLoginGc = !requestPath.equals(loginGc);
if (needAuthentication)
if (alreadyLoginGc)
super.doFilter(request, response, chain);
else
httpResponse.setHeader("Cache-Control", "no-cache, no
store");
super.doFilter(request, response, chain);
else
chain.doFilter(request, response);
当我调用 httpRequest.getUserPrincipal();
这个方法时,它会返回 Nullpoint Exception。
当我尝试获取经过身份验证的用户时,它将返回 annonymousUser
。
Authentication auth = SecurityContextHolder.getContext()
.getAuthentication();
auth.getName();
Saml.xml 如下所示:
<keycloak-saml-adapter>
<SP entityID="https://localhost/gc" sslPolicy="NONE">
<PrincipalNameMapping policy="FROM_NAME_ID"/>
<IDP entityID="************************">
<SingleSignOnService requestBinding="POST"
validateResponseSignature="true"
bindingUrl="********************************"/>
<SingleLogoutService requestBinding="REDIRECT"
responseBinding="REDIRECT"
redirectBindingUrl="***************************"/>
<Keys>
<Key signing="true">
<CertificatePem>
-----BEGIN CERTIFICATE-----
##########################
###### Dummy Data ########
##########################
-----END CERTIFICATE-----
</CertificatePem>
</Key>
</Keys>
</IDP>
</SP>
</keycloak-saml-adapter>
【问题讨论】:
@durSamlFilter
来自 keycloak-saml-servlet-filter-adapter
库。
那你就得切换了。先认证再访问。
【参考方案1】:
我不确定您使用的过滤器实现是否处理了下面的 spring 安全性所需的逻辑,但很明显 SecurityContextHolder
没有被填充,因为没有配置适配器来这样做。
Keycloak 提供了一个Spring Security Adapter,尝试使用它。它也将填充httpRequest.getUserPrincipal()
。
【讨论】:
以上是关于doFilter() 重写方法 httpRequest.getUserPrincipal() 总是返回 NullPoint 异常的主要内容,如果未能解决你的问题,请参考以下文章