Update docs and polish
- Modify docs and add a better content. - Add access to payload in EventSecurityExpressionRoot #114.
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
:core-jdbc-JdbcTemplate: http://docs.spring.io/spring/docs/{spring-version}/spring-framework-reference/html/jdbc.html#jdbc-JdbcTemplate
|
||||
:sm-statecontext: http://docs.spring.io/spring-statemachine/docs/{spring-statemachine-version}/api/org/springframework/statemachine/StateContext.html
|
||||
:sm-statecontext-stage: http://docs.spring.io/spring-statemachine/docs/{spring-statemachine-version}/api/org/springframework/statemachine/StateContext.Stage.html
|
||||
:spring-security-site: http://projects.spring.io/spring-security
|
||||
|
||||
= Spring Statemachine - Reference Documentation
|
||||
|
||||
|
||||
@@ -1076,10 +1076,10 @@ More about error handling shown in above example, see section
|
||||
|
||||
[[sm-security]]
|
||||
== State Machine Security
|
||||
Security features are build atop of functionality from a _Spring
|
||||
Security_. Security features are handy when it is required to protect
|
||||
part of a state machine execution and interaction with it. More
|
||||
detailed info can be found from section <<sm-security-details>>.
|
||||
Security features are build atop of functionality from a
|
||||
{spring-security-site}[_Spring Security_]. Security features are
|
||||
handy when it is required to protect part of a state machine
|
||||
execution and interaction with it.
|
||||
|
||||
[IMPORTANT]
|
||||
====
|
||||
@@ -1088,13 +1088,26 @@ we don't go into details of how overall security framework works. For
|
||||
this read _Spring Security_ reference documentation.
|
||||
====
|
||||
|
||||
First level of defence with a security is naturally protecting events
|
||||
which really are a driver from user point of view what is going to
|
||||
happen in a state machine. More fine grained security settings can
|
||||
then be defined for transitions and actions. This can be think of like
|
||||
allowing an employee to access a building, walk around it and then
|
||||
giving more detailed access rights to enter different rooms and allow
|
||||
to switch lights on and off while being on those rooms. If you trust
|
||||
your users then event security may be all you need, if you don't, then
|
||||
more detailed security needs to be applied.
|
||||
|
||||
More detailed info can be
|
||||
found from section <<sm-security-details>>.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
For complete example, see sample <<statemachine-examples-security>>.
|
||||
====
|
||||
|
||||
=== Configuring Security
|
||||
All generic configurations for security are done from
|
||||
All generic configurations for security are done in
|
||||
`SecurityConfigurer` which is obtained from
|
||||
`StateMachineConfigurationConfigurer`. Security is disabled on
|
||||
default even if _Spring Security_ classes are
|
||||
@@ -1172,38 +1185,125 @@ Attributes are easier to use but are relatively limited in terms of
|
||||
functionality. Expressions provide more features but are a little bit
|
||||
of harder to use.
|
||||
|
||||
This section is splitted into different subsections because we're
|
||||
re-using something from a _Spring Security_ and then do custom
|
||||
attributes and expression handling for events and transitions.
|
||||
|
||||
==== Generic Attribute Usage
|
||||
On default `AccessDecisionManager` instances for events and
|
||||
transitions use a `RoleVoter`, meaning you can use role attributes.
|
||||
transitions both use a `RoleVoter`, meaning you can use role attributes
|
||||
familiar from _Spring Security_.
|
||||
|
||||
For attributes we have 3 different comparison types, `ANY`, `ALL` and
|
||||
`MAJORITY` which maps into voters `AffirmativeBased`, `UnanimousBased`
|
||||
and `ConsensusBased` respectively.
|
||||
`MAJORITY` which maps into default access decision managers
|
||||
`AffirmativeBased`, `UnanimousBased` and `ConsensusBased` respectively.
|
||||
If custom `AccessDecisionManager` has been defined, comparison type is
|
||||
effectively discarded as it's only used to create a default manager.
|
||||
|
||||
==== Generic Expression Usage
|
||||
Security expressions needs to return either _TRUE_ or _FALSE_.
|
||||
|
||||
The base class for expression root objects is
|
||||
`SecurityExpressionRoot`. This provides some common expressions which
|
||||
are available in both transition and event security.
|
||||
|
||||
[[common-expressions]]
|
||||
.Common built-in expressions
|
||||
|===
|
||||
| Expression | Description
|
||||
|
||||
| `hasRole([role])`
|
||||
| Returns `true` if the current principal has the specified role. By
|
||||
default if the supplied role does not start with 'ROLE_' it will be
|
||||
added. This can be customized by modifying the `defaultRolePrefix` on
|
||||
`DefaultWebSecurityExpressionHandler`.
|
||||
|
||||
| `hasAnyRole([role1,role2])`
|
||||
| Returns `true` if the current principal has any of the supplied
|
||||
roles (given as a comma-separated list of strings). By default if the
|
||||
supplied role does not start with 'ROLE_' it will be added. This can
|
||||
be customized by modifying the `defaultRolePrefix` on
|
||||
`DefaultWebSecurityExpressionHandler`.
|
||||
|
||||
| `hasAuthority([authority])`
|
||||
| Returns `true` if the current principal has the specified authority.
|
||||
|
||||
| `hasAnyAuthority([authority1,authority2])`
|
||||
| Returns `true` if the current principal has any of the supplied
|
||||
roles (given as a comma-separated list of strings)
|
||||
|
||||
| `principal`
|
||||
| Allows direct access to the principal object representing the
|
||||
current user
|
||||
|
||||
| `authentication`
|
||||
| Allows direct access to the current `Authentication` object obtained
|
||||
from the `SecurityContext`
|
||||
|
||||
| `permitAll`
|
||||
| Always evaluates to `true`
|
||||
|
||||
| `denyAll`
|
||||
| Always evaluates to `false`
|
||||
|
||||
| `isAnonymous()`
|
||||
| Returns `true` if the current principal is an anonymous user
|
||||
|
||||
| `isRememberMe()`
|
||||
| Returns `true` if the current principal is a remember-me user
|
||||
|
||||
| `isAuthenticated()`
|
||||
| Returns `true` if the user is not anonymous
|
||||
|
||||
| `isFullyAuthenticated()`
|
||||
| Returns `true` if the user is not an anonymous or a remember-me user
|
||||
|
||||
| `hasPermission(Object target, Object permission)`
|
||||
| Returns `true` if the user has access to the provided target for the
|
||||
given permission. For example, `hasPermission(domainObject, 'read')`
|
||||
|
||||
| `hasPermission(Object targetId, String targetType, Object
|
||||
permission)`
|
||||
| Returns `true` if the user has access to the provided target for the
|
||||
given permission. For example, `hasPermission(1,
|
||||
'com.example.domain.Message', 'read')`
|
||||
|===
|
||||
|
||||
==== Event Attributes
|
||||
Event id can be matched by using prefix _EVENT__. For example matching
|
||||
event `A` would match with attribte _EVENT_A_.
|
||||
Event id can be matched by using prefix `EVENT_`. For example matching
|
||||
event `A` would match with attribte `EVENT_A`.
|
||||
|
||||
==== Event Expressions
|
||||
For generic options for expressions, see _Spring Security_ docs. We
|
||||
inherit from `SecurityExpressionRoot` and options from there are
|
||||
available.
|
||||
The base class for expression root object for event is
|
||||
`EventSecurityExpressionRoot`. This provides access to a `Message`
|
||||
object which is passed around with eventing.
|
||||
|
||||
.Event expressions
|
||||
|===
|
||||
| Expression | Description
|
||||
|
||||
| `hasEvent(Object event)`
|
||||
| Returns `true` if the event matches given event.
|
||||
|
||||
|===
|
||||
|
||||
==== Transition Attributes
|
||||
Matching transition sources and targets, use prefixes
|
||||
_TRANSITION_SOURCE__ and _TRANSITION_TARGET__ respectively.
|
||||
`TRANSITION_SOURCE_` and `TRANSITION_TARGET_` respectively.
|
||||
|
||||
==== Transition Expressions
|
||||
For generic options for expressions, see _Spring Security_ docs. We
|
||||
inherit from `SecurityExpressionRoot` and options from there are
|
||||
available.
|
||||
The base class for expression root object for transition is
|
||||
`TransitionSecurityExpressionRoot`. This provides access to a
|
||||
`Transition`
|
||||
object which is passed around for transition changes.
|
||||
|
||||
.Transition expressions
|
||||
|===
|
||||
| Expression | Description
|
||||
|
||||
| `hasSource(Object source)`
|
||||
| Returns `true` if the transition source matches given source.
|
||||
|
||||
| `hasTarget(Object target)`
|
||||
| Returns `true` if the transition target matches given target.
|
||||
|
||||
|===
|
||||
|
||||
[[sm-security-details]]
|
||||
=== Understanding Security
|
||||
@@ -1212,14 +1312,17 @@ state machine. Not really something you'd need to know but it is
|
||||
always better to be transparent instead of hiding all the magic what
|
||||
happens behind a scenes.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Security only makes sense if _State Machine_ is executed in a wallet
|
||||
garden where user don't have direct access to the application thus
|
||||
could modify Spring Security's `SecurityContext` hold in a thread
|
||||
local. If user controls the jvm, then effectively there is no security
|
||||
at all.
|
||||
====
|
||||
|
||||
Integration point for security is done with a
|
||||
`StateMachineInterceptor` which is then added automatically into a
|
||||
<<sm-interceptor,_StateMachineInterceptor_>> which is then added automatically into a
|
||||
state machine if security is enabled. Specific class is a
|
||||
`StateMachineSecurityInterceptor` which intercepts events and
|
||||
transitions. This interceptor then consults Spring Security's
|
||||
|
||||
Reference in New Issue
Block a user