Directory
1.1 Permissions
1.2 Pre-call processing
1.2.1 Accessdecisionmanager
1.2.2 Voting-based Accessdecisionmanager implementation
1.3 Post-call processing
1.4 Inheritance of roles
1.1 Permissions
All authentication implementation classes hold a list of grantedauthority that represent the permissions that the user has. Grantedauthority is set to the authentication object by AuthenticationManager, Accessdecisionmanager then obtains the user's grantedauthority from the authentication to authenticate the user's access to the corresponding resource.
Grantedauthority is an interface that defines only a getauthority () method with a return value of type string. This method allows Accessdecisionmanager to obtain a string that accurately represents the permission. By returning a string, a grantedauthority can easily be read by most Accessdecisionmanager. If a grantedauthority cannot be represented exactly by a string, then its corresponding getauthority () method call should return a null, This means that Accessdecisionmanager must have specific support for the implementation of the grantedauthority, so that the permission information represented by the grantedauthority can be obtained.
Spring Security has built-in a grantedauthority implementation, simplegrantedauthority. It directly receives a string that represents the permission information, and then the Getauthority () method returns the string directly. All the Authenticationprovider built into Spring security use it to encapsulate authentication objects.
1.2 Pre-call processing
Spring security uses interceptors to control access to protected objects, such as method calls and Web requests. Before formally accessing the protected object, Spring security uses Accessdecisionmanager to authenticate whether the current user has access to the corresponding protected object.
1.2.1AccessDecisionManager
Accessdecisionmanager is called by Abstractsecurityinterceptor, which is responsible for authenticating the user's access to the corresponding resource (method or URL). Accessdecisionmanager is an interface that defines only three methods, which are defined as follows.
Public Interface Accessdecisionmanager {
/**
* Pass parameters to determine whether the user has access to the corresponding protected object
*
* @param Authentication is currently requesting the authentication of the containing object
* @param object protected, which can be a methodinvocation, joinpoint, or filterinvocation.
* @param configattributes The configuration properties associated with the protected object being requested
*
*/
void Decide (authentication authentication, Object object, collection<configattribute> Configattributes)
throws Accessdeniedexception, insufficientauthenticationexception;
/**
* Indicates whether the current Accessdecisionmanager supports the corresponding Configattribute
*/
Boolean supports (Configattribute attribute);
/**
* Indicates whether the current Accessdecisionmanager supports the corresponding protected object type
*/
Boolean supports (class<?> clazz);
}
The decide () method is used to determine whether the authentication conforms to the configattributes required by the protected object. The supports (Configattribute attribute) method is used to determine whether Accessdecisionmanager can handle the corresponding configattribute. The Supports (class<?> Clazz) method is used to determine whether the configured Accessdecisionmanager supports the corresponding protected object type.
1.2.2 Voting-based Accessdecisionmanager implementation
Spring Security has built in several voting-based Accessdecisionmanager, but you can also implement your own accessdecisionmanager if needed. The following is a diagram provided by the spring security official documentation that shows classes related to voting-based Accessdecisionmanager implementations.
In this way, a series of accessdecisionvoter will be used by Accessdecisionmanager to vote on whether authentication has access to the protected object, Then decide whether or not to throw accessdeniedexception according to the poll results. Accessdecisionvoter is an interface in which there are three methods defined, as shown in the following structure.
Public Interface accessdecisionvoter<s> {
int access_granted = 1;
int Access_abstain = 0;
int access_denied =-1;
Boolean supports (Configattribute attribute);
Boolean supports (class<?> clazz);
int vote (authentication authentication, S object, collection<configattribute> attributes);
}
The return result of the vote () method is one of the three constants defined in Accessdecisionvoter. Access_granted agreed, Access_denied said return, Access_abstain said to abstain. If a accessdecisionvoter cannot determine whether the current authentication has permission to access the corresponding protected object, the return value of its vote () method should be a waiver access_abstain.
Spring Security has built in three voting-based Accessdecisionmanager implementation classes, which are affirmativebased, consensusbased, and unanimousbased, respectively.
The logic of affirmativebased is this:
(1) As long as there is a accessdecisionvoter vote for access_granted consent to the user to visit;
(2) If all abstention is also expressed through;
(3) If no one voted in favour of the vote, but someone voted against it, the accessdeniedexception would be thrown.
The logic of consensusbased is this:
(1) If the affirmative vote is more than the negative vote, it will be passed.
(2) Conversely, Accessdeniedexception will be thrown if the negative vote is more than the affirmative vote.
(3) If the affirmative vote is the same as the negative and not equal to 0, and the value of the attribute allowifequalgranteddenieddecisions is true, it is passed, otherwise an exception accessdeniedexception will be thrown. The value of parameter allowifequalgranteddenieddecisions defaults to True.
(4) If all Accessdecisionvoter are abstained, the value of the parameter allowifallabstaindecisions will be determined, if true the value is passed, Otherwise, an exception accessdeniedexception will be thrown. The value of parameter allowifallabstaindecisions defaults to False.
unanimousbased 's logic is a bit different from the other two implementations, and the other two will pass all the configuration properties of the protected object to Accessdecisionvoter for a single vote. And unanimousbased will only pass one configattribute at a time to vote for Accessdecisionvoter. This means that if the logic of our accessdecisionvoter is that only one of the configattribute that is passed in will be able to match the vote, but putting it in the unanimousbased will not necessarily be in favor. The logic of unanimousbased is, in particular,:
(1) If one of the Configattribute configured by the protected object is objected to by an arbitrary accessdecisionvoter, the accessdeniedexception will be thrown.
(2) If there is no negative vote, but there is an affirmative vote, it will be adopted.
(3) If all abstentions, the value of the parameter allowifallabstaindecisions will be determined, true passes, false throws accessdeniedexception.
1.2.2.1RoleVoter
Rolevoter is a accessdecisionvoter built into spring security that will configattribute simply as a role name and vote in favor of the role if it is voted. If the Configattribute begins with "Role_", the Rolevoter will be used to vote. When a user has a permission that has one or more configattribute that can match the configuration of the protected object, it will vote in favor of the Role_, if the user has no permissions to match the protected object configuration to "Role_" At the beginning of the Configattribute, Rolevoter will vote against it, and Rolevoter will abstain if the protected object is configured with a configattribute that does not begin with "Role_".
1.2.2.2AuthenticatedVoter
Authenticatedvoter is also a accessdecisionvoter implementation built into Spring security. It is primarily used to differentiate between anonymous users, Remember-me authenticated users, and fully authenticated users. A fully authenticated user is a user who is successfully logged in and authenticated by a system-provided login portal.
The configattribute that Authenticatedvoter can handle are is_authenticated_fully, is_authenticated_remembered, and Is_authenticated_. Anonymously. If the configattribute is not within the scope of these three, then Authenticatedvoter will abstain. Otherwise, depending on the Configattribute, if the Configattribute is is_authenticated_anonymously, then whether the user is anonymous or has been authenticated will vote in favour; if it is Is_ Authenticated_remembered will only vote in favour if the user is automatically logged in by Remember-me, or is logged in through the login portal, otherwise it will vote no, and when Configattribute is Is_ Authenticated_fully only if the user is logged in through the login portal will vote in favour of the vote, or will vote against.
Authenticatedvoter is through Authenticationtrustresolver's isanonymous () method and Isrememberme () method to determine whether the authentication held by Securitycontextholder is Anonymousauthenticationtoken or Remembermeauthenticationtoken, That is, is_authenticated_anonymously and is_authenticated_remembered.
1.2.2.3 Custom Voter
Of course, users can also implement their own voting logic by implementing accessdecisionvoter.
1.3 Post-call processing
Accessdecisionmanager is used to determine whether a user has permission to access a protected object before accessing it. Sometimes we might want to make some changes to the return value after the request has been completed, and of course, you can do this simply by using AOP. Spring Security provides us with a Afterinvocationmanager interface that allows us to modify the return value after the protected object has been accessed or to authenticate the permission to see if we need to throw accessdeniedexception. It will be called by the Abstractsecurityinterceptor subclass. The Afterinvocationmanager interface is defined as follows.
Public Interface Afterinvocationmanager {
Object Decide (Authentication authentication, Object object, collection<configattribute> attributes,
Object returnedobject) throws accessdeniedexception;
Boolean supports (Configattribute attribute);
Boolean supports (class<?> clazz);
}
The following is a diagram of the implementation of a Afterinvocationmanager construct provided by the spring security official documentation.
Similar to Authenticationmanager,afterinvocationmanager has a default implementation class Afterinvocationprovidermanager, which has a collection of Afterinvocationprovider, Afterinvocationprovider and Afterinvocationmanager have the same method definition, When you call a method in Afterinvocationprovidermanager, you actually call the method that contains the Afterinvocationprovider in turn.
It is important to note that Afterinvocationmanager needs to be executed after the protected object has been successfully accessed.
1.4 Inheritance of roles
This is also a common requirement for role inheritance, such as requiring role_admin to have all the Role_user permissions. Of course, we can grant the Role_user role to the user who has the role_admin role to achieve this effect or to modify the resources that need to be accessed Role_user role_admin can also be accessed. Spring Security provides us with a much simpler approach, which is the inheritance of roles, which allows our role_admin to inherit role_user directly so that all role_user accessible resources role_admin can be accessed. Defining the inheritance of roles we need to define a rolehierarchy in ApplicationContext, and then give it to a rolehierarchyvoter, Then add the Rolehierarchyvoter to our voter-based Accessdecisionmanager and specify the one that is currently used for our own definition of Accessdecisionmanager. The following is a complete example of defining role inheritance.
<beans xmlns="Http://www.springframework.org/schema/beans"
xmlns:security="Http://www.springframework.org/schema/security"
xmlns:xsi="Http://www.w3.org/2001/XMLSchema-instance"
xsi:schemalocation="Http://www.springframework.org/schema/beans
Http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
Http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd ">
<!--Specify the Accessdecisionmanager that will be used by access-decision-manager-ref
<security:http access-decision-manager-ref="Accessdecisionmanager">
<security:form-login/>
<security:intercept-url pattern="/admin.jsp" access="role_admin" />
<security:intercept-url pattern="/**" access="Role_user" />
</security:http>
<security:authentication-manager alias="AuthenticationManager">
<security:authentication-provider
user-service-ref="Userdetailsservice"/>
</security:authentication-manager>
<bean id="Userdetailsservice"
class="Org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="DataSource" ref="DataSource" />
</bean>
<!--define your own Accessdecisionmanager bean---
<bean id="Accessdecisionmanager" class= " Org.springframework.security.access.vote.AffirmativeBased ">
<property name="Decisionvoters">
<list>
<ref local="Rolevoter"/>
</list>
</property>
</bean>
<bean id="Rolevoter"
class="Org.springframework.security.access.vote.RoleHierarchyVoter">
<constructor-arg ref="Rolehierarchy" />
</bean>
<bean id="Rolehierarchy"
class="Org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy"><!--role Inheritance Relationship--
<value>
Role_admin > Role_user
</value>
</property>
</bean>
</beans>
In the above configuration we have defined that Role_admin is inherited from Role_user so that Role_admin will be able to access all the resources that Role_user can access. With the hierarchy property of Rolehierarchyimpl, we can define inheritance relationships among multiple roles, such as:
<bean id="Rolehierarchy"
class="Org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy"><!--role Inheritance Relationship--
<value>
Role_admin > Role_user
Role_a > Role_b
Role_b > Role_c
Role_c > Role_d
</value>
</property>
</bean>
In the above configuration we also defined Role_admin inherited Role_user,role_a inherited Role_b,role_b and inherited the Role_c,role_c and inherited Role_d, so role_a will be able to access Role_b, Role_ All resources that can be accessed by C and Role_d.
(Note: This article is written based on spring Security3.1.6)
Spring Security (15)--Authority authentication structure