实现了不同的角色拥有不同路径的访问权限
基于JDBC的用户认证
首先修改pom.xml,增加MySQL依赖及JPA
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.18</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
创建实体类UserInfo,添加get/set方法
@Entity public class UserInfo { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String username; private String password; private String role; }
创建持久层UserInfoDao,继承JpaRepository,定义方法findByUsername(String username)
public interface UserInfoDao extends JpaRepository<UserInfo,Long>{ //按照username查询数据库 UserInfo findByUsername(String username); }
创建service层UserInfoService接口,并创建UserInfoServiceImpl实现类实现该接口
public interface UserInfoService { UserInfo findUserInfo(String username); }
不要忘记@Service注解
@Service public class UserInfoServiceImpl implements UserInfoService { @Autowired private UserInfoDao userInfoDao; @Override public UserInfo findUserInfo(String username) { return userInfoDao.findByUsername(username); } } 复制代码
配置application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=root spring.jpa.generate-ddl=true spring.jpa.show-sql=true spring.jpa.database=mysql # 声明创建表时使用InnoDB引擎,默认使用myisam spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
此时启动应用会在数据库中创建user_info表,接着需要初始化user_info表中的数据 在init包下面创建JDBCInit类
@Component public class JDBCInit { @Autowired private UserInfoDao userInfoDao; @PostConstruct public void init(){ PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); UserInfo user1 = new UserInfo(); user1.setUsername("IronMan"); user1.setPassword(passwordEncoder.encode("12345")); user1.setRole("admin"); userInfoDao.save(user1); UserInfo user2 = new UserInfo(); user2.setUsername("thor"); user2.setPassword(passwordEncoder.encode("12345")); user2.setRole("user"); userInfoDao.save(user2); } }
接着创建MyUserDetailService,该类继承框架包中的UserDetailService,作用类似于存储用户角色信息
@Component("myUserDetailService") public class MyUserDetailService implements UserDetailsService { @Autowired private UserInfoService userInfoService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserInfo userInfo = null; User user = null; if (username != null){ userInfo = userInfoService.findUserInfo(username); if (userInfo != null){ List<GrantedAuthority> grantedAuthorityList = new ArrayList<>(); GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_"+userInfo.getRole()); grantedAuthorityList.add(authority); // 创建User类,框架中的User类 user = new User(userInfo.getUsername(),userInfo.getPassword(),grantedAuthorityList); } } return user; } }
修改MyWebSecurityConfig,将保存用信息到内存中的代码全部删除
/** * prePostEnabled = true表示可以使用@PreAuthorize注解和@PostAuthorize方法级别的注解 */ @Configuration//表示该类是一个配置类,返回值是Java对象,由SpringIOC管理,相当于配置xml文件 @EnableWebSecurity //表示启用SpringSecurity安全框架功能 @EnableGlobalMethodSecurity(prePostEnabled = true) //启用方法级别的安全控制 public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private MyUserDetailService myUserDetailService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(myUserDetailService).passwordEncoder(new BCryptPasswordEncoder()); } }
HelloSecurityController的代码不变,启动应用,使用IronMan/12345登录,可以访问/hello,/admin
使用thor/12345登录,访问/hello,/admin