Spring WebFlow + Spring 安全性:使用表达式而不是角色
Spring WebFlow + Spring Security: use expression instead of role
我创建了一个 CustomWebSecurityExpressionHandler 来通过搜索函数 ID 检查数据库 table 上的用户。我想通过一些数据库更新和重新启动上下文来更改我在每个函数上的角色,而不需要重新编译和编辑 XML.
的山
我想在 webflow 中使用 SpringSecurityExpression!就像我在 Spring 的任何其他部分可以做的那样...
<?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">
<secured attributes="isFUUU('key')" />
<view-state id="main" view="dashboard/main.html" >
</view-state>
</flow>
如何让 isFUU("key") 正常工作?需要自定义 CustomAccessDecisionManager 吗?
我找到了解决方法
我必须调试 20 classes of spring security 和 webflow 发现在 SecurityFlowExecutionListener 中,即使你设置 spring security 来处理表达式,侦听器也会起作用仅基于。
我发现为了解析表达式 a 需要一个特定类型的配置属性,准确地说是 WebExpressionConfigAttribute。
但它不是 public class!!! https://jira.spring.io/browse/SEC-1727。
因此,正如这个 OLD Jira 中所建议的,我需要在同一个包中创建我的 CustomSecurityFlowExecutionListener (org.springframework.security.web.access.expression)
这里是例子
CustomSecurityFlowExecutionListener:
package org.springframework.security.web.access.expression; //First part of the trick!
import foo.bar.example.services.security.CustomAccessDecisionManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.expression.ExpressionParser;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.webflow.security.SecurityFlowExecutionListener;
import org.springframework.webflow.security.SecurityRule;
/**
* Force Spring WebFlow Security listener to use expression!
*
* @author roberto.gabrieli
*/
public class CustomSecurityFlowExecutionListener<T > extends SecurityFlowExecutionListener
{
/**
* Convert SecurityRule into a form understood by Spring Security Force the usage of WebExpressionConfigAttribute!
*
* @param rule
* the rule to convert
* @return list of ConfigAttributes for Spring Security
*/
@Override
@SuppressWarnings("deprecation")
protected Collection<ConfigAttribute> getConfigAttributes(SecurityRule rule)
{
// Get Access Decision Manager to find if has my expression handler
AccessDecisionManager adm = getAccessDecisionManager();
ExpressionParser ep = null;
// Check if is my CustomAccessDecisionManager so I can use my expressions
if ( adm instanceof CustomAccessDecisionManager )
{
ep = ((CustomAccessDecisionManager) adm).getWebSecurityExpressionHandler().getExpressionParser();
}
List<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
for ( String attribute : rule.getAttributes() )
{
if ( ep != null )
// this will end the trick with fireworks!
configAttributes.add(new WebExpressionConfigAttribute(ep.parseExpression(attribute)));
else
configAttributes.add(new SecurityConfig(attribute));
}
return configAttributes;
}
}
WebFlow-config.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.4.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
...
<bean id="securityFlowExecutionListener"
class="org.springframework.security.web.access.expression.MamSecurityFlowExecutionListener">
<property name="accessDecisionManager" ref="customAccessDecisionManager"/>
</bean>
...
</beans>
我找到了另一个如何在 WebFlows 中使用 Spring 表达式语言的解决方案。出自书 "Pro Spring Security"。简而言之,他们定义了自定义 AccessDecisionManger
和自定义 AccessDecisionVoter
(implements AccessDesisionVoter<org.springframework.webflow.engine.State
) 和自定义 SecurityExpressionRoot
。因此,不需要像您的解决方案中那样拥有自己的侦听器。这些自定义 类 支持流状态级别的表达式。您可以在 github 上使用 link.
找到完整示例
我创建了一个 CustomWebSecurityExpressionHandler 来通过搜索函数 ID 检查数据库 table 上的用户。我想通过一些数据库更新和重新启动上下文来更改我在每个函数上的角色,而不需要重新编译和编辑 XML.
的山我想在 webflow 中使用 SpringSecurityExpression!就像我在 Spring 的任何其他部分可以做的那样...
<?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">
<secured attributes="isFUUU('key')" />
<view-state id="main" view="dashboard/main.html" >
</view-state>
</flow>
如何让 isFUU("key") 正常工作?需要自定义 CustomAccessDecisionManager 吗?
我找到了解决方法
我必须调试 20 classes of spring security 和 webflow 发现在 SecurityFlowExecutionListener 中,即使你设置 spring security 来处理表达式,侦听器也会起作用仅基于。 我发现为了解析表达式 a 需要一个特定类型的配置属性,准确地说是 WebExpressionConfigAttribute。 但它不是 public class!!! https://jira.spring.io/browse/SEC-1727。 因此,正如这个 OLD Jira 中所建议的,我需要在同一个包中创建我的 CustomSecurityFlowExecutionListener (org.springframework.security.web.access.expression)
这里是例子
CustomSecurityFlowExecutionListener:
package org.springframework.security.web.access.expression; //First part of the trick!
import foo.bar.example.services.security.CustomAccessDecisionManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.expression.ExpressionParser;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.webflow.security.SecurityFlowExecutionListener;
import org.springframework.webflow.security.SecurityRule;
/**
* Force Spring WebFlow Security listener to use expression!
*
* @author roberto.gabrieli
*/
public class CustomSecurityFlowExecutionListener<T > extends SecurityFlowExecutionListener
{
/**
* Convert SecurityRule into a form understood by Spring Security Force the usage of WebExpressionConfigAttribute!
*
* @param rule
* the rule to convert
* @return list of ConfigAttributes for Spring Security
*/
@Override
@SuppressWarnings("deprecation")
protected Collection<ConfigAttribute> getConfigAttributes(SecurityRule rule)
{
// Get Access Decision Manager to find if has my expression handler
AccessDecisionManager adm = getAccessDecisionManager();
ExpressionParser ep = null;
// Check if is my CustomAccessDecisionManager so I can use my expressions
if ( adm instanceof CustomAccessDecisionManager )
{
ep = ((CustomAccessDecisionManager) adm).getWebSecurityExpressionHandler().getExpressionParser();
}
List<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
for ( String attribute : rule.getAttributes() )
{
if ( ep != null )
// this will end the trick with fireworks!
configAttributes.add(new WebExpressionConfigAttribute(ep.parseExpression(attribute)));
else
configAttributes.add(new SecurityConfig(attribute));
}
return configAttributes;
}
}
WebFlow-config.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.4.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
...
<bean id="securityFlowExecutionListener"
class="org.springframework.security.web.access.expression.MamSecurityFlowExecutionListener">
<property name="accessDecisionManager" ref="customAccessDecisionManager"/>
</bean>
...
</beans>
我找到了另一个如何在 WebFlows 中使用 Spring 表达式语言的解决方案。出自书 "Pro Spring Security"。简而言之,他们定义了自定义 AccessDecisionManger
和自定义 AccessDecisionVoter
(implements AccessDesisionVoter<org.springframework.webflow.engine.State
) 和自定义 SecurityExpressionRoot
。因此,不需要像您的解决方案中那样拥有自己的侦听器。这些自定义 类 支持流状态级别的表达式。您可以在 github 上使用 link.