Introduction to the Spring security Rights Management framework
Spring Security provides comprehensive security services for enterprise application software based on Java EE. Special emphasis is placed on projects that support the use of Spring framework artifacts, the spring framework is the leader in enterprise software development Java EE solutions. If you haven't used spring to develop an enterprise application, we warmly encourage you to take a closer look. Familiarity with spring, especially the injection principle, helps you use spring Security faster and more easily.
There are many reasons why people use spring secruity, and most of them have found that Java EE's servlet specification or security features in the EJB specification lack the depth required for typical enterprise scenarios. When referring to these specifications, it is important to recognize that they are not portable at the war or ear level. So if you change the server environment, there is typically a lot of work to reconfigure your application programmer security to the new target environment. Using spring security solves these problems and provides you with many other useful, customizable security features.
As you may know, the two main areas of the two applications are "authentication" and "Authorization" (or access control). These two main areas are the two targets of spring Security. "Authentication" is the process of establishing a subject that he declares (a "subject" generally refers to a user, device, or other system that can perform actions in your application). "Authorization" refers to the process of determining whether a principal allows an action to be performed in your application. In order to reach the need for authorization, the identity of the subject has been established by the certification process. This concept is generic and not just in spring security.
Spring Security's main component diagram:
At the authentication layer, Spring Security supports a variety of authentication modes. Most of these validations are either provided by third parties or developed by relevant standards organizations such as the Internet Engineering Task Force. Spring Security also provides its own set of authentication features. Specifically, Spring Security currently supports all of these technology-integrated authentication:
- HTTP BASIC Authentication Header (based on IETF rfc-based standard)
- HTTP Digest Authentication Header (IETF rfc-based standard)
- HTTP/Client certificate Exchange (IETF rfc-based standard)
- LDAP (a very common way to cross-platform authentication needs, especially in large environments)
- Form-based authentication (for a simple user interface)
- OpenID Certification
- Authentication based on pre-established request headers (such as computer Associates Siteminder) validated against pre-established request
- Ja-sig Central authentication Service (CAS, an open-source SSO system)
- Transparent authentication context propagation for remote Method invocation (RMI) and Httpinvoker (Spring Remote Protocol)
- Automatic "Remember-me" Authentication (you can check a box to avoid re-certification for a predetermined time period)
- Anonymous authentication (Let every unauthenticated access automatically assume a specific security identity)
- Run-as Authentication (useful when an access should use a different security identity)
- Java Authentication and Authorization Service (JAAS)
- JEE Container autentication (so if you want to be able to use container-managed certifications)
- Kerberos
- Java Open Source Single Sign On (Josso) *
- OpenNMS Network Management Platform *
- AppFuse *
- ANDROMDA *
- Mule ESB *
- Direct Web Request (DWR) *
- Grails *
- Tapestry *
- Jtrac *
- Jasypt *
- Roller *
- Elastic Path *
- Atlassian Crowd *
- Your own authentication systems (see below)
The official document address for Spring security5.x is as follows:
https://docs.spring.io/spring-security/site/docs/5.0.7.RELEASE/reference/htmlsingle/
https://docs.spring.io/spring-security/site/docs/5.0.7.RELEASE/api/
11 rights interceptors commonly used by Spring security
Securitycontextpersistencefilter:
- This filter is located at the top and is the first filter to work
- Verify that the user session exists, exists in Securitycontextholder, does not exist, and is created into Securitycontextholder
- Another function is to empty the contents of the Securitycontextholder after the filter has been executed.
Logoutfilter:
- Clears the user's session and the contents of the Securitycontextholder when the user issues a logout request
Abstractauthenticationprocessingfilter:
- Filter to process from form login
Defaultloginpagegeneratingfilter:
- Used to generate a default login page
Basicauthenticationfilter:
Securitycontextholderawarerequestfilter:
- Request to wrap a user
- The purpose is to provide some additional data for subsequent programs.
Remembermeauthenticationfilter:
- When the rememberme tag is present in the user's cookie, the user login is automatically implemented according to the tag, and the SecurityContext is created to grant the appropriate permissions
Anonymousauthenticationfilter:
- Ensure the unity of operation, when the user is not logged in, the default is to assign the user permissions to anonymous users, you can choose to turn off anonymous users
Exceptiontranslationfilter:
- Handles the exception thrown in the Filtersecurityinterceptor, then redirects the request to the appropriate page, or responds with an error message. That is, as a filter that handles global exceptions
Sessionmanagementfilter:
- Used to defend the session forgery XXX, will destroy the user's session, and regenerate a session
Filtersecurityinterceptor:
- The user's permission control is included here
- If the user does not log in, it throws the user's non-logged exception
- If the user is logged in but does not have access to the current resource, an Access denied exception is thrown
- If the user is logged in and has permission to access the current resource, the release
These are the 11 rights interceptors commonly used by spring security, so what is the order in which these interceptors are executed? This requires a first look at the Filterchainproxy filter chain proxy class:
- Filterchainproxy can invoke a set of filter in the order specified, so that this set of filter can not only do the verification authorization of the work, but also enjoy the functions of the spring IOC, to easily get other dependent resources
Rapid construction of springsecurity environment based on Springboot
Open idea and create a Springboot project:
Tick the appropriate module:
Create a new config package in the project, under which the Springsecurityconfig configuration class is created to configure the spring security interception rules. The code is as follows:
Package Org.zero.security.securitydemo.config;import Org.springframework.context.annotation.configuration;import Org.springframework.security.config.annotation.web.builders.httpsecurity;import Org.springframework.security.config.annotation.web.builders.websecurity;import Org.springframework.security.config.annotation.web.configuration.enablewebsecurity;import org.springframework.security.config.annotation.web.configuration.websecurityconfigureradapter;/** * @program: Security-demo * @description: Spring Security Configuration class * @author: 2018-08-29 * @create: 23:20 **/@Configuration @enablewebsec Uritypublic class Springsecurityconfig extends Websecurityconfigureradapter {@Override protected void Configure (HTT Psecurity http) throws Exception {//define a simple access Rule http.authorizerequests (). Antmatchers ("/"). Permitall ()//allow arbitrary access to the root path. Anyrequest (). Authenticated ()///root path requests require authentication. and (). Logout (). P Ermitall ()//allow arbitrary access to the logoff path . and (). Formlogin (); Allow form login//disable default CSRF authentication http.csrf (). disable (); } @Override public void Configure (Websecurity Web) throws Exception {//does not intercept access web.ignoring () for static resources. Ant Matchers ("/js/**", "/css/**", "/images/**"); }}
Then create a new controller package that creates the Democontroller director class in the package to open some interfaces for testing. The code is as follows:
package org.zero.security.securitydemo.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;/** * @program: security-demo * @description: spring security demo * @author: 01 * @create: 2018-08-29 23:14 **/@RestControllerpublic class DemoController { @GetMapping("/") public String demo(){ return "Hello Spring Security"; } @GetMapping("/hello") public String hello(){ return "Hello World"; }}
Start the project, access the root directory, and properly output the appropriate string:
and access /hello
, will jump to the login page, need to verify, this represents the configuration of springsecurity:
Case real operation based on Springsecurity Rights management
CASE1, simple login:
Springsecurity comes with a set of memory-based validations, so that when we need to implement simple login functionality, we don't need to create additional databases. In the Springsecurityconfig class, add the following methods:
@Configuration@EnableWebSecuritypublic class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication(). // 使用基于内存的认证方式 passwordEncoder(new BCryptPasswordEncoder()). // 设置密码的加密方式 withUser("admin"). // 设置用户名称 password(new BCryptPasswordEncoder().encode("123456")). // 设置密码 roles("ADMIN"); // 自定义该用户的角色 } ...}
Restart the project, when access to the controlled resources, will jump to the following login page, enter a set user name and password:
Access success:
Access the logout interface to log out:
CASE2, has the specified role, each role has the specified permissions:
Even with simple logins, you may experience some resources that require administrator roles to access. So let's see how to restrict a resource to be accessed only by administrator users. In the Configure method, add an ordinary user with the following code:
@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication(). passwordEncoder(new BCryptPasswordEncoder()). withUser("admin"). password(new BCryptPasswordEncoder().encode("123456")). roles("ADMIN"); auth.inMemoryAuthentication(). passwordEncoder(new BCryptPasswordEncoder()). withUser("user"). password(new BCryptPasswordEncoder().encode("user")). roles("USER");}
Add an interface to the Democontroller class and specify that the interface is accessible only to users of the admin role. The code is as follows:
@RestController// 开启验证@EnableGlobalMethodSecurity(prePostEnabled = true)public class DemoController { // 指定该接口只能被ADMIN角色的用户访问,ROLE_这个前缀是固定要写的 @PreAuthorize("hasRole(‘ROLE_ADMIN‘)") @GetMapping("/roleAuth") public String role(){ return "admin auth"; } ...}
To restart the project, log in to a user who is not in the admin role:
Accessing the Roleauth interface will return a 403 error:
Login Admin user, Access Roleauth interface successfully:
Expressions in the @PreAuthorize can use an operator such as and, or, for example:
@PreAuthorize("hasRole(‘ROLE_ADMIN‘) or hasRole(‘ROLE_ROOT‘)")
In addition to @preauthorize annotations, there are:
- @PostAuthorize: Perform role validation after the method finishes
- @PreFilter: Validation before method execution to filter parameters or return values of a collection type
- @PostFilter: Validation after method execution to filter the parameter or return value of the collection type
CASE3, custom password encryption:
We can customize our own encryption method to encrypt and match the password, I use MD5 as a demonstration here. First create a Mypasswordencoder class and implement the Passwordencoder interface. The specific code is as follows:
package org.zero.security.securitydemo.encoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.util.DigestUtils;/** * @program: security-demo * @description: 自定义密码加密器 * @author: 01 * @create: 2018-09-07 21:43 **/public class MyPasswordEncoder implements PasswordEncoder { @Override public String encode(CharSequence charSequence) { // 使用Spring自带的工具进行MD5加密 return DigestUtils.md5DigestAsHex(charSequence.toString().getBytes()); } @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { // 验证密码加密后是否一致 return encode(rawPassword).equals(encodedPassword); }}
Using our own custom password cipher, the code for modifying the Configure method is as follows:
@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication(). passwordEncoder(new MyPasswordEncoder()). withUser("admin"). password(new MyPasswordEncoder().encode("123456")). roles("ADMIN"); auth.inMemoryAuthentication(). passwordEncoder(new MyPasswordEncoder()). withUser("user"). password(new MyPasswordEncoder().encode("user")). roles("USER");}
Case4, parameter verification:
With @PreAuthorize
annotations, we can verify the permission parameters before the method executes. For example, I want to verify that the ID is less, and the value of the username parameter is the same as the user name currently logged in. The code is as follows:
@PreAuthorize("#id<10 and principal.username.equals(#username)")@GetMapping("/check_info")public String checkInfo(Integer id, String username) { return "success";}
If the parameter is an object it can also be verified, the code is as follows:
@PreAuthorize("#user.username.equals(‘admin‘)")@GetMapping("/check_user")public String checkUser(User user) { return "success";}
Summarize
Advantages:
- Provides a set of security frameworks, and this framework is available
- Provide a lot of user authentication function, realize the related interface, save a lot of development work
- Based on spring, it makes it easy to integrate into spring projects and encapsulates many methods
Disadvantages:
- More profiles, roles are "encoded" into configuration files or source files, RBAC is not obvious
- No operational interface for the relationship between users, roles, and permissions in the system
- In case of large data volume, it is almost unusable
Spring Security Authority framework theory and simple case