当前SpringBoot版本2.2.5.RELEASE,对应SpringSecurity5.2.2.RELEASE
当前内容用于不认人学习和使用SpringSecurity,当前内容主要涉及SpringSecurity访问数据库集成MyBatis的操作,实现用户权限的基本控制
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.5.RELEASEversion>
<relativePath/>
parent>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>3.8.1version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>RELEASEversion>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.46version>
<scope>runtimescope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.21version>
dependency>
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account {
private Long id;
private String username;
private String password;
private Boolean enabled;
private List<String> roles;
}
controller层
@RestController
public class VisitController {
@RequestMapping("/visitAdminPage")
public String visitAdminPage() {
return "访问admin页面成功";
}
@RequestMapping("/visitUserPage")
public String visitUserPage() {
return "访问user页面成功";
}
@RequestMapping("/visitIndexPage")
public String visitIndexPage() {
return "访问index页面成功";
}
}
入口类
@SpringBootApplication
public class SpringSecurityMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSecurityMybatisApplication.class, args);
}
}
数据源配置
@Configuration
@PropertySource(value = { "db.properties" })
public class DataSourceConfig {
@Value("${url}")
private String url;
@Value("${dbname}")
private String dbname;
@Value("${dbpwd}")
private String dbpwd;
@Value("${driverClassName}")
private String driverClassName;
@Bean
public DataSource configDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(dbname);
dataSource.setPassword(dbpwd);
return dataSource;
}
}
db.properties文件
url=jdbc:mysql://localhost:3306/springboot-security
dbname=root
dbpwd=root
driverClassName=com.mysql.jdbc.Driver
mybatis的配置类
@Configuration
@MapperScan(basePackages = {"com.hy.springboot.security.mybatis.mapper"})
@EnableTransactionManagement
public class MyBatisConfig {
@Autowired
DataSource dataSource; // mybatis需要数据源
// 配置当前sql会话工厂
@Bean("sqlSessionFactoryBean")
public SqlSessionFactoryBean configSqlSessionFactoryBean() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setTypeAliasesPackage("com.hy.springboot.security.mybatis.entity");
/* sqlSessionFactoryBean.setMapperLocations(mapperLocations); */
return sqlSessionFactoryBean;
}
}
SpringSecurity的配置类
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
// 创建自定义的userDetailService用于获取用户信息
@Bean
protected UserDetailsService userDetailsService() {
return new DefaultUserDetailsService();
}
class DefaultUserDetailsService implements UserDetailsService {
@Autowired
AccountMapper accountMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username == null || "".equals(username.trim())) {
throw new UsernameNotFoundException("用户名不能为空!");
}
Account account = accountMapper.findByUsername(username);
if (account == null) {
throw new UsernameNotFoundException("用户名不存在!");
}
Collection<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
for (String roleName : account.getRoles()) {
roles.add(new SimpleGrantedAuthority(roleName));
}
return new User(account.getUsername(), account.getPassword(), account.getEnabled(), true, true, true,
roles);
}
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// TODO Auto-generated method stub
//BCryptPasswordEncoder使用这个加密方式
// 本人不使用加密方式
auth.userDetailsService(userDetailsService()).passwordEncoder(NoOpPasswordEncoder.getInstance());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/visitAdminPage").hasRole("ADMIN")
.antMatchers("/visitUserPage").hasRole("USER")// 所需要的格式为ROLE_USER,必须以ROLE_开头
.anyRequest().authenticated()
.and()
.formLogin().successForwardUrl("/visitIndexPage").permitAll()
.and().csrf().disable();
}
}
public interface AccountMapper {
Account findByUsername(String username);
}
<mapper
namespace="com.hy.springboot.security.mybatis.mapper.AccountMapper">
<resultMap type="account" id="tableAccount">
<id column="id" property="id" />
<result column="username" property="username" />
<result column="password" property="password" />
<result column="enabled" property="enabled" />
<collection property="roles" ofType="String">
<constructor>
<arg column="roleName" />
constructor>
collection>
resultMap>
<select id="findByUsername" resultMap="tableAccount">
SELECT u.*,r.`roleName`
FROM security_mybatis_users u
INNER JOIN security_mybatis_roles r ON r.`username`=u.`username`
WHERE u.`username`=#{username}
select>
mapper>
然后各种页面测试都成功,用user登录也成功,权限校验也成功
1.通过实现UserDetailsService方式默认只要进行通过用户名获取,密码校验是SpringSecurity来自动检查的,必须定义passwordEncoder方式,否则密码校验出现错误
2.SpringSecurity是提供了默认的登录页面,如果定义类登录的url则使用用户定义的登录页面
以上纯属个人见解,如有问题请联系本人!