質問

I'm using Spring Web Flow in my webapp and i would like to know if there is a general way to prevent some subflows to be accessed directly. These subflows are meant to be accessed just from certain flows, not directly by the url, so in these subflows i would like to check "if i was called from a flow".

is there any mechanisms to achieve it? I was looking at spring security but i couldn't find any useful feature to make this kind of restriction.

Thanks you!

役に立ちましたか?

解決

You can check this by using input mapper attribute as shown below. Suppose you have a parent flow which invokes 'subflow-flow'. You need to pass an input value containing the name of the parent flow as:

    <?xml version="1.0" encoding="UTF-8"?>
    <flow xmlns="http://www.springframework.org/schema/webflow"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/webflow
            http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">  
        ... 
        <subflow-state id="subflow-flow" subflow="subflow-flow">
            <!--flowInitiatedBy should be different for each different parent flow-->
            <input name="flowInitiatedBy" value="'parentFlowName'"/>
            <transition on="invalidAccess" to="someViewWithMessage"/>
            <transition on="processedSubflow" to="someOtherState"/>
        </subflow-state>
        ...
    </flow>

Then in subflow you can retrieve the parentflowname and perform the check in yourAction class. You can define subflow as:

    <?xml version="1.0" encoding="UTF-8"?>
    <flow xmlns="http://www.springframework.org/schema/webflow"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/webflow
            http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
            start-state="start">            
        <input name="flowInitiatedBy" type="java.lang.String"/>
        <action-state id="start">
            <evaluate expression="yourAction.checkAccessibility(flowRequestContext)"/>
            <transition on="invalidAccess" to="verifyWhetherDraftsExists"/>
            <transition on="continue" to="continueToState"/>
        </action-state>
        <!--define other states for continue transition -->
        ...
        <end-state id="invalidAccess"/>
        <end-state id="processedSubflow"/>
    </flow>

In your action class:

    public class YourAction{
    ...
    public String checkAccessibility(RequestContext context){
        String flowInitiatedBy = context.getFlowScope().get("flowInitiatedBy");
        //flowInitiatedBy will be empty if initiated by url.
        if(flowInitiatedBy is empty){
            return "invalidAccess";
        }else{
            // dosomething
            return "continue";
        }
    }
    ...
    }

Hope this helps.

他のヒント

I also wish there was some kind of built-in, simple mechanism. However, I just did this a slightly different way I thought I'd share. That is, since my Subflow knows its own name, I just had the first state in the Flow configuration check whether or not the Flow ID (name) matches that hardcoded name:

<decision-state id="subOnly">
    <if test="flowExecutionContext.definition.id == 'thisSubflowFlowName'" then="invalidAccess" else="mySubflowFirstState"/>
</decision-state>

Where "invalidAccess" is an end-state like the prior answer shows.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top