【问题标题】:Mule persistent OAuth token storeMule 持久 OAuth 令牌存储
【发布时间】:2014-11-18 12:23:41
【问题描述】:

有谁知道如何为 Mule OAuth Provider 模块配置持久令牌存储​​? 添加普通对象存储不支持org.mule.modules.oauth2.provider.token.TokenStore 接口。

编辑

我想持久化到文件-磁盘。

编辑 2

OAuth 提供程序设置流程:

<mule xmlns:objectstore="http://www.mulesoft.org/schema/mule/objectstore" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:https="http://www.mulesoft.org/schema/mule/https" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:json="http://www.mulesoft.org/schema/mule/json"
    xmlns:mulexml="http://www.mulesoft.org/schema/mule/xml"
    xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" 
    xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.5.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ss="http://www.springframework.org/schema/security" xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security"
    xmlns:oauth2-provider="http://www.mulesoft.org/schema/mule/oauth2-provider"
    xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-current.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/xml http://www.mulesoft.org/schema/mule/xml/current/mule-xml.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/https http://www.mulesoft.org/schema/mule/https/current/mule-https.xsd
http://www.mulesoft.org/schema/mule/oauth2-provider http://www.mulesoft.org/schema/mule/oauth2-provider/current/mule-oauth2-provider.xsd
http://www.mulesoft.org/schema/mule/spring-security http://www.mulesoft.org/schema/mule/spring-security/current/mule-spring-security.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.mulesoft.org/schema/mule/objectstore http://www.mulesoft.org/schema/mule/objectstore/current/mule-objectstore.xsd">
    <spring:beans>
        <spring:bean id="oauthTokenStore" name="oauthTokenStore" class="org.mule.util.store.TextFileObjectStore"/>
    </spring:beans>

    <spring:beans>
        <ss:authentication-manager id="resourceOwnerAuthenticationManager">
            <ss:authentication-provider>
                <ss:user-service id="resourceOwnerUserService">
                    <ss:user name="${username}" password="${password}" authorities="RESOURCE_OWNER" />
                </ss:user-service>
            </ss:authentication-provider>
        </ss:authentication-manager>
    </spring:beans>

    <mule-ss:security-manager>
        <mule-ss:delegate-security-provider name="resourceOwnerSecurityProvider" delegate-ref="resourceOwnerAuthenticationManager" />
    </mule-ss:security-manager>

    <oauth2-provider:config name="blazeOauth2Provider"
        providerName="Blaze" host="0.0.0.0" port="${blaze.esb.port.https}"
        authorizationEndpointPath="api/1.0/authorize" accessTokenEndpointPath="api/1.0/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="BLAH" doc:name="OAuth provider module"
        tokenTtlSeconds="${blaze.security.token.lifespan}" connector-ref="httpsServerConnector" supportedGrantTypes="AUTHORIZATION_CODE IMPLICIT" enableRefreshToken="true" tokenStore-ref="oauthTokenStore" >

        <oauth2-provider:clients>
            <oauth2-provider:client clientId="${blaze.client.id}" secret="${blaze.client.secret}" type="CONFIDENTIAL" clientName="Client" description="Service Front-End">
                <oauth2-provider:redirect-uris>
                    <oauth2-provider:redirect-uri>http://localhost*</oauth2-provider:redirect-uri>
                </oauth2-provider:redirect-uris>
                <oauth2-provider:authorized-grant-types>
                    <oauth2-provider:authorized-grant-type>AUTHORIZATION_CODE</oauth2-provider:authorized-grant-type>
                    <oauth2-provider:authorized-grant-type>TOKEN</oauth2-provider:authorized-grant-type>
                </oauth2-provider:authorized-grant-types>
                <oauth2-provider:scopes>
                    <oauth2-provider:scope>BLAH</oauth2-provider:scope>
                </oauth2-provider:scopes>
            </oauth2-provider:client>
        </oauth2-provider:clients>
    </oauth2-provider:config>

</mule>

【问题讨论】:

  • 要使用哪种类型的持久性来存储令牌?
  • 文件持久性 - 我已经编辑了帖子

标签: oauth-2.0 mule


【解决方案1】:

好的,经过一个简单的测试,我建议您开发自己的 FileObjectStore 以获得更多控制。

  1. 创建公共类,例如:

    公共类 MyFileObjectStore 扩展 AbstractObjectStore { ..}

  2. 使用属性文件存储令牌,key=value

  3. 实现方法:doStore、doRetrieve、doRemove,主要是更新属性文件。

  4. 改变你的流程:

    <spring:bean id="accessTokenStore" class="test.MyFileObjectStore"/>
    
    <spring: bean name="tokenStore" class="org.mule.modules.oauth2.provider.token.ObjectStoreTokenStore">
    <spring:property name="accessTokenObjectStore" ref="accessTokenStore" />
    

【讨论】:

    【解决方案2】:

    有几种方法可以为 oauth 设置 tokenStore。您可以使用例如(最常见的):

    1. org.mule.util.store.PartitionedPersistentObjectStore 或
    2. org.mule.transport.jdbc.store.JdbcObjectStore

    根据您的要求,您可以使用:

    org.mule.util.store.TextFileObjectStore

    希望能帮到你;

    【讨论】:

    • 谢谢胡里奥,你有一个例子 - 我正在努力实施。尝试&lt;spring:bean id="oauthTokenStore" name="oauthTokenStore" class="org.mule.util.store.TextFileObjectStore"/&gt; 并将其链接到 OAuth 令牌存储引用,但 Mule 不喜欢:无法转换为类型 org.mule.modules.oauth2.provider.token.TokenStore
    • 添加了 EDIT 2 - XML with global provider
    【解决方案3】:

    基于@Julio 的回答:

    添加了一个实现映射&lt;String, AccessTokenStoreHolder&gt;的类:

    package xxx;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Properties;
    
    import org.mule.api.lifecycle.InitialisationException;
    import org.mule.api.store.ObjectDoesNotExistException;
    import org.mule.api.store.ObjectStoreException;
    import org.mule.config.i18n.CoreMessages;
    import org.mule.util.FileUtils;
    import org.mule.util.IOUtils;
    import org.mule.util.StringUtils;
    import org.mule.util.store.InMemoryObjectStore;
    import org.mule.modules.oauth2.provider.token.AccessTokenStoreHolder;
    
    public class PersistantOAuthObjectStore extends InMemoryObjectStore<AccessTokenStoreHolder> {
    
        protected File fileStore;
        protected String directory;
        private Map<String, AccessTokenStoreHolder> tokenStore;
        private FileOutputStream output;
    
        public PersistantOAuthObjectStore() {
            super();
        }
    
        private Map<String, AccessTokenStoreHolder> getTokenStore() {
            if (tokenStore == null)
                tokenStore = new HashMap<>();
            return tokenStore;
        }
    
        @Override
        public void initialise() throws InitialisationException
        {
            super.initialise();
             if (directory == null)
                directory = context.getConfiguration().getWorkingDirectory() + "/objectstore";
    
            try
            {
                File dir = FileUtils.openDirectory(directory);
                fileStore = new File(dir, name + ".dat");
                if (fileStore.exists())
                    loadFromStore();
            }
            catch (Exception e)
            {
                throw new InitialisationException(e, this);
            }
        }
    
        @SuppressWarnings("unchecked")
        protected synchronized void loadFromStore() throws Exception
        {
            ObjectInputStream stream = new ObjectInputStream(new FileInputStream(fileStore));
            Object result = stream.readObject();
            tokenStore = (Map<String, AccessTokenStoreHolder>)result;
            for (Map.Entry<String, AccessTokenStoreHolder> entry : getTokenStore().entrySet())
                super.store(entry.getKey().toString(), entry.getValue());
    
            stream.close();
        }
    
        @Override
        public void store(Serializable id, AccessTokenStoreHolder item) throws ObjectStoreException
        {
            super.store(id, item);
    
            try
            {
    
                synchronized(getTokenStore()) {
                    getTokenStore().put(id.toString(), item);
                    saveMap();
                }
    
            }
            catch (IOException e)
            {
                throw new ObjectStoreException(e);
            }
        }
    
        private void saveMap() throws IOException {
            if (output == null)
                output = new FileOutputStream(fileStore, false);
    
            ObjectOutputStream stream = new ObjectOutputStream(output); 
            stream.writeObject(getTokenStore());
        }
    
        @Override
        public AccessTokenStoreHolder remove(Serializable key) throws ObjectStoreException
        {
            super.retrieve(key);
    
            try
            {
                synchronized (getTokenStore())
                {
                    if (getTokenStore().containsKey(key)) {
                        AccessTokenStoreHolder val = getTokenStore().get(key);
                        getTokenStore().remove(key);
                        saveMap();
                        return val;
                    }
                }
    
                throw new ObjectDoesNotExistException(CoreMessages.objectNotFound(key));
            }
            catch (IOException e)
            {
                throw new ObjectStoreException(e);
            }
        }   
    
        @Override
        public void clear() throws ObjectStoreException
        {
            super.clear();
    
            try
            {
                synchronized (getTokenStore()) {
                    getTokenStore().clear();
                    saveMap();
                }
            }
            catch (IOException e)
            {
                throw new ObjectStoreException(e);
            }
        }
    
        public String getDirectory()
        {
            return directory;
        }
    
        public void setDirectory(String directory)
        {
            this.directory = directory;
        }
    
        @Override
        public boolean isPersistent() {
            return true;
        }
    
    }
    

    然后在xml中添加2个spring bean:

    <spring:bean id="oauthTokenStore" name="oauthTokenStore" class="org.mule.modules.oauth2.provider.token.ObjectStoreTokenStore">
        <spring:property name="accessTokenObjectStore" ref="oauthObjectStore"/>
    </spring:bean>
    <spring:bean id="oauthObjectStore" class="com.vatit.blaze.esb.utils.objectStore.BlazePersistantObjectStore" init-method="initialise" destroy-method="dispose" name="oauthObjectStore">
        <spring:property name="name" value="oauthObjectStore"/>
    </spring:bean>
    

    然后在您的 OAuth 2 提供程序配置中引用 tokenStoretokenStore-ref="oauthTokenStore"

    【讨论】:

    • 优秀的吉尔伯特,感谢您的贡献。
    • 重新发布了一些垃圾清理+固定同步部分 - 我认为(java初学者)
    【解决方案4】:

    我认为上述答案是正确的,但并不理想。 ObjectStoreTokenStore 可以由多个持久对象存储组成。我不确定您是否甚至需要编写任何 Java 代码来完成这项工作。

    <spring:bean name="tokenStore" class="org.mule.modules.oauth2.provider.token.ObjectStoreTokenStore">
        <spring:property name="accessTokenObjectStore" ref="accessTokenFileObjectStore"/>
        <spring:property name="refreshTokenObjectStore" ref="refreshTokenFileObjectStore"/>
    </spring:bean>
    

    这里的accessTokenFileObjectStorerefreshTokenFileObjectStore 可以是从TextFileObjectStore 创建的spring bean

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-14
      • 2011-09-12
      • 1970-01-01
      • 2014-12-21
      • 2021-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多