引入相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
一、三种配置方式:
1、配置文件设置.properties
#账号密码角色设置
spring.security.user.name=root
spring.security.user.password=root
spring.security.user.roles=ROLE_ADMIN
2、配置类设置
重写WebSecurityConfigurerAdapter中的configure方法
@Configuration
public class MySecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("yxj")
.password(passwordEncoder()
.encode("yxj"))
.roles("ADMIN");
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
3、自定义实现类(数据库认证)
引入依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
一、创建配置类
@Configuration
public class MySecurity extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder())
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
二、编写实现类
UserDetailsServiceImpl
package com.xmut.uservice;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xmut.dao.UserMapper;
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.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("userDetailsService") //userDetailsService要跟自动注入的名字一样
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
//查询数据库
QueryWrapper<com.xmut.domain.User> wrapper = new QueryWrapper();
wrapper.eq("username",s);
com.xmut.domain.User user = userMapper.selectOne(wrapper);
//判断账号是否存在
if(user == null){
throw new UsernameNotFoundException("用户名不存在");
}else {
System.out.println("登录成功");
List<GrantedAuthority> author = AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_role");
return new User(user.getUsername(),new BCryptPasswordEncoder().encode(user.getPassword()),author);
}
}
}
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(0) NOT NULL AUTO_INCREMENT COMMENT 'id',
`username` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户名',
`password` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '密码',
`role` varchar(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '权限',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'admin', 'admin', 'admin');
INSERT INTO `user` VALUES (2, 'kongjun', '123', 'user');
SET FOREIGN_KEY_CHECKS = 1;
application.properties
spring.datasource.type = com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/bookdb?serverTimezone=UTC&useSSL=false
spring.datasource.username = root
spring.datasource.password = 123456
User
@Data
public class User {
private Integer id;
private String username;
private String password;
}
UserMapper
package com.xmut.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xmut.domain.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface UserMapper extends BaseMapper<User> {
}
二、权限设置和csrf防护(configure(HttpSecurity http))
1、页面权限
@Override
protected void configure(HttpSecurity http) throws Exception {
//1、未授权跳转页面
http.exceptionHandling().accessDeniedPage("/unauth.html");
//2、自定义登录页面+权限角色认证
http.formLogin()
.loginPage("/login.html") //跳转页面
.usernameParameter("username") //登录页面用户名输入框的name属性
.passwordParameter("password") //登录页面密码输入框的name属性
.failureUrl("/error.html") //登录失败跳转页面)
.loginProcessingUrl("/user/login") //登录访问路径(跟from中的地址要一致)
.defaultSuccessUrl("/hello.html").permitAll() //认证成功后跳转的路径
.and()
.authorizeRequests() //前两个是权限,后两个是角色,角色比权限更高
.antMatchers("/","/test/hello","/logout").permitAll() //设置那些路径可以直接访问不需要认证
.antMatchers("/test/index").hasAuthority("admin,user") //访问当前路径需要拥有admin权限和user权限
.antMatchers("/test2").hasAnyAuthority("admin","user") //访问当前路径需要拥有admin或者user权限)
.antMatchers("/test/index3").hasRole("role2") //访问当前路径需要拥有role角色
.antMatchers("/test4").hasAnyRole("role","role2") //访问当前路径需要拥有role或者role2角色
.anyRequest().authenticated() //所有请求都能访问
.and()
.rememberMe().tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(60) //token有效期为60s
.userDetailsService(userDetailsService)
.and().csrf().disable(); //关闭csrf防护
}
2、注销功能
<!--前端页面-->
<a href="/logout">退出</a>
//注销,退出登录后跳转到index.html
http.logout().logoutUrl("/logout").logoutSuccessUrl("/login.html").permitAll();
3、自动登录功能
<!--from表单中添加-->
<input type="checkbox" name="remember-me"/>自动登录
//1、注入数据源
@Autowired
private DataSource dataSource;
//2、配置对象
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
// tokenRepository.setCreateTableOnStartup(true); //自动创建表结构创建一次就要取消
return tokenRepository;
}
//在csrf防护前面添加以下代码
.and()
.rememberMe().tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(60) //token有效期为60s
.userDetailsService(userDetailsService)
3、配置csrf防护
from表单中添加以下代码
<!-- 开启csrf防护,防止跨站攻击,隐藏表单-->
<!-- <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}">-->