目录
springSecurityConfig类configure方法
入门案例
springSecurity安全主要用于登录
1.导入所需的依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
2.编写一个controller
package com.hang.demo2.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/Test") public class TestController { @GetMapping("add") public String add(){ return "hello security"; } }
运行后就会出现登录页面
账号默认是:user
密码会打印在控制台
修改默认的账号密码
修改默认账号后密码不会打印在控制台了
通过配置文件修改
spring.security.user.name=hang spring.security.user.password=123456
编写类实现接口
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception{ BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); // 给密码加密 String password = passwordEncoder.encode("123"); auth.inMemoryAuthentication().withUser("hang").password(password).roles("admin"); } @Bean PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } }
.inMemoryAuthentication: 给这个账号存到内存当中去
.withUser("hang"):设置用户名
.password(password):设置密码
.roles("admin"):设置角色
自定义编写实现类
package com.hang.demo2.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration public class SecurityConfigTest extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception{ auth.userDetailsService(userDetailsService).passwordEncoder(password()); } @Bean PasswordEncoder password(){ return new BCryptPasswordEncoder(); } }
继承WebSecurityConfigurerAdapter类 并且实现其方法configure
package com.hang.demo2.service; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; 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.List; @Service(value = "userDetailsService") public class MyUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role"); return new User("hang",new BCryptPasswordEncoder().encode("123"),auths); } }
这里service的值一定要和SecurityConfigTest类里面的UserDetailsService 变量名一致 要不然会注入不进去
auths不能为空 可以随便写一个
mybaits-plus整合security
1.导入所需的依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 连接数据库依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- mybatis-plus依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency> <!-- Lombok依赖 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- security依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2.编写连接数据库配置文件
#spring.security.user.name=hang #spring.security.user.password=123456 spring.datasource.url=jdbc:mysql://localhost:3306/sys?serverTimezone=GMT spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver mybatis-plus.global-config.banner=false
3.编写实体类
package com.hang.demo2.pojo; import lombok.Data; @Data public class Users { private long id; private String username; private String password; }
4.编写security工具类
package com.hang.demo2.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration public class SecurityConfigTest extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception{ auth.userDetailsService(userDetailsService).passwordEncoder(password()); } @Bean PasswordEncoder password(){ return new BCryptPasswordEncoder(); } }
4.编写连接数据库的类
package com.hang.demo2.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import com.hang.demo2.pojo.*; @Mapper @Repository public interface UserMapper extends BaseMapper<Users> { }
5.编写mapper类
package com.hang.demo2.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import com.hang.demo2.pojo.*; @Mapper @Repository public interface UserMapper extends BaseMapper<Users> { }
因为运用到了mybatis-plus 所以说只需要继承BaseMapper这个类就行了
6.编写service类
package com.hang.demo2.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.hang.demo2.mapper.UserMapper; import com.hang.demo2.pojo.Users; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; 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.List; @Service(value = "userDetailsService") public class MyUserDetailsService implements UserDetailsService { @Autowired private UserMapper userMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { QueryWrapper<Users> queryWrapper = new QueryWrapper<>(); //给一个查询的条件 queryWrapper.eq("username",username); //selectOne查询一条数据 Users users = userMapper.selectOne(queryWrapper); System.out.println("users = " + users); if (users==null) { throw new UsernameNotFoundException("出错了"); } List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role"); return new User(username,new BCryptPasswordEncoder().encode(users.getPassword()),auths); } }
这里@Service的value一定要和security工具类UserDetailsService值一致
springSecurityConfig类configure方法
修改默认登录页面
在工具类里面(继承WebSecurityConfigurerAdapter的那个)
@Override protected void configure(HttpSecurity http) throws Exception { http.exceptionHandling().accessDeniedPage("/unAuth.html"); http.formLogin() //自定义编写的登录页面 .loginPage("/login.html") //登录页面的设置 .loginProcessingUrl("/user/login") //登录访问路径 .defaultSuccessUrl("/Test/index").permitAll() //登录成功后跳转的页面 .and().authorizeRequests() .antMatchers("/","/Test/add","/user/login").permitAll() //不需要登录也能访问的页面 // .antMatchers().hasAuthority("admin") //访问什么页面需要什么权限 hasAuthority 必须有这个 .antMatchers("/Test/hang").hasAnyAuthority("admin,hang") //访问这个页面需要什么权限 有其中一个即可 .anyRequest().authenticated() .and().csrf().disable(); //关闭csrf保护 }
设置权限
在工具类里面 config(HttpSecurity http)方法里面
//访问什么页面需要什么权限 hasAuthority 必须有这个 .antMatchers().hasAuthority("admin") .antMatchers("/Test/hang").hasAnyAuthority("admin,hang")
这段代码的意思是 进入/Test/Hang需要有admin或者是hang其中一个权限
在service类里面 以下代码就是给权限
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("hang"); return new User(username,new BCryptPasswordEncoder().encode(users.getPassword()),auths);
意思是给了一个hang的权限
注:如果访问没有权限的页面会显示403、
修改403页面
所以说我们可以优化页面 修改403时候显示的页面
http.exceptionHandling().accessDeniedPage("/unAuth.html");
使用注解实现给方法设置权限
@Secured({"zhang"}) @ResponseBody @GetMapping("zhang") public String zhang(){ return "hello zhang"; }
@Secured({"zhang"}) :意思是需要有张这个权限才能进入此方法
使用之前 需要在启动方法上加注解
@EnableGlobalMethodSecurity(securedEnabled = true)
意思是开启springsecurity注解扫描
退出
http.logout().logoutUrl("/logout") .logoutSuccessUrl("/security.html").permitAll();
注:在点击退出的时候 跳转的路径也要是/logout,下面这个路径是退出后跳转的页面
securityConfig配置
package com.hang.demo2.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration public class SecurityConfigTest extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception{ auth.userDetailsService(userDetailsService).passwordEncoder(password()); } @Bean PasswordEncoder password(){ return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { // 退出的logout http.logout().logoutUrl("/logout") // 退出后去到哪个页面 .logoutSuccessUrl("/security.html").permitAll(); // 如果没有权限时候显示的页面403 http.exceptionHandling().accessDeniedPage("/unAuth.html"); http.formLogin() //自定义编写的登录页面 .loginPage("/login.html") //登录页面的设置 .loginProcessingUrl("/user/login") //登录访问路径 .defaultSuccessUrl("/Test/index").permitAll() //登录成功后跳转的页面 .and().authorizeRequests() .antMatchers("/","/Test/add","/user/login").permitAll() //不需要登录也能访问的页面 // .antMatchers().hasAuthority("admin") //访问什么页面需要什么权限 hasAuthority 必须有这个 .antMatchers("/Test/hang").hasAnyAuthority("admin,hang") //访问这个页面需要什么权限 有其中一个即可 .anyRequest().authenticated() .and().csrf().disable(); //关闭csrf保护 } }