【问题标题】:Spring oAuth2 with user rights具有用户权限的 Spring oAuth2
【发布时间】:2015-03-30 18:03:22
【问题描述】:

我对 oauth 非常陌生,尤其是 spring oauth2。目前在我的项目中,我通过xml配置启用spring安全提供程序来使用基本的spring oauth。

当前配置支持使用 ROLE_CLIENT 访问我的服务。 该数据库只是 spring 参考文档中指定的参考数据库

但现在我需要使用 USER RIGHTS 扩展用户级别的 spring 安全授权,而不是像 spring 默认那样基于 ROLE。

现在我有以下表格

什么是使用oauth2并使用spring security使用用户权限授权我的api。

这是我的上下文 securty.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: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.xsd  
	http://www.springframework.org/schema/context  
	http://www.springframework.org/schema/context/spring-context.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">

	
	<http pattern="/oauth/token" create-session="stateless"
		authentication-manager-ref="clientAuthenticationManager"
		xmlns="http://www.springframework.org/schema/security">
		<anonymous enabled="false" />
		<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
		<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>

	<!--OAuth2 protected resources are separated out into their own block so 
		can deal with authorization and error handling separately -->
	<http pattern="/api/**" 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="/api/**" access="ROLE_CLIENT" requires-channel="https"/>
		<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
		<access-denied-handler ref="oauthAccessDeniedHandler" />
	</http>
	
	<bean id="clientDetails" class="org.springframework.security.oauth2.provider.client.JdbcClientDetailsService">
		<constructor-arg index="0">
			<ref bean="dataSource" />
		</constructor-arg>
	</bean>
	
	<!-- Configure Authentication manager -->
	<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
		<constructor-arg name="strength" value="11" />
	</bean>
	
	<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
		<constructor-arg ref="clientDetails" />
	</bean>
	<!-- Used for the persistence of tokens (currently an in memory implementation) 
	<bean id="tokenStore"
		class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />
	-->
	<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
		<constructor-arg ref="dataSource" />
	</bean>
	
	<!-- Used to create token and every thing about them except for their persistence 
		that is reposibility of TokenStore -->
	<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" />
		<property name="accessTokenValiditySeconds" value="4500" />
	</bean>
	<!-- <bean id="userApprovalHandler" class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler"> 
		<property name="tokenServices" ref="tokenServices" /> </bean> -->

	<bean id="oAuth2RequestFactory" class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
		<constructor-arg ref="clientDetails" />
	</bean>
	
	<bean id="userApprovalHandler" class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
		<property name="requestFactory" ref="oAuth2RequestFactory" />
		<property name="tokenStore" ref="tokenStore" />
	</bean>

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

	<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
		<property name="realmName" value="Authorization/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="authenticationManager" />
	</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="user123" authorities="ROLE_CLIENT" />
			</user-service>
		</authentication-provider>
	</authentication-manager>
	-->
	
	<authentication-manager alias="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
		<authentication-provider user-service-ref="clientDetailsUserService">
			<password-encoder ref="passwordEncoder" />
		</authentication-provider>
	</authentication-manager>
	
	<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
		<authentication-provider>
		    <!--  password-encoder hash="sha" />-->
		    <password-encoder ref="passwordEncoder" />
			<jdbc-user-service  data-source-ref="dataSource"/>
		</authentication-provider>
		<authentication-provider user-service-ref="clientDetailsUserService" />
	</authentication-manager>

	
	<!--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 authentication-manager-ref="authenticationManager"/>
	</oauth:authorization-server>

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

	<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" />
</beans>

【问题讨论】:

    标签: java spring spring-mvc oauth spring-security


    【解决方案1】:

    在您的 userDetails 类中添加检查给定 RIGHT 的方法,然后在您的

       <http pattern="/api/**" 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="/api/**" access="ROLE_CLIENT" requires-channel="https"/>
            <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
            <access-denied-handler ref="oauthAccessDeniedHandler" />
        </http>
    

    而不是

    <intercept-url pattern="/api/**" access="ROLE_CLIENT" requires-channel="https"/>
    

    使用

    <intercept-url pattern="/api/**" access="getPrincipal().hasHasSpecificRight()" requires-channel="https"/>
    

    hasHasSpecificRight() 是检查所需 RIGHT 的方法

    【讨论】:

    • 我在原则上找不到这样的功能。那么我应该如何为该调用编写 EL。
    • 你不能因为我上面说过你必须实现你自己的clientDetails。你能告诉我你的 getPrincipal() 方法返回什么类类型,它会更容易为你指出正确的方向吗? docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/…
    • 我正在使用春季参考文档中解释的 oauth。我的数据库与弹簧参考相同(第一张图片显示了关系)。我使用 JdbcClientDetailsS​​ervice 作为 clientDetails。
    • 我知道你在使用什么,但你能告诉我你的 getPrincipal() 返回什么类型的对象吗?您将针对经过身份验证的用户的属性进行身份验证,用户拥有权利,您必须检查该用户拥有哪些权利才能查看他是否被授权,但您必须找到访问允许您执行的对象的方法检查。如果您发布您的 getPrincipal() 返回的类,我们可以从那里开始。不仅仅是一行代码的问题。
    • 这是主体对象类型:org.springframework.security.oauth2.provider.OAuth2Authentication 这是里面的内容: 主体:org.springframework.security.core.userdetails.User@364492:用户名: 测试;密码保护];启用:真; AccountNonExpired:真;凭据非过期:真; AccountNonLocked:真;授予权限:ROLE_CLIENT;凭证:[受保护];已认证:真实;详细信息:remoteAddress=127.0.0.1,tokenValue=;授予权限:ROLE_CLIENT
    猜你喜欢
    • 2017-03-30
    • 2016-10-11
    • 2018-05-15
    • 2016-07-08
    • 2015-06-25
    • 2015-09-28
    • 2015-05-10
    • 2015-11-12
    • 2022-11-27
    相关资源
    最近更新 更多