介绍
这是Spring Security官方文档的一段介绍,大概是讲Spring Security为基于Java开发的应用程序提供了全面的安全服务,建议我们结合Spring去使用,现在有很多身份验证都是通过第三方的,但是Spring Security提供了自己的一组身份验证特性。具体来说,Spring Security目前支持所有这些技术的身份验证集成;
运行原理
大概画了security的主要拦截器的流程图。
代码实现
-
添加依赖
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency>
-
yml配置
server: port: 80 spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/securite?useUnicode=true&characterEncoding=utf8 username: root password: 123 mybatis: configuration: map-underscore-to-camel-case: true
-
数据库
roles 表示角色,多个角色用“,”隔开,前缀是ROLE_。
-
实体类
@Data public class UserModel { private int id; private String name; private String password; private int age; private String address; private String roles; }
-
mapper层
@Mapper public interface UserMapper { @Select("select * from user where name = #{name}") UserModel getUserByName(String name); }
-
service 层
@Service public class UserService { @Autowired private UserMapper userMapper; public UserModel getUserByName(String name) { return userMapper.getUserByName(name); } }
-
UserDetailsService具体实现(这里就是具体校验过程)
@Service public class MyUserDetailsService implements UserDetailsService { @Autowired private UserService userService; @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { UserModel userModel = userService.getUserByName(s); if (userModel == null) { throw new UsernameNotFoundException("用户不存在"); } return new User(userModel.getName(), userModel.getPassword(), createAuthority(userModel.getRoles())); } //这里是将数据库的角色分割,构造GrantedAuthority private List<SimpleGrantedAuthority> createAuthority(String roles) { String[] roleArray = roles.split(","); List<SimpleGrantedAuthority> authorityList = new ArrayList<>(); for (String role : roleArray) { authorityList.add(new SimpleGrantedAuthority(role)); } return authorityList; } }
-
拦截规则设置
@EnableWebSecurity @Configuration public class MyWebSecuriteConfig extends WebSecurityConfigurerAdapter { @Autowired private MyUserDetailsService myUserDetailsService; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests()//拦截 .antMatchers("/", "/home").permitAll()//允许/、/home的访问 .antMatchers("/user/**").hasAnyRole("USER")//用户USER角色的用户访问有关/user下面的所有 .antMatchers("/admin/**").hasAnyRole("ADMIN")//同上 .anyRequest().authenticated()//其它所有访问都拦截 .and() .formLogin()//添加登陆 .loginPage("/login").permitAll()//登陆页面“/login"允许访问 .defaultSuccessUrl("/buy")//成功默认跳转/buy .permitAll() .and() .logout().logoutUrl("/logout") .logoutSuccessUrl("/login") .permitAll();//同上 } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(myUserDetailsService);//添加实现的UserDetailsService } }
-
controller
@Configuration public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("home"); registry.addViewController("/home").setViewName("home"); registry.addViewController("/login").setViewName("login"); registry.addViewController("/buy").setViewName("buy"); } }
页面就不贴出来了,请看源码