【问题标题】:How to configure Spring 4.0 with spring boot and spring security openId如何使用 spring boot 和 spring security openId 配置 Spring 4.0
【发布时间】:2014-02-09 10:46:39
【问题描述】:

我正在尝试使用 Spring Security OpenId 启动并运行 Spring 4.0 启动应用程序。我正在使用标准方式来引导 Spring Boot 应用程序:

@Configuration
@ComponentScan("x.y.z")
@EnableAutoConfiguration
@Import({SecurityConfig.class})
public class ServiceRegistryStart extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(ServiceRegistryStart.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        application.sources(getClass());
        return application;
    }
}

SecurityConfig.class 长这样(受Spring security中的“openid-jc sample project”影响):

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/resources/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .openidLogin()
                .loginPage("/login.html")
                .permitAll()
                .authenticationUserDetailsService(new CustomUserDetailsService())
                .attributeExchange("https://www.google.com/.*")
                    .attribute("email")
                        .type("http://axschema.org/contact/email")
                        .required(true)
                        .and()
                    .attribute("firstname")
                        .type("http://axschema.org/namePerson/first")
                        .required(true)
                        .and()
                    .attribute("lastname")
                        .type("http://axschema.org/namePerson/last")
                        .required(true)
                        .and()
                    .and()
                .attributeExchange(".*yahoo.com.*")
                    .attribute("email")
                        .type("http://axschema.org/contact/email")
                        .required(true)
                        .and()
                    .attribute("fullname")
                        .type("http://axschema.org/namePerson")
                        .required(true)
                        .and()
                    .and()
                .attributeExchange(".*myopenid.com.*")
                    .attribute("email")
                        .type("http://schema.openid.net/contact/email")
                        .required(true)
                        .and()
                    .attribute("fullname")
                        .type("http://schema.openid.net/namePerson")
                        .required(true);
    }

    @Bean(name = "myAuthenticationManager")
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    class CustomUserDetailsService implements AuthenticationUserDetailsService<OpenIDAuthenticationToken> {

        @Override
        public UserDetails loadUserDetails(OpenIDAuthenticationToken token) throws UsernameNotFoundException {
            return new User(token.getName(), "", AuthorityUtils.createAuthorityList("ROLE_USER"));
        }
    }
}

登录页面如下所示:

<form id="googleLoginForm" action="/j_spring_openid_security_check" method="post">
    <h1>Login</h1>

    <input name="openid_identifier" type="hidden" value="https://www.google.com/accounts/o8/id"/>
    <input name="openid.ns.pape" type="hidden" value="http://specs.openid.net/extensions/pape/1.0"/>
    <input name="openid.pape.max_auth_age" type="hidden" value="0"/>

    <p>
        <input name="submit" value="Login using Google" type="submit"/>
    </p>
</form>

问题是“/j_spring_openid_security_check”似乎不存在。我认为问题是我应该在使用 Spring Security 时从 AbstractSecurityWebApplicationInitializer 扩展,但在启动时我应该使用 SpringBootServletInitializer。将两者结合起来的最佳方法是什么? SpringBootServletInitializer 的 javadoc 说它会在检测到 Spring Security 时自动注册一个过滤器,但在这种情况下它似乎不起作用。

【问题讨论】:

  • 你在 pom.xml 文件中做了什么来获得 OpenID 支持?我正在做与您类似的事情,并且包含了“spring-boot-starter-security”依赖项,但这并没有引入与 OpenID 相关的类。我想我可以自己添加“spring-security-openid”依赖项,但我不确定要指定哪个版本以及如何使其与 Spring Boot 版本(不断变化)保持同步。我很惊讶 Spring Boot Security 还没有导入这个。
  • spring boot的重点是不必指定版本。只需给spring-security-openid添加依赖即可,版本已经在父pom中指定了。

标签: spring spring-security openid spring-boot


【解决方案1】:

我实际上设法解决了这个问题。首先,我使用 Spring Boot 来启动一个嵌入式容器,所以我不需要任何 WebApplicationInitializers。其次,登录页面中的帖子 URL 应指向“/login/openid”,第三,我必须在安全配置中禁用跨站点请求伪造预防:

http.csrf().disable(). ..

在SecurityConfig类的configure方法中。

【讨论】:

  • 谢谢,不过我得等两天才能做到这一点。
  • 只是我的 2 美分:这个答案的亮点是使用“/login/openid”而不是网络上随处可见的 j_spring_openid_security_check