doFilter()重写的方法httpRequest.getUserPrincipal()始终返回NullPoint异常

时间:2018-11-14 05:34:52

标签: spring-boot spring-security saml-2.0 keycloak

我创建了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异常。

,当我尝试获取经过身份验证的用户时,它将返回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>

1 个答案:

答案 0 :(得分:0)

我不确定您使用的过滤器实现是否可以处理下面的弹簧安全性所需的逻辑,但是很明显,SecurityContextHolder没有填充,因为没有配置适配器。

Keycloak提供了Spring Security Adapter,请尝试使用它。它还将填充httpRequest.getUserPrincipal()