我是使用Spring Security OAuth2版本实现的2.0.10.RELEASE的新手。我使用'InMemoryTokenStore'开发了代码,并且对它的工作方式印象深刻(它创建了access_token'refresh_token'等。),但是我对它的工作方式还没有足够的了解。任何人都可以帮助了解/提供有关其工作原理的信息吗?

从黑客的 Angular 来看,'InMemoryTokenStore'是最安全的实现吗?我还看到OAuth2提供了许多实现,例如JdbcTokenStoreJwtTokenStoreKeyStoreKeyFactory。我不认为像access_token一样,将JdbcTokenStore存储到数据库中也很不错。

我们应该遵循哪种实现方式,为什么?

spring-security-oauth2.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:oauth="http://www.springframework.org/schema/security/oauth2"
    xmlns:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">


    <http pattern="/oauth/token" auto-config="true" use-expressions="true"  create-session="stateless"  authentication-manager-ref="authenticationManager"
        xmlns="http://www.springframework.org/schema/security" >

        <!-- <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" /> -->
        <intercept-url pattern="/oauth/token" access="permitAll" />
        <anonymous enabled="false" />
        <http-basic entry-point-ref="clientAuthenticationEntryPoint" />
        <custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
        <!-- Added this to fix error -->
        <sec:csrf disabled="true" />
    </http>

    <http pattern="/resources/**" auto-config="true" use-expressions="true" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
        xmlns="http://www.springframework.org/schema/security">
        <anonymous enabled="false" />
        <intercept-url pattern="/resources/**" method="GET" />
        <!-- <intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_FULLY" /> -->
        <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
        <!-- Added this to fix error -->
        <sec:csrf disabled="true" />
    </http>

    <http pattern="/logout" create-session="never"  auto-config="true" use-expressions="true"
        entry-point-ref="oauthAuthenticationEntryPoint"
        xmlns="http://www.springframework.org/schema/security">
        <anonymous enabled="false" />
        <intercept-url pattern="/logout" method="GET" />
        <sec:logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler"   />
        <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
        <!-- Added this to fix error -->
        <sec:csrf disabled="true" />
    </http>

    <bean id="logoutSuccessHandler" class="demo.oauth2.authentication.security.LogoutImpl" >
        <property name="tokenstore" ref="tokenStore"></property>
    </bean>

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

    <bean id="clientAuthenticationEntryPoint"
        class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
        <property name="realmName" value="springsec/client" />
        <property name="typeName" value="Basic" />
    </bean>

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

    <bean id="clientCredentialsTokenEndpointFilter"
        class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
        <property name="authenticationManager" ref="authenticationManager" />
    </bean>

    <authentication-manager alias="authenticationManager"
        xmlns="http://www.springframework.org/schema/security">
        <authentication-provider user-service-ref="clientDetailsUserService" />
    </authentication-manager>

    <bean id="clientDetailsUserService"
        class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
        <constructor-arg ref="clientDetails" />
    </bean>

    <bean id="clientDetails" class="demo.oauth2.authentication.security.ClientDetailsServiceImpl"/>

    <authentication-manager id="userAuthenticationManager"
        xmlns="http://www.springframework.org/schema/security">
        <authentication-provider  ref="customUserAuthenticationProvider">
        </authentication-provider>
    </authentication-manager>

    <bean id="customUserAuthenticationProvider"
        class="demo.oauth2.authentication.security.CustomUserAuthenticationProvider">
    </bean>

    <oauth:authorization-server
        client-details-service-ref="clientDetails" token-services-ref="tokenServices">
        <oauth:authorization-code />
        <oauth:implicit/>
        <oauth:refresh-token/>
        <oauth:client-credentials />
        <oauth:password authentication-manager-ref="userAuthenticationManager"/>
    </oauth:authorization-server>

    <oauth:resource-server id="resourceServerFilter"
        resource-id="springsec" token-services-ref="tokenServices" />

    <!-- <bean id="tokenStore"
        class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" /> -->

    <bean id="tokenStore"
          class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />

    <bean id="tokenServices"
        class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
        <property name="tokenStore" ref="tokenStore" />
        <property name="supportRefreshToken" value="true" />
        <property name="accessTokenValiditySeconds" value="300000"></property>
        <property name="clientDetailsService" ref="clientDetails" />
    </bean>


    <mvc:annotation-driven />   <!-- Declares explicit support for annotation-driven MVC controllers  @RequestMapping, @Controller -->

    <mvc:default-servlet-handler />

    <bean id="MyResource" class="demo.oauth2.authentication.resources.MyResource"></bean>

</beans>

最佳答案

您正在将几件事混在一起。 InMemoryTokenStore,JwtTokenStore和JdbcTokenStore仅应用于不同的情况。没有哪个事情比其中一个更安全,哪个更不安全。

JwtTokenStore



重要的是, token 根本不会持久保存,而是基于签名“即时”验证。



InMemoryTokenStore

InMemoryTokenStore 将 token 存储在服务器内存中,因此几乎不可能在不同服务器之间共享它们。重新启动授权服务器时,您将丢失InMemoryTokenStore中的所有访问 token 。我希望仅在开发期间而不是在生产环境中使用InMemoryTokenStore。



JdbcTokenStore



如果是JdbcTokenStore,则将 token 保存在真实数据库中。因此,在授权服务重新启动的情况下,您是安全的。 token 还可以轻松地在服务器之间共享和撤销。但是您对数据库的依赖性更大。

07-24 16:42