本文最后更新于:February 4, 2022 pm
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转、依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
目录 1.写配置类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 package com.tothefor.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;@EnableWebSecurity public class SecutityConfigTest extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure (HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/" ).permitAll() .antMatchers("/div1/**" ).hasRole("div1" ) .antMatchers("/div2/**" ).hasRole("div2" ) .antMatchers("/div3/**" ).hasRole("div3" ); http.csrf().disable(); http.formLogin().loginPage("/toLogin" ).usernameParameter("user" ).passwordParameter("pwd" ); http.logout().logoutSuccessUrl("/" ); } @Override protected void configure (AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Bean PasswordEncoder passwordEncoder () { return new BCryptPasswordEncoder(); } }
2.实现UserDetailsService 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 package com.tothefor.service;import com.tothefor.dao.PersonMapper;import com.tothefor.entity.Person;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.AuthorityUtils;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.User;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.stereotype.Service;import java.util.ArrayList;import java.util.List;@Service("UserDetailsService") public class MyUserDetailsService implements UserDetailsService { @Autowired private PersonMapper personMapper; @Override public UserDetails loadUserByUsername (String username) throws UsernameNotFoundException { Person p = personMapper.queryByName(username); if (p==null ){ throw new UsernameNotFoundException("用户名不存在" ); } String urole = "admin" ; urole="ROLE_" +urole; GrantedAuthority g = new SimpleGrantedAuthority(urole); List<GrantedAuthority> auths = new ArrayList<>(); auths.add(g); return new User(p.getName(),new BCryptPasswordEncoder().encode(p.getPassword()),auths); } }
@Service(“UserDetailsService”)中的UserDetailsService是自己写的那个类,是实现了UserDetailsService接口的自定义类。
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());是根据提供的User对象(SpringSecurity中的)中的信息来进行验证。而这个User对象(SpringSecurity中的)的实现类是通过实现UserDetailsService接口实现的,该实现类中就返回了一个User对象(SpringSecurity中的)。
自定义的实现类中重新一个方法loadUserByUsername(String username),根据提供的用户名它去查出用户的具体信息,然后返回一个User对象(SpringSecurity中的User对象),这个User对象会携带着需要验证的信息去验证。
总结 总得来说分为两步。
还是和原来一样进行配置类的设置,即继承WebSecurityConfigurerAdapter类。只是原来是直接写死用户和密码、角色。现在就不写死,而是通过Security自带的一个User类进行验证。我们需要做的就是把信息放进User类中,然后把这个User对象进行验证。
编写MyUserDetailsService,是实现的UserDetailsService接口。重写一个方法,此方法可以通过前端获取的用户名进行查询,然后把信息封装成一个User对象返回。
获取当前登录用户信息 此方法与Security无关,只是记录一下有这种方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package com.tothefor.controller;import org.springframework.security.core.Authentication;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import javax.servlet.http.HttpServletRequest;@Controller public class TestGet { @GetMapping("/testGet") public void getT (HttpServletRequest request) { System.out.println(request.getClass()); System.out.println("当前用户名 " +request.getRemoteUser()); System.out.println("当前用户是否具有某个角色 " + request.isUserInRole("admin" )); Authentication auth = (Authentication) request.getUserPrincipal(); System.out.println("用户对象 " +request.getUserPrincipal()); System.out.println("用户名 " +auth.getName()); System.out.println("用户权限 " +auth.getAuthorities()); } }