一、添加依赖:
<dependency>
<groupId>org.springframework.boot
<artifactId>spring-boot-starter-security
</dependency>
二、定义三个实体:用户类、角色类、权限类
@Data
public class User implements UserDetails {
private Integer id;
private String username;
private String realName;
private String password;
private List roles;
@Override
public Collection getAuthorities() {
return null;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
@Data
public class Role {
private String roleName;
private List permissions;
}
@Data
public class Permission {
private String permissionName;
}
三、配置类
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsServiceImpl myUserDetailsService;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/***
* 权限过滤
* @date 2020/1/22
* @param http
**/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login")
.failureForwardUrl("/fail")
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication)throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=utf-8");
RequestCache cache =new HttpSessionRequestCache();
SavedRequest savedRequest = cache.getRequest(httpServletRequest, httpServletResponse);
String url = savedRequest.getRedirectUrl();
httpServletResponse.sendRedirect(url);
}
})
.permitAll()
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/logout.html").permitAll()
//禁用跨域请求
.and().csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth)throws Exception {
//下面这两行配置表示在内存中配置了两个用户,进行认证
// auth.inMemoryAuthentication()
// .passwordEncoder(passwordEncoder())
// .withUser("lisi").roles("USER").password(passwordEncoder().encode("123"))
// .and()
// .withUser("admin").roles("USER","ADMIN").password(passwordEncoder().encode("123"));
//调用数据库中的用户进行认证
auth.userDetailsService(myUserDetailsService);
}
}
四、权限验证配置类
@Configuration
public class MyPermissionEvaluator implements PermissionEvaluator {
@Override
public boolean hasPermission(Authentication authentication, Object permission, Object operation) {
boolean accessable =false;
User user = (User) authentication.getPrincipal();
if (user !=null) {
for (GrantedAuthority authorities : authentication.getAuthorities()) {
String authorities1 = String.format("%s-%s", permission, operation);
if (authorities1.equals(authorities.getAuthority())) {
return accessable =true;
}
}
}
return accessable;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable serializable, String s, Object o) {
return false;
}
}
五、通过数据库查询
@Component
public class MyUserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username)throws UsernameNotFoundException {
User user = userService.findUserByUserName(username);
if (user ==null) {
throw new UsernameNotFoundException(String.format("No user found with username: %s", username));
}
List authorities =new ArrayList<>();
for (Role role : user.getRoles()) {
for (Permission permission : role.getPermissions()) {
authorities.add(new SimpleGrantedAuthority(String.format("%s-%s", role.getRoleName(), permission.getPermissionName())));
}
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), user.isEnabled(),
user.isAccountNonExpired(), user.isCredentialsNonExpired(), user.isAccountNonLocked(), authorities);
}
}
@Service
public class UserService {
//密码加密
@Autowired
private BCryptPasswordEncoder passwordEncoder;
public User findUserByUserName(String userName) {
List userList = create();
List users = userList.parallelStream().filter(user -> user.getUsername().equals(userName)).collect(Collectors.toList());
return users !=null ? users.get(0) :null;
}
private List create() {
Permission permission =new Permission();
permission.setPermissionName("select");
List permissions =new ArrayList<>();
permissions.add(permission);
Role role =new Role();
role.setRoleName("admin");
role.setPermissions(permissions);
List roles =new ArrayList<>();
roles.add(role);
User user =new User();
user.setId(1);
user.setRealName("张三");
user.setUsername("zhangsan");
user.setPassword(passwordEncoder.encode("123456"));
user.setRoles(roles);
/**********************************************************/
Permission permission1 =new Permission();
permission1.setPermissionName("update");
List permissions1 =new ArrayList<>();
permissions1.add(permission1);
Role role1 =new Role();
role1.setRoleName("user");
role1.setPermissions(permissions1);
List roles1 =new ArrayList<>();
roles1.add(role1);
User user1 =new User();
user1.setId(2);
user1.setRealName("李四");
user1.setUsername("lisi");
user1.setPassword(passwordEncoder.encode("123456"));
user1.setRoles(roles1);
List users =new ArrayList<>();
users.add(user);
users.add(user1);
return users;
}
}
@Controller
public class TestController {
@RequestMapping("/hello")
@PreAuthorize("hasPermission('admin','select')")
public String hello() {
return "hello.html";
}
@GetMapping("/login")
public String loginIndex() {
return "login.html";
}
@GetMapping("/test")
@ResponseBody
public String test() {
return "hello world";
}
// @RequestMapping("/myLogin")
// public String myLogin() {
// System.out.println("lllsldfds");
// return "hello";
// }
@RequestMapping("/logout")
public String logout() {
return "logout.html";
}
@RequestMapping("/fail")
@ResponseBody
public String loginFail() {
return "登录失败";
}
}
//启动类
@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled =true)
public class SecurityApplication {
public static void main(String[] args) {
SpringApplication.run(SecurityApplication.class, args);
}
}