#SpringBoot整合SpringSecurity一(入门出体验) ### SpringSecurity简介 SpringSecurity是基于Spring应用提供的声明式的安全保护性的框架,它可以在web请求级别的和方法调用级别处理身份和授权。他是基于AspectJ的切面进行配置的。 ### 创建SpringBoot项目 ####创建模块(这里选用gradle做项目的构建工具) ![1.jpg](imgs/1.jpg) ####选择项目依赖 ![2.jpg](imgs/2.jpg) ####自定义一个端口,然后运行项目 ```properties server.port=8888 ``` 直接运行会报如下错误: ```log Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2020-08-04 11:49:11.685 ERROR 1268 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLICATION FAILED TO START *************************** Description: Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine a suitable driver class Action: Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it on the classpath. If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active). ``` 这是由于我们导入了jpa的starter包,springboot有自动装配,需要注入datasource,为了节省时间,我们把内个依赖屏蔽掉,只需在@SpringBootApplication(exclued = '')配置即可 ```java @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})//这里是重点,不写的话你还得配置完数据库的设置才能启动 public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` 运行成功后我们注意控制台,有一串加密字符串,这是security生成的安全密码,在不做任何配置的情况下,需要用这个密码去登录,用户名为user ![3.jpg](imgs/3.jpg) 然后访问项目,会出现如下登录框。这个登录页面是security自动配置的,后期我们也可以替换掉它。至此,基本配置已经完成了。用户名为user 密码为控制台的加密字符串。 ![4.jpg](imgs/4.jpg) 也可以在配置文件自定义账号密码 ```properties spring.security.user.name=root spring.security.user.password=root ``` 写一个配置类,继承WebSecurityConfigurerAdapter,实现configure(AuthenticationManagerBuilder auth)方法,也可以配置登录账户,代码如下: ```java @Configuration public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //可以配置多个 用户1 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())//申明加密的方式(不加密访问会报错) .withUser("root")//用户名 .password(new BCryptPasswordEncoder().encode("123456"))//密码 .roles();//角色,一会儿会讲 //用户二 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())//申明加密的方式(不加密访问会报错) .withUser("admin")//用户名 .password(new BCryptPasswordEncoder().encode("123456"))//密码 .roles();//角色,一会儿会讲 } } ``` 定义一个controller方法,设置请求的角色 ```java @RestController public class PageController { @GetMapping("/index") @PreAuthorize("hasAnyRole('admin')") public String index(){ return "index请求成功"; } } ``` 给用户设置角色,@EnableGlobalMethodSecurity注解很关键,如果不配置,则不生效 ```java @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true)//开启方法 认证 public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //可以配置多个 用户1 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())//申明加密的方式(不加密访问会报错) .withUser("admin")//用户名 .password(new BCryptPasswordEncoder().encode("123456"))//密码 .roles("admin"); } } ``` 如果没有admin的角色,就会显示如下页面: ![5.jpg](imgs/5.jpg) 接下来设置通过数据库账号密码登录 ```java @Component//配置到容器里面 public class MyUserDetails implements UserDetailsService { private final UserService userService; private final PasswordEncoder passwordEncoder; public MyUserDetails(UserService userService,PasswordEncoder passwordEncoder) { this.userService = userService; this.passwordEncoder = passwordEncoder; } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { System.out.println(username); ArrayList<GrantedAuthority> authorities = new ArrayList<>(); authorities.add(new SimpleGrantedAuthority("ROLE_"+"admin"));//把角色添加进去******~~~~__````__~~~~****** User user = userService.findByUsername(username);//去数据库里面查询 if (StringUtils.isEmpty(user)){ throw new UsernameNotFoundException("用户不存在"); } org.springframework.security.core.userdetails.User userdetails = new org.springframework.security.core.userdetails.User(user.getUsername(),passwordEncoder.encode(user.getPassword()),authorities); return userdetails; } } ```