是否可以通过我的逻辑使用 oauth 协议来创建 clientid 并生成访问令牌来保护 api?

Posted

技术标签:

【中文标题】是否可以通过我的逻辑使用 oauth 协议来创建 clientid 并生成访问令牌来保护 api?【英文标题】:Is it possible to secure api by using oauth protocol by my logic to create clientid and generate access token? 【发布时间】:2013-10-23 03:30:16 【问题描述】:

按照下面的 spring-security.xml 令牌将自动生成,但我想使用该 clientid 的 clientid 和访问令牌(在 db 中可用)在 api 中实现身份验证。

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

<!-- Just for testing... -->
<http pattern="/oauth/cache_approvals" security="none" xmlns="http://www.springframework.org/schema/security" />
<http pattern="/oauth/uncache_approvals" security="none" xmlns="http://www.springframework.org/schema/security" />

<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
    xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
    <anonymous enabled="false" />
    <http-basic entry-point-ref="clientAuthenticationEntryPoint" />
    <!-- include this only if you need to authenticate clients via request parameters -->
    <custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

<!-- The OAuth2 protected resources are separated out into their own block so we can deal with authorization and error handling 
    separately. This isn't mandatory, but it makes it easier to control the behaviour. -->
<http pattern="/test/*" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
    access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security">
    <anonymous enabled="false" />
    <intercept-url pattern="/test/*" access="ROLE_USER" />
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="test" />
</bean>

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

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

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

<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans">
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
            <bean class="org.springframework.security.access.vote.RoleVoter" />
            <bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
        </list>
    </constructor-arg>
</bean>

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

<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
    <authentication-provider>
        <user-service id="userDetailsService">
            <user name="user" password="password" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

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

<!-- Used for the persistenceof tokens (currently an in memory implementation) -->
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />

<!-- Used to create token and and every thing about them except for their persistence that is reposibility of TokenStore (Given here is a           default implementation) -->
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
    <property name="tokenStore" ref="tokenStore" />
    <property name="supportRefreshToken" value="true" />
    <property name="clientDetailsService" ref="clientDetails" />
</bean>

<bean id="userApprovalHandler" class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
    <property name="tokenServices" ref="tokenServices" />
</bean>

<!-- authorization-server aka AuthorizationServerTokenServices is an interface that defines everything necessary for token management -->
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices"
    user-approval-handler-ref="userApprovalHandler">
    <oauth:authorization-code />
    <oauth:implicit />
    <oauth:refresh-token />
    <oauth:client-credentials />
    <oauth:password />
</oauth:authorization-server>

<oauth:resource-server id="resourceServerFilter" resource-id="test" token-services-ref="tokenServices" />
<!-- ClientsDeailsService: Entry Point to clients database (given is in memory implementation) -->
<oauth:client-details-service id="clientDetails">
<!-- client -->
<oauth:client client-id="the_client" authorized-grant-types="authorization_code,client_credentials"
        authorities="ROLE_USER" scope="read,write,trust" secret="secret" />

<oauth:client client-id="my-trusted-client-with-secret" authorized-grant-types="password,authorization_code,refresh_token,implicit"
        secret="somesecret" authorities="ROLE_USER" />

</oauth:client-details-service>

<sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true">
    <!--you could also wire in the expression handler up at the layer of the http filters. See https://jira.springsource.org/browse/SEC-1452 -->
    <sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>

<oauth:expression-handler id="oauthExpressionHandler" />

<oauth:web-expression-handler id="oauthWebExpressionHandler" />

谢谢

【问题讨论】:

【参考方案1】:

而不是使用

 <oauth:client-details-service id="clientDetails">
<oauth:client client-id="the_client" authorized-grant-types="authorization_code,client_credentials" authorities="ROLE_USER"          scope="read,write,trust" secret="secret" />
<oauth:client client-id="my-trusted-client-with-secret" authorized-grant-types="password,authorization_code,refresh_token,implicit"
    secret="somesecret" authorities="ROLE_USER" />

使用这个

<beans:bean id="clientDetails"  class="org.springframework.security.oauth2.provider.JdbcClientDetailsService">
    <beans:constructor-arg ref="dataSource" />
</beans:bean>

您也可以创建自己的自定义 ClientDetailsS​​ervice,例如 spring-oauth 提供的 JdbcClientDetailsS​​ervice。

注意:- 当使用 JdbcClientDetailsS​​ervice 时,使用 JdbcClientDetailsS​​ervice 使用的必要列制作 oauth-client-details 表。

【讨论】:

那么百万美元的问题是,该表的 DDL 是什么?我似乎在任何地方都找不到它... github.com/spring-projects/spring-security-oauth/blob/master/…

以上是关于是否可以通过我的逻辑使用 oauth 协议来创建 clientid 并生成访问令牌来保护 api?的主要内容,如果未能解决你的问题,请参考以下文章

Oauth2协议中如何对accessToken进行校验

Oauth2协议中如何对accessToken进行校验

OAuth 2.0应该用于身份验证超时吗?

如何识别OAuth令牌是否已过期?

OAuth2.0

防止 OAuth 客户端修改用户的请求