一、spring security 简介
spring security 的核心功能主要包括:
认证 (你是谁)
授权 (你能干什么)
攻击防护 (防止伪造身份)
其核心就是一组过滤器链,项目启动后将会自动配置。最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。
二、入门项目
依赖
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
User实体继承了UserDetails(security依赖自带的)
@ApiModel(value = "TODO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements UserDetails {
@ApiModelProperty(value = "")
private Long id;
@ApiModelProperty(value = "")
private String username;
@ApiModelProperty(value = "")
private String idcard;
@ApiModelProperty(value = "")
private String telephon;
@ApiModelProperty(value = "")
private String email;
@ApiModelProperty(value = "")
private String password;
@ApiModelProperty(value = "")
private String role;
private List<GrantedAuthority> authorities;
public void setAuthorities(List<GrantedAuthority> authorities) {
this.authorities = authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public String getUsername() {
return this.username;
}
/**
* 账户是否未过期,过期无法验证
*/
@Override
public boolean isAccountNonExpired() {
return true;
}
/**
* 指定用户是否解锁,锁定的用户无法进行身份验证
*
* @return
*/
@Override
public boolean isAccountNonLocked() {
return true;
}
/**
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
*
* @return
*/
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
* 是否可用 ,禁用的用户不能身份验证
*
* @return
*/
@Override
public boolean isEnabled() {
return true;
}
}
实现UserDetailsService,认证逻辑(security依赖自带的)
@Service
public class UserDetailsImpl implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.selectByName(username);
if (user == null) {
throw new UsernameNotFoundException("登录用户:" + username + "不存在");
}
//AuthorityUtils.commaSeparatedStringToAuthorityList将逗号分隔的字符集转成权限对象列表
user.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(user.getRole()));
return user;
}
}
认证成功和失败Handler
/**
* 认证失败跳转页面, 在httpBasic和form表单登录失败处理类
*/
@Component
public class MyAuthencationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter out = httpServletResponse.getWriter();
out.write("{\"code\":\"40001\",\"msg\":\"登录失败\"}");
}
}
/**
* 认证成功跳转页面, 在httpBasic和form表单登录成功处理类
*/
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter out = httpServletResponse.getWriter();
out.write("{\"code\":\"20001\",\"msg\":\"登录成功\"}");
}
}
WebSecurityConfigurerAdapter
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyAuthencationFailureHandler failureHandler;
@Autowired
private MyAuthenticationSuccessHandler successHandler;
@Autowired
private UserDetailsImpl userDetails;
/**
* 当前配置为form表单登录认证方式
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()//开启formlogin模式
.loginPage("/login.html")//用户未登录时,访问任何资源跳转到该页面
.loginProcessingUrl("/login")//登录表单form中action的地址,即处理认证的路径
.usernameParameter("username")//默认是username,提交用户名字段
.passwordParameter("password")//默认是password,提交密码字段
// .defaultSuccessUrl("/index")//登录成功跳转接口
// .failureUrl("/login")//登录失败跳转页面
//登录成功
.successHandler(successHandler)
//登录失败
.failureHandler(failureHandler)
// 连接, 在后面继续配置其他的
.and()
//配置登录后的权限
.authorizeRequests()
//用户可任意访问
.antMatchers("/login.html","/login").permitAll()
//user角色和admin角色可以访问
.antMatchers("/order").hasAnyAuthority("ROLE_user","ROLE_admin")
//admin可访问
.antMatchers("/system/user","/system/role","/system/menu").hasAnyRole("admin")
// 除上面外的请求全部需要鉴权认证 authenticated()要求在执行请求要求必须已登录------------------------
.anyRequest().authenticated()
.and()// 连接, 继续配置其他的
.csrf().disable();//禁用跨站csrf攻击防御, 否则无法成功登录
//登出功能
http.logout().logoutUrl("/logout");
}
//登录验证逻辑
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
//调用DetailsService完成用户身份验证 设置密码加密方式
auth.userDetailsService(userDetails).passwordEncoder(getBCryptPasswordEncoder());
}
/**
* 强散列哈谢加密实现
* @return
*/
@Bean
public BCryptPasswordEncoder getBCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
}
附带源码地址:https://gitee.com/zhu_can_admin/boke.git