SpringSecurity
Spring Security integrates spring technology stack, provides the overall security solution of Java EE application, and provides comprehensive security services. Spring Security supports a wide range of authentication models
Module division
Core - spring-security-core.jar |
Core modules: core authentication, authorization, JDBC user support, independent Spring application support |
Remoting - spring-security-remoting.jar |
Remote interaction module: generally not required, you can use Spring Remoting function to simplify remote client interaction |
Web - spring-security-web.jar |
web security module: web project use, access control based on URL |
Config - spring-security-config.jar |
java configuration module: must rely on package, including parsing xml and java annotation to use spring security function |
LDAP - spring-security-ldap.jar |
LDAP (Lightweight Directory Access Protocol) support module: optional dependency package, LDAP function support |
ACL - spring-security-acl.jar |
ACL support: ACL (access control list) access control list. Fine grained resource access control (RBAC+ACL) |
CAS - spring-security-cas.jar |
CAS integration support: CAS (Central Authentication Service) Central Authentication Service. Open source ApereoCAS integration |
OpenID - spring-security-openid.jar |
OpenID authentication method: used to authenticate users against external servers (wechat, Sina Weibo third party login) |
Test - spring-security-test.jar |
Test module: fast test of spring security application |
Maven based Web engineering example
Add security POM dependency
<!-- In the security framework jar package --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>4.2.10.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>4.2.10.RELEASE</version> </dependency> <!-- Tag library --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>4.2.10.RELEASE</version> </dependency>
Add spring security Filter to web.xml for security control
<!-- Core controller, pay attention to spring and springmvc Configuration files are created by Web Container loading --> <servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:/spring/springmvc.xml classpath*:/spring/spring-*.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!--Agent management all SpringSecurity Filter--> <filter> <filter-name>springSecurityFilterChain</filter-name><!--Name fixing,Can not change--> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Spring security configuration class
/** * @Configuration Components in hypervisor (scan) * @EnableWebSecurity Formal basic annotation of security framework support annotation
* @EnableGlobalMethodSecurity Turn on using expression methods to verify security */ @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class AppWebSecurityConfig extends WebSecurityConfigurerAdapter { @Override //Authentication protected void configure(AuthenticationManagerBuilder auth) throws Exception { } @Override //To grant authorization protected void configure(HttpSecurity http) throws Exception { } }
Check the source code of the login page, and there is a tag < input type = "hidden" name = "${65374; CSRF. Parametername}" value = "${ᦉ CSRF. Token}" / > this is spring security to help us prevent "Cross Site Request Forgery" attack; it can also prevent the form from submitting repeatedly. This tag value dynamically generates a token value that verifies the correctness of the token value when a user requests to log in. If you want to disable this function, you can set http.csrf().disable();
l. token value change:
n. if the login is successful (the user name and password are correct), the token will be deleted,
n. return to the login page or the back page, and the token will be regenerated;
n. if the login fails (wrong user name and password), the token does not change.
n. refresh the login page, and the token value does not change
Authentication
@Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //Query data from database auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder()); }
UserDetailsService
This interface is called by Security to check the permission based on AOP mode, and returns a UserDetails interface type, which stores all the permission information queried by the user from the database
Steps:
1. Implement the UserDetailsService interface in the business layer to query the user object from the Dao layer through the user name
2. Create a set of HashSet < GrantedAuthority > interface type. The GrantedAuthority type is used to store role and permission information. Its implementation class simplegratedauthority needs to pass in string type role name and permission name
3. Query the role set owned by the user through the user id
4. Query the permission set owned by the user through the user id
5 create a simplegratedauthority object with all role names and ownership restrictions and add it to the HashSet < grantedauthority > Set
6. Create a user class object, which implements the UserDetails interface. For this user object, pass in the user name and password of the user plus the permission Set and return the object
@Autowired //user private TAdminMapper adminMapper; @Autowired //role private TRoleMapper roleMapper; @Autowired //Jurisdiction private TPermissionMapper permissionMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { TAdminExample example = new TAdminExample(); TAdminExample.Criteria criteria = example.createCriteria(); criteria.andLoginacctEqualTo(username); List<TAdmin> admins = adminMapper.selectByExample(example); //Find the user from the database TAdmin admin = admins.get(0); //This collection is used to store roles and permissions HashSet<GrantedAuthority> authorities = new HashSet<>(); //Find out the corresponding role of the user from the database List<TRole> roles = roleMapper.listRole(admin.getId()); //Find out the corresponding permissions of the user from the database List<TPermission> permissions = permissionMapper.listPermission(admin.getId()); //Add roles and permissions to authorities Collection for (TRole role : roles) { String name = role.getName(); authorities.add(new SimpleGrantedAuthority("ROLE_" + name));//Note that roles need to be added "ROLE_" } permissions.forEach((p) -> { String name = p.getName(); authorities.add(new SimpleGrantedAuthority(name)); }); //Created from this user name and password and permission collection User Object and return User user = new User(admin.getLoginacct().toString(), admin.getUserpswd().toString(), authorities); return user; }
To grant authorization
HttpSecurity This class allows configuration of specific http requests based on security considerations. By default, it applies to all requests. It also applies to http method Configure fine access control for users
@Override protected void configure(HttpSecurity http) throws Exception { //Be based on httpRequest Specify antMatchers Resources permitAll Release,For other requests anyRequest Must be certified authenticated http.authorizeRequests().antMatchers("/welcome.jsp","/static/**") .permitAll().anyRequest().authenticated(); //Jump to the default login interface http.formLogin().loginPage("/welcome.jsp"); //Controller specified at login/login,And verify the user name and password,Jump to controller after successful verification/main http.formLogin().loginProcessingUrl("/login") .usernameParameter("loginacct") .passwordParameter("userpswd") .defaultSuccessUrl("/main"); //cancel csrf Token value validation http.csrf().disable(); //Controller specified on exit,And specify the login interface after successful exit http.logout().logoutUrl("/exit").logoutSuccessUrl("/welcome.jsp"); //Remember my function.To be specified in the front check box value The value is remember-me http.rememberMe(); //Custom exception handler http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { //Determine whether it is an asynchronous request if("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){ response.getWriter().write("403"); }else { request.setAttribute("msg",accessDeniedException.getMessage()); request.getRequestDispatcher("/WEB-INF/views/unauth.jsp") .forward(request,response); } } }); }
Access control can be more refined through method calls
authorizeRequests(): returns a configuration object to configure the access restrictions of the request
formLogin(): returns the form configuration object. When nothing is specified, a default is provided, such as configure login request and login success page
logout(): returns the logout configuration object. You can set the exit url through logoutUrl
Ant matchers: match the request path or request action type, such as. Ant matchers ("/ admin / *")
addFilterBefore: add a filter before a filter
addFilterAfter: add a filter after a filter
addFilterAt: adding a filter in the same location of a filter will not overwrite the filter in the same location
hasRole: used in combination with ant matchers to set the role permission or IP that the request is allowed to access
Method name |
purpose |
access(String) |
Can be accessed when the result of SpringEL expression is true |
anonymous() |
Anonymous accessible |
denyAll() |
User not accessible |
fullyAuthenticated() |
User fully authenticated access (automatic login under non remember me) |
hasAnyAuthority(String...) |
Any permission in the parameter can be accessed |
hasAnyRole(String...) |
Any role in the parameter can be accessed |
hasAuthority(String) |
Users with a certain permission can access |
hasRole(String) |
Users of a role can access |
permitAll() |
Accessible to all users |
rememberMe() |
Allow users logged in through remember me to access |
authenticated() |
User can access after login |
hasIpAddress(String) |
The user can access the IP from the parameter |
@Details of EnableGlobalMethodSecurity
@ enableglobalmethodsecurity (secureenabled = true) enable @ Secured annotation filtering permission
@ Secured("software engineer"): have the specified role to access the method
@ EnableGlobalMethodSecurity(jsr250Enabled=true) enable @ RolesAllowed annotation filtering permission
@ EnableGlobalMethodSecurity(prePostEnabled=true) use SpEL Expression method level security 4 annotations available
@PreAuthorize checks before method execution, and restricts access to the method based on expression evaluation results / / @ PreAuthorize("hasRole('software engineer ')")
@PostAuthorize checks after method execution, but if the expression evaluates to false, a security exception is thrown
@PostFilter allows method calls, but must filter the results of the method by expression
@PreFilter allows method calls, but you must filter the input values before entering the method
Security tab
In jsp page, you can further control the access right of html tag or obtain the user information through tag: import tag library
<%@taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> <sec:authentication property="name"/> //Display the user login name in the required location, and the property must be name <sec:authorize access="hasRole('PM - project manager')">//Users who are not in this role hide the following tags <button type="button" id="deleteBath" class="btn btn-danger" style="float:right;margin-left:10px;">delete</button> </sec:authorize>