首先先建立一个Spring Boot项目:
添加Spring Security配置:
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
添加配置文件:
/**
* Created with IntelliJ IDEA.
*
* @Auther: Source
* @Date: 2020/11/26/16:14
* @Description:
*/
@Configuration
@EnableWebSecurity //启动spring security过滤器链
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 该方法的作用就是代替之前的:<security:http>
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // 授权配置
.antMatchers("/**") //拦截的路劲,/**:拦截所有
.fullyAuthenticated() //反问方式
.and()
.formLogin(); //表单验证
}
}
从启项目就能看到控制台打印的密码,这个是自动生成加密后的密码
然后后打开网页:
就能进入一个Security自带的一个页面,然后输入user和刚才控制台打印的密码就可以登录了
自定义用户认证
修改Security配置文件:
@Configuration
//@EnableWebSecurity //启动spring security过滤器链
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// 自定义用户信息
@Override
@Bean
public UserDetailsService userDetailsService(){
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("root").password("123").authorities("ROLE_ALL").build());
manager.createUser(User.withUsername("admin").password("123").authorities("ROLE_ADD").build());
return manager;
}
@Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
// 该方法的作用就是代替之前的:<security:http>
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user/add").hasAnyAuthority("ROLE_ADD","ROLE_ALL")
.antMatchers("/user/delete").hasAnyAuthority("ROLE_ADD","ROLE_ALL")
.antMatchers("/user/update").hasAnyAuthority("ROLE_UPDATE","ROLE_ALL")
.antMatchers("/user/list").hasAnyAuthority("ROLE_LIST","ROLE_ALL")
.antMatchers("/user/**").hasAnyAuthority() //所有/user/**的请求必须通过验证
.anyRequest().permitAll() //出了/user/**,其他的可以访问
.and()
.formLogin()
.successForwardUrl("/login-success"); //自定义登录成功地址
}
}
添加处理成功Controller:
/**
* Created with IntelliJ IDEA.
*
* @Auther: Source
* @Date: 2020/11/26/19:16
* @Description:
*/
@Controller
public class loginInfo {
@RequestMapping("/login-success")
public String loginSuccess(){
return "/index";
}
}
添加列表访问Controller:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/add")
public String add(){
return "user/add";
}
@RequestMapping("/update")
public String update(){
return "user/update";
}
@RequestMapping("/delete")
public String delete(){
return "user/delete";
}
@RequestMapping("/list")
public String list(){
return "user/list";
}
}
添加完成后重新启动项目,访问项目,点击需要权限的页面,即可看到Security自带的登录页面
输入账号:root 密码:123
即可访问所有的页面
添加自定义异常处理
/**
* Created with IntelliJ IDEA.
*
* @Auther: Source
* @Date: 2020/11/26/19:48
* @Description: 自定义异常处理
*/
@Component
public class ErrorPageConfig implements ErrorPageRegistrar {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/401");
ErrorPage error403Page = new ErrorPage(HttpStatus.FORBIDDEN, "/403");
ErrorPage error405Page = new ErrorPage(HttpStatus.METHOD_NOT_ALLOWED, "/405");
ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404");
ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500");
registry.addErrorPages(error401Page,error405Page, error404Page, error500Page, error403Page);
}
}
在Controller添加请求:
@RequestMapping("/403")
public String FORBIDDEN(){
return "/403";
}
@RequestMapping("/404")
public String NOT_FOUND(){
return "/404";
}
@RequestMapping("/401")
public String UNAUTHORIZED(){
return "/401";
}
@RequestMapping("/500")
public String INTERNAL_SERVER_ERROR(){
return "/500";
}
@RequestMapping("/405")
public String METHOD_NOT_ALLOWED(){
return "/405";
}
自定了登录页面
...以上省略
.and()
.formLogin()
.loginPage("/login") //添加自定义登录页面
.successForwardUrl("/login-success") //自定义登录成功地址
.and()
.csrf().disable(); //关闭跨载的功能
添加图形验证码
之前有特意写到
添加持久层登录
在Dao中添加根据用户名查询所有用户接口和查询权限接口
public interface UserMapper extends Mapper<MyUser> {
@Select("select * from sys_user where username = #{username}")
MyUser findByUserName(String username);
}
public interface PermissionMapper extends Mapper<Permission> {
@Select("select permission.*\n" +
" from\n" +
" sys_user user\n" +
" inner join sys_user_role user_role on user.id = user_role.user_id\n" +
" inner join sys_role_permission role_permission on user_role.role_id = role_permission.role_id\n" +
" inner join sys_permission permission on role_permission.perm_id = \n" +
" where user.username = #{username};")
List<Permission> selectByUsername(String username);
}
创建MyUserDatilsService 实现Security的UserDatilsService的接口
@Service
public class MyUserDetailsService implements UserDetailsService {
private Logger logger = Logger.getLogger(MyUserDetailsService.class);
@Autowired
private UserService userService;
@Autowired
private PermissionService permissionService;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
("当前用户:" + s );
//根据用户名查询用户信息
MyUser myUser = userService.findUsername(s);
if(myUser!=null) {
//根据用户名查询当前用户所有权限
List<Permission> permissions = permissionService.selectByUserName(s);
//authorities:存放所有用户权限
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (Permission perm : permissions) {
GrantedAuthority authority = new SimpleGrantedAuthority(perm.getPermTag());
authorities.add(authority);
}
//把所有权限赋值给user
myUser.setAuthorities(authorities);
(myUser.toString());
}
// UserDetails user = User.withUsername("root").password("123").authorities("ROLE_ALL").build();
return myUser;
}
}
记得添加@Service的注解
然后再config中添加
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
将加密方式改成BCryptPasswordEncoder
添加remember-me记住密码
添加Bean
/**
* 注册remember-me接口
* @return
*/
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource);
// createTableOnStartup属性用于是否启动项目时创建保存token信息的数据表,这里设置为false,我们自己手动创建,首次可以选择true自动创建。
jdbcTokenRepository.setCreateTableOnStartup(false);
return jdbcTokenRepository;
}
然后在http中添加
.and()
.rememberMe()
.tokenRepository(persistentTokenRepository()) // 配置 token 持久化仓库
.tokenValiditySeconds(3600) // remember 过期时间,单为秒
.userDetailsService(userDetailsService) // 处理自动登录逻辑
.and()
记得前后需要用and连接
前端只需添加一个单选框,name需要为remember-me
记住我:<input type="checkbox" name="remember-me" value="true"><br>
重启项目,勾选记住密码单选框登录就能在cookie中看到一个remember-me的cookie