如何在Spring Security上实现自己的OpenIDConsumer?

时间:2012-09-06 13:39:54

标签: spring spring-security openid

我想为Spring Security OpenID实现一个新的OpenIDConsumer。我在一个类中实现了OpenIDConsumer,然后将相应的配置添加到applicationContext-security.xml,但我的代码似乎根本没有执行。

这是applicationContext-security.xml

的相关部分
<http auto-config="false">
    <intercept-url pattern="/**" access="ROLE_USER"/>
    <openid-login login-page="/auth/login"
            authentication-failure-url="/auth/login?login_error=true">
        <attribute-exchange>
            <openid-attribute name="email" type="http://axschema.org/contact/email" required="true"/>
        </attribute-exchange>
    </openid-login>
</http>
<b:bean id="openIdConsumer" class="sample.OpenIDTestConsumer">
    <b:property name="email" value="email"/>
</b:bean>

现在,类sample.OpenIDTestConsumer已初始化,但Spring Security并未使用它,而是使用了原始类,我认为OpenID4JavaConsumer

sample.OpenIDTestConsumer类实现OpenIDConsumer接口并初始化并设置setEmail方法,但它不执行beginConsumption或{{1}方法,这就是为什么我认为它只是因为endConsumption bean定义而被创建但未被使用。

问题是:我如何粘贴或设置自定义类以作为OpenIDConsumer工作而不使用Spring实现?

2 个答案:

答案 0 :(得分:2)

默认情况下,使用安全命名空间配置时,Spring Security会向OpenIDAuthenticationFilter注册OpenID4JavaConsumer。您无法使用命名空间定义自定义使用者。解决方案是使用custom filter并在applicationContext-security.xml中手动配置OpenIDAuthenticationFilter:

<http ...>
   ...
   <custom-filter position="OPENID_FILTER" ref="openIdFilter" />
</http>
<b:bean id="openIdFilter" class="org.springframework.security.openid.OpenIDAuthenticationFilter">
   <b:property name="consumer" ref="openidConsumer" />
   <!-- customize your filter (authentication failure url, login-page, … -->
</b:bean>
<b:bean id="openIdConsumer" class="sample.OpenIDTestConsumer">
   <!-- config attribute exchange here -->
   <b:property name="email" value="email"/>
</b:bean>

答案 1 :(得分:2)

另一个解决方案是使用FAQ中的提示并使用BeanPostProcessor。结果可能如下所示:

public class CustomOpenidConsumerBeanPostProcessor implements BeanPostProcessor {
    private OpenIDConsumer openidConsumer;

    public Object postProcessAfterInitialization(Object bean, String name) {
        if (bean instanceof OpenIDCOnsumer) {
           return openidConsumer;
        }
        return bean;
    }

    public Object postProcessBeforeInitialization(Object bean, String name) {
        return bean;
    }

    public void setOpenidConsumer(OpenIDConsumer openidConsumer) {
        this.openidConsumer = openidConsumer;
    }
}

然后您的配置将包括以下内容:

<b:bean class="CustomOpenidConsumerBeanPostProcessor">
    <b:property name="openidConsumer" ref="openIdConsumer"/>
  </b:bean>
<b:bean id="openIdConsumer" class="sample.OpenIDTestConsumer">
   <!-- config attribute exchange here -->
   <b:property name="email" value="email"/>
</b:bean>