Spring 安全显示默认登录而不是 OAuth2

Spring Security shows default login instead of OAuth2

我正在编写需要对用户进行身份验证的 RESTful Web 服务(Tomcat 上的泽西岛 运行)。计划是重定向他们通过 OAuth2 登录到 Google。一旦他们允许我们查看他们的电子邮件地址,我们就会知道他们是否是我们系统中的已知用户。

我正在使用 Spring Security。我让它使用基本身份验证(用户和密码的硬连线列表。)然后我将 OAuth2 元素添加到 XML 配置中,但是当我从浏览器访问该服务时,我仍然得到浏览器提示登录,而不是重定向到 Google 的网站。控制台没有记录任何特定错误。

建议将不胜感激。这是我的 Spring 安全配置文件:spring-security.xml(虽然没有真实客户端的 ID 和密码。)

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2" 

xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  http://www.springframework.org/schema/security
  http://www.springframework.org/schema/security/spring-security-3.2.xsd
  http://www.springframework.org/schema/security/oauth2 
  http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd">

<debug/>

<oauth:client id="oauth2ClientFilter" />

<oauth:resource id="googleOauth2Resource" type="authorization_code" client-id="myclientid.apps.googleusercontent.com" client-secret="myclientsecret" 
    access-token-uri="https://accounts.google.com/o/oauth2/v3/token" user-authorization-uri="https://accounts.google.com/o/oauth2/auth" scope="email" />

<http auto-config='true' xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/V1/**" access="ROLE_USER" />
    <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <custom-filter ref="oauth2ClientFilter" after="EXCEPTION_TRANSLATION_FILTER" />
</http>

<oauth:rest-template id="googleOauthRestTemplate" resource="googleOauth2Resource" />

<authentication-manager>
</authentication-manager>

</beans:beans>

这是我的 web.xml 文件的内容。 (当我有用户和密码的硬连线列表时,这里没有任何改变。)

<!-- Require HTTPS for everything except /img (favicon) and /css. -->
<security-constraint>
    <web-resource-collection>
        <web-resource-name>HTTPSOnly</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>
<security-constraint>
    <web-resource-collection>
        <web-resource-name>HTTPSOrHTTP</web-resource-name>
        <url-pattern>*.ico</url-pattern>
        <url-pattern>/img/*</url-pattern>
        <url-pattern>/css/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
</security-constraint> 


<servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <!-- Register resources and providers under com.vogella.jersey.first package. -->
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.foobar.dataservices</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/V1/*</url-pattern>
</servlet-mapping>

<resource-ref>
    <description>TAE DB Connection Pool</description>
    <res-ref-name>jdbc/taeDB</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

<listener>  
  <listener-class>
   org.springframework.web.context.ContextLoaderListener  
  </listener-class>  
</listener>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/spring-security.xml</param-value>
</context-param>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

非常感谢有关 OAuth2 工作的建议。

正在从 spring-security.xml[=28= 中的 http 元素中删除 auto-config="true" ] 摆脱了错误的登录表单。

这揭示了一个新错误:

Configuration problem: No AuthenticationEntryPoint could be established. Please make sure you have a login mechanism configured through the namespace (such as form-login) or specify a custom AuthenticationEntryPoint with the 'entry-point-ref' attribute

所以我添加了缺失的 entry-point-ref 和一个 access-denied-handler

<http xmlns="http://www.springframework.org/schema/security" entry-point-ref="oauthAuthenticationEntryPoint">
    <intercept-url pattern="/V1/**" access="IS_AUTHENTICATED_FULLY" />
    <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <custom-filter ref="oauth2ClientFilter" after="EXCEPTION_TRANSLATION_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

<beans:bean id="oauthAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
</beans:bean>

<beans:bean id="oauthAccessDeniedHandler"
    class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
</beans:bean>

服务现在启动时不会记录任何错误,也不会显示错误的登录表单。

(但请注意,它拒绝了我所有资源的权限。我认为 Spring Security 会代表我的 RESTful 服务重定向到 Google,但也许我的网页需要获取调用服务之前的授权令牌?我认为这是一个新话题。)