Spring boot 如何使用Atlassian Crowd Integration与Spring boot+;使用javabean的Spring安全性

Spring boot 如何使用Atlassian Crowd Integration与Spring boot+;使用javabean的Spring安全性,spring-boot,spring-security,atlassian-crowd,Spring Boot,Spring Security,Atlassian Crowd,我们使用许多基于SpringSecurity构建的SpringBoot项目来提供用于多种目的的小型web应用程序。我们正在强烈考虑使用Crowd作为中央身份验证提供者,但是我在将spring引导配置为使用java风格的bean而不是提供的XML配置时遇到了很多麻烦,因为这不再是推荐的配置(请参阅以验证java风格的配置是首选方式). 我的基本安全测试应用程序的安全配置设置如下: WebSecurityConfig.java package hello; import org.springfra

我们使用许多基于SpringSecurity构建的SpringBoot项目来提供用于多种目的的小型web应用程序。我们正在强烈考虑使用Crowd作为中央身份验证提供者,但是我在将spring引导配置为使用java风格的bean而不是提供的XML配置时遇到了很多麻烦,因为这不再是推荐的配置(请参阅以验证java风格的配置是首选方式).

我的基本安全测试应用程序的安全配置设置如下:

WebSecurityConfig.java

package hello;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }
}
我真的很困惑如何修改它以适应人群内置的springsecurity集成。(特别是com.atlassian.crowd:crowd-integration-springsecurity:2.8.3)。我试图使用XML通过标准配置注释类尝试和引导功能,如下所示:

applicationContext-security.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
                        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

<!--
    <debug />
    <beans:alias name="springSecurityFilterChain" alias="org.springframework.security.filterChainProxy"/>   
-->

    <!-- Added for Integrating Crowd with Spring Security -->

    <!-- 3.1 Configuring Centralised User Management -->

    <!-- 3.1.1 -->
    <beans:bean id="crowdUserDetailsService" class="com.atlassian.crowd.integration.springsecurity.user.CrowdUserDetailsServiceImpl">
        <beans:property name="groupMembershipManager" ref="crowdGroupMembershipManager"/>
        <beans:property name="userManager" ref="crowdUserManager"/>
        <beans:property name="authorityPrefix" value="ROLE_"/>

<!--
        <beans:property name="groupToAuthorityMappings">
            <beans:bean factory-bean="groupToAuthorityMappings" factory-method="entrySet" />
        </beans:property>
-->
    </beans:bean>

<!--
    <util:map id="groupToAuthorityMappings">
        <beans:entry key="crowd-administrators" value="ROLE_crowd-administrators" />
        <beans:entry key="some-other-group" value="specific-authority-for-other-group" />
    </util:map>
-->

    <!-- 3.1.2 -->
    <beans:bean id="crowdAuthenticationProvider" class="com.atlassian.crowd.integration.springsecurity.RemoteCrowdAuthenticationProvider">
        <beans:constructor-arg ref="crowdAuthenticationManager"/>
        <beans:constructor-arg ref="httpAuthenticator"/>
        <beans:constructor-arg ref="crowdUserDetailsService"/>
    </beans:bean>

    <!-- 3.2 -->

    <http pattern="/console/static/session-context"
          entry-point-ref="crowdAuthenticationProcessingFilterEntryPoint">
    </http>

    <http pattern='/console/static/**' security='none'/>

    <http auto-config="false"
          entry-point-ref="crowdAuthenticationProcessingFilterEntryPoint"
          access-denied-page="/denied.html">
        <custom-filter position="FORM_LOGIN_FILTER" ref='authenticationProcessingFilter'/>
        <custom-filter position="LOGOUT_FILTER" ref='logoutFilter'/>

        <intercept-url pattern="/console/secure/**" access="ROLE_crowd-administrators"/>
        <intercept-url pattern="/console/user/**" access="IS_AUTHENTICATED_FULLY"/>

        <intercept-url pattern="/console/resource-with-own-check/**" access='IS_AUTHENTICATED_ANONYMOUSLY'/>
    </http>


    <authentication-manager alias='authenticationManager'>
        <authentication-provider ref='crowdAuthenticationProvider'/>
    </authentication-manager>

    <beans:bean id="crowdAuthenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
        <beans:property name="loginFormUrl" value="/login.html"/>
    </beans:bean>

    <beans:bean id="authenticationProcessingFilter" class="com.atlassian.crowd.integration.springsecurity.CrowdSSOAuthenticationProcessingFilter">
        <beans:property name="httpAuthenticator" ref="httpAuthenticator"/>
        <beans:property name="authenticationManager" ref="authenticationManager"/>
        <beans:property name="filterProcessesUrl" value="/j_security_check"/>
        <beans:property name="authenticationFailureHandler">
            <beans:bean class="com.atlassian.crowd.integration.springsecurity.UsernameStoringAuthenticationFailureHandler">
                <beans:property name="defaultFailureUrl" value="/console/login.action?error=true"/>
            </beans:bean>
        </beans:property>

        <beans:property name="authenticationSuccessHandler">
            <beans:bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
                <beans:property name="defaultTargetUrl" value="/console/defaultstartpage.action"/>
            </beans:bean>
        </beans:property>
    </beans:bean>

     <beans:bean id="crowdLogoutHandler" class="com.atlassian.crowd.integration.springsecurity.CrowdLogoutHandler">
        <beans:property name="httpAuthenticator" ref="httpAuthenticator"/>
    </beans:bean>

     <beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <beans:constructor-arg value="/login.html"/>
        <beans:constructor-arg>
            <beans:list>
                <beans:ref bean="crowdLogoutHandler"/>
                <beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
            </beans:list>
        </beans:constructor-arg>
        <beans:property name="filterProcessesUrl" value="/console/logoff.action"/>
    </beans:bean>

以上是我在任何地方都能找到的XML安全文件的最新综合示例,它与SpringSecurity4.0不兼容(如果您增加版本,就会到处出现XML冲突)。我不知道httpAuthenticator在哪里/如何解决,因为我没有看到任何具有该ID的bean,这使得它非常麻烦

任何帮助都将不胜感激,我已经为此努力了好几天,几乎没有结果

额外信息:


运行spring boot版本1.3.1-Release,spring security版本4.0,所以,我想我实际上已经弄明白了这一点,它至少为我提供了一个进一步定制spring boot集成的起点。主要的魔法是WebSecurityConfig类,它现在看起来如下所示:

WebSecurityConfig.java:

package hello;
import com.atlassian.crowd.integration.http.HttpAuthenticator;
import com.atlassian.crowd.integration.http.HttpAuthenticatorImpl;
import com.atlassian.crowd.integration.springsecurity.RemoteCrowdAuthenticationProvider;
import com.atlassian.crowd.integration.springsecurity.user.CrowdUserDetailsService;
import com.atlassian.crowd.integration.springsecurity.user.CrowdUserDetailsServiceImpl;
import com.atlassian.crowd.service.AuthenticationManager;
import com.atlassian.crowd.service.GroupManager;
import com.atlassian.crowd.service.UserManager;
import com.atlassian.crowd.service.cache.BasicCache;
import com.atlassian.crowd.service.cache.CacheImpl;
import com.atlassian.crowd.service.cache.CachingGroupManager;
import com.atlassian.crowd.service.cache.CachingGroupMembershipManager;
import com.atlassian.crowd.service.cache.CachingUserManager;
import com.atlassian.crowd.service.cache.SimpleAuthenticationManager;
import com.atlassian.crowd.service.soap.client.SecurityServerClient;
import com.atlassian.crowd.service.soap.client.SecurityServerClientImpl;
import com.atlassian.crowd.service.soap.client.SoapClientPropertiesImpl;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .csrf().disable()
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }
    public static Properties getProps() throws IOException{
     Properties prop = new Properties();
    try(InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("crowd.properties")){
        prop.load(in);
    }
    return prop;
    }
    @Bean
    public SecurityServerClient securityServerClient() throws IOException{
    return new SecurityServerClientImpl(SoapClientPropertiesImpl.newInstanceFromProperties(getProps()));
    }
   private final BasicCache cache = new CacheImpl(Thread.currentThread().getContextClassLoader().getResource("crowd-ehcache.xml"));

    @Bean
    public AuthenticationManager crowdAuthenticationManager() throws IOException{

        return new SimpleAuthenticationManager(securityServerClient());
    }
    @Bean
    public HttpAuthenticator httpAuthenticator() throws IOException{
    return new HttpAuthenticatorImpl(crowdAuthenticationManager());
    }
    @Bean
    public UserManager userManager() throws IOException{
    return new CachingUserManager(securityServerClient(), cache);
    }
    @Bean
    public GroupManager groupManager() throws IOException{
    return new CachingGroupManager(securityServerClient(), cache);
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(crowdAuthenticationProvider());
    }
    @Bean
    public CrowdUserDetailsService crowdUserDetailsService() throws IOException{
    CrowdUserDetailsServiceImpl cusd = new CrowdUserDetailsServiceImpl();
    cusd.setUserManager(userManager());
    cusd.setGroupMembershipManager(new CachingGroupMembershipManager(securityServerClient(), userManager(),groupManager(),cache));
    cusd.setAuthorityPrefix("ROLE_");
    return cusd;
    }
    @Bean
    RemoteCrowdAuthenticationProvider crowdAuthenticationProvider() throws IOException{
    return new RemoteCrowdAuthenticationProvider(crowdAuthenticationManager(), httpAuthenticator(), crowdUserDetailsService());
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("ROLE_USER");
    }
}
最困难的部分是弄清楚如何设置bean,这根本没有文档记录,因为在此之前,它都是XML魔法。现在,假设您有适当的crowd.properties文件和适当的EhCache文件设置(也可以用JavaBean删除,但这不太过分),您可以以纯java的方式使用群组集成

使此工作正常的build.gradle如下所示:

build.gradle:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.1.RELEASE")
    }
}
if (!hasProperty('mainClass')) {
    ext.mainClass = 'hello.Application'
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
jar {
    baseName = 'gs-securing-web'
    version =  '0.1.0'
}
repositories {
    maven {
    url = 'https://m2proxy.atlassian.com/repository/public'
    }
    mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
    compile "commons-codec:commons-codec:1.10"
    compile "org.springframework.boot:spring-boot-starter-web"
    compile "org.springframework.boot:spring-boot-starter"
    compile "org.springframework:spring-tx"
    compile 'org.springframework.boot:spring-boot-starter-security'
    compile 'org.springframework.boot:spring-boot-starter-thymeleaf'
    compile (group: "com.atlassian.crowd", name: "crowd-integration-springsecurity", version: "2.8.+"){
    exclude (group: 'org.apache.ws.commons');
    }
    compile 'org.slf4j:slf4j-api'
    compile "org.codehaus.groovy:groovy"
    compile "org.codehaus.groovy:groovy-json:2.3.8"
}
task wrapper(type: Wrapper) {
    gradleVersion = '2.10'
}

就这样!然后正确引导身份验证以使用安全接口。现在,值得一提的是,我还没有尝试过它是如何将各种角色/等等交给我的,但这应该能让我向前迈进。此外,这还不包括SSO代码,我还没有完全弄明白。所以一旦我知道了,我会在某个地方发布一个更彻底的指南

对我有效,但我删除了全局配置方法,但我有一个疑问。这段代码是如何从浏览器中获取crowd.token_密钥的,因为在我的情况下,它就是这样工作的,我不知道如何在SpringBoot中获得这个cook。我以前集成过Crowd,但也集成了其他框架。

只是一个跟进,@WillBD在Atlassian上发布说,他不再在需要此功能的公司工作,SSO要求被取消,因此缺少更新。嘿@mnd谢谢你为我发布更新!有时这些老问题就变得模糊不清了:)我不明白这是如何回答这个问题的。