maven配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
基于内存的简单应用
首先我们有两个不同的权限USER和ADMIN,分别能访问不同的页面
@Controller
@RequestMapping("/product")
public class ProductTestController {
@RequestMapping("/info")
@ResponseBody
public String productInfo(){
return " some product info ";
}
}
-------------------------------------------
@Controller
@RequestMapping("/admin")
public class AdminTestController {
@RequestMapping("/home")
@ResponseBody
public String productInfo(){
return " admin home page ";
}
}
之后在
SecurityConfiguration
里增加角色管理配置
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
//设置角色和权限
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("admin") // 管理员,同事具有 ADMIN,USER权限,可以访问所有资源
.password("{noop}admin")
.roles("ADMIN", "USER")
.and()
.withUser("user").password("{noop}user") // 普通用户,只能访问 /product/**
.roles("USER");
}
//设置接口对应的权限
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/product/**").hasRole("USER")
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin().and()
.httpBasic();
}
}
我们还可以获取用户的信息
@RequestMapping("/info")
@ResponseBody
public String productInfo(){
String currentUser = "";
Object principl = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(principl instanceof UserDetails) {
currentUser = ((UserDetails)principl).getUsername();
}else {
currentUser = principl.toString();
}
return " some product info,currentUser is: "+currentUser;
}
通过数据库查询,存储用户和角色实现安全认证
实体类和repository
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "user")
public class User implements java.io.Serializable{
@Id
@Column(name = "user_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId;
@Column(name = "user_name")
private String userName;
@Column
private String password;
@Column
private String role;
}
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findUserByUserName(String userName);
}
之后在数据库插入两条数据
user_id | user_name | password | role |
---|---|---|---|
1 | admin | $2a$10$KAIHJloiQwYHEZ05J/WrVOAxZRAHuMyUP1ibralQ4.R9FKUiFUufq | ROLE_ADMIN |
2 | user | $2a$10$KAIHJloiQwYHEZ05J/WrVOAxZRAHuMyUP1ibralQ4.R9FKUiFUufq | ROLE_USER |
密码这里都是使用了BCryptPasswordEncoder
需在SecurityConfiguration
中加入配置,这里的密码是123
自定义UserDetailsService
spring security在认证过程中需要查找用户,会调用UserDetailsService的loadUserByUsername方法得到一个UserDetails
@Component("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
//1.查询用户
User userFromDatabase = userRepository.findUserByUserName(userName);
if (userFromDatabase == null) {
//log.warn("User: {} not found", login);
throw new UsernameNotFoundException("User " + userName + " was not found in db");
//这里找不到必须抛异常
}
// 2. 设置角色
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(userFromDatabase.getRole());
grantedAuthorities.add(grantedAuthority);
return new org.springframework.security.core.userdetails.User(
userName, userFromDatabase.getPassword(), grantedAuthorities);
}
}
这个方法做了2件事情,查询用户以及设置角色,通常一个用户会有多个角色,即上面的userFromDatabase.getRole()
通常是一个list,所以设置角色的时候,就是for循环new 多个SimpleGrantedAuthority并设置。(本例为了简单没有设置角色表以及用户角色关联表,只在用户中增加了一个角色字段,所以grantedAuthorities只有一个)
修改SecurityConfiguration
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/product/**").hasRole("USER")
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin().and()
.httpBasic();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
OK了,现在admin用户能访问admin页面,而user用户只能访问product页面
Comments | 0 条评论