根据API,OpenID身份验证涉及两个阶段:

  • 提交OpenID身份

  • 处理来自OpenID服务器的重定向
    我的任务是捕获第一阶段并从提交中提取额外信息 .

经过一番调查,我得出以下结论:

spring-security.xml

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

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

    <security:http pattern="/myapp/auth/login" security="none"/>
    <security:http pattern="/myapp/auth/logout" security="none"/>
    <security:http entry-point-ref="entryPoint">
        <security:intercept-url pattern="/myapp/main/*" access="ROLE_USER"/>
        <security:logout invalidate-session="true"
            logout-success-url="/myapp/auth/login"
            logout-url="/myapp/auth/logout"/>  
        <security:custom-filter position="OPENID_FILTER" ref="openIdAuthFilter"/>
    </security:http>

  <bean id="openIdAuthFilter" class="org.myorg.openid.filter.CustomOpenIDAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManager"/>
    <property name="authenticationSuccessHandler" ref="authenticationSuccessHandler"/>
    <property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
    <property name="consumer">
      <bean class="org.springframework.security.openid.OpenID4JavaConsumer">
        <constructor-arg index="0">
          <bean class="org.openid4java.consumer.ConsumerManager"/>
        </constructor-arg>
        <constructor-arg index="1">
          <list value-type="org.springframework.security.openid.OpenIDAttribute">
            <bean class="org.springframework.security.openid.OpenIDAttribute">
              <constructor-arg index="0" value="email"/>
              <constructor-arg index="1" value="http://schema.openid.net/contact/email"/>
              <property name="required" value="true"/>
              <property name="count" value="1"/>           
            </bean>
            <bean class="org.springframework.security.openid.OpenIDAttribute">
              <constructor-arg index="0" value="firstName"/>
              <constructor-arg index="1" value="http://axschema.org/namePerson/first" />
              <property name="required" value="true"/>
              <property name="count" value="1"/>     
            </bean>
            <bean class="org.springframework.security.openid.OpenIDAttribute">
              <constructor-arg index="0" value="lastName"/>
              <constructor-arg index="1" value="http://axschema.org/namePerson/last" />
              <property name="required" value="true"/>
              <property name="count" value="1"/>     
            </bean>
          </list>
        </constructor-arg>
      </bean>
    </property>
  </bean>  
    <security:authentication-manager alias="authenticationManager">
      <security:authentication-provider ref="openIdAuthProvider"/>
    </security:authentication-manager>
  <bean id="openIdAuthProvider" class="org.springframework.security.openid.OpenIDAuthenticationProvider">
    <property name="authenticationUserDetailsService" ref="registeringUserService"/>
  </bean>

    <bean id="authenticationSuccessHandler"
        class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
        <property name="defaultTargetUrl" value="/myapp/main/translationpage.jsp" />
    </bean>

    <bean id="authenticationFailureHandler"
        class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
         <property name="defaultFailureUrl" value="/myapp/auth/login?error=true" />
    </bean>
<!--
    A custom UserDetailsService which will allow any user to authenticate and "register" their IDs in an internal map
    for use if they return to the site. This is the most common usage pattern for sites which use OpenID.
 -->
    <bean id="registeringUserService" class="org.myorg.openid.service.CustomUserDetailsService" />

  <bean id="entryPoint"
    class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <property name="loginFormUrl" value="/myapp/auth/login"/>
  </bean>
</beans>

CustomOpenIDAuthenticationFilter.java,它尝试从login.jsp中提取额外信息

protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) 
    throws IOException,ServletException{
        System.out.println("==before login==");
        String language = request.getParameter("language");
        System.out.println("language= " + language);
        super.successfulAuthentication(request, response, authResult);
        System.out.println("==after login==");
    }

login.jsp打印“language = null” . 我是一个非常新的mvc和安全,我错过了什么?谢谢 . 好的,最后我想我明白了 .

http://static.springsource.org/spring-security/site/docs/3.1.x/apidocs/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.html#doFilter%28javax.servlet.ServletRequest,%20javax.servlet.ServletResponse,%20javax.servlet.FilterChain%29,它声明"Return null, indicating that the authentication process is still in progress. Before returning, the implementation should perform any additional work required to complete the process." . 但我试图打印出来 .

最终的CustomOpenIDAuthenticationFilter是

public class CustomOpenIDAuthenticationFilter extends OpenIDAuthenticationFilter{

public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException {
    System.out.println("==attemptAuthentication==");
    String language = request.getParameter("language");
    System.out.println("language= " + language);
    Authentication au = super.attemptAuthentication(request, response);
    //System.out.println(au.getPrincipal());
    return au;
}
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) 
throws IOException,ServletException{
    System.out.println("==before login==");
    super.successfulAuthentication(request, response, authResult);
    System.out.println("==after login==");
}

protected void unsuccessfulAuthentication(HttpServletRequest request,
        HttpServletResponse response, AuthenticationException failed)
throws IOException,ServletException{
    System.out.println("==before failed login==");
    super.unsuccessfulAuthentication(request, response, failed);
    System.out.println("==after failed login==");
}

}