doFilter() 覆盖方法 httpRequest.getUserPrincipal() 总是 return NullPoint Exception
doFilter() overridden method httpRequest.getUserPrincipal() always return NullPoint Exception
我创建了 spring 启动应用程序。我使用了以下依赖项。
Spring开机版本为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>
安全配置 class 如下所示。
@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");
}
}
过滤器 class 如下所示:
@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();
这个方法时,它会 return 空点异常。
当我试图获得经过身份验证的用户时,它会 return 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>
我不确定您使用的过滤器实现是否处理了底层 spring 安全性所需的逻辑,但很明显 SecurityContextHolder
未填充,因为没有配置适配器来这样做.
Keycloak提供了一个Spring Security Adapter,试试看吧。它也会填充 httpRequest.getUserPrincipal()
。
我创建了 spring 启动应用程序。我使用了以下依赖项。 Spring开机版本为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>
安全配置 class 如下所示。
@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");
}
}
过滤器 class 如下所示:
@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();
这个方法时,它会 return 空点异常。
当我试图获得经过身份验证的用户时,它会 return 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>
我不确定您使用的过滤器实现是否处理了底层 spring 安全性所需的逻辑,但很明显 SecurityContextHolder
未填充,因为没有配置适配器来这样做.
Keycloak提供了一个Spring Security Adapter,试试看吧。它也会填充 httpRequest.getUserPrincipal()
。