springboot-springsecurity小记

2021-02-03  本文已影响0人  Aolus

spring security 优秀得权限控制框架 针对RABC原则设计核心功能:

认证(你是谁)

授权(你能干什么)

攻击防护(防止伪造身份)

核心组件:

SecurityContextHolder

用于存储应用程序安全上下文(Spring Context)的详细信息,如当前操作的用户对象信息、认证状态、角色权限信息等。默认情况下,SecurityContextHolder 会使用 ThreadLocal 来存储这些信息,意味着安全上下文始终可用于同一执行线程中的方法。

获取有关当前用户的信息

因为身份信息与线程是绑定的,所以可以在程序的任何地方使用静态方法获取用户信息。例如获取当前经过身份验证的用户的名称,代码如下:

Object principal =SecurityContextHolder.getContext().getAuthentication().getPrincipal();if(principal instanceof UserDetails) {    String username = ((UserDetails)principal).getUsername();}else{    String username = principal.toString();}

其中,getAuthentication() 返回认证信息,getPrincipal() 返回身份信息,UserDetails 是对用户信息的封装类。

Authentication

认证信息接口,集成了 Principal 类。该接口中方法如下:

接口方法功能说明

getAuthorities()获取权限信息列表,默认是 GrantedAuthority 接口的一些实现类,通常是代表权限信息的一系列字符串

getCredentials()获取用户提交的密码凭证,用户输入的密码字符窜,在认证过后通常会被移除,用于保障安全

getDetails()获取用户详细信息,用于记录 ip、sessionid、证书序列号等值

getPrincipal()获取用户身份信息,大部分情况下返回的是 UserDetails 接口的实现类,是框架中最常用的接口之一

AuthenticationManager

认证管理器,负责验证。认证成功后,AuthenticationManager 返回一个填充了用户认证信息(包括权限信息、身份信息、详细信息等,但密码通常会被移除)的 Authentication 实例。然后再将 Authentication 设置到 SecurityContextHolder 容器中。

AuthenticationManager 接口是认证相关的核心接口,也是发起认证的入口。但它一般不直接认证,其常用实现类 ProviderManager 内部会维护一个 List<AuthenticationProvider> 列表,存放里多种认证方式,默认情况下,只需要通过一个 AuthenticationProvider 的认证,就可被认为是登录成功。

Springboot -Spring Security 相关集成
1.引入对应依赖

配置Spring securoty 核心配置

public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Resource

  private UserDetailsService userDetailsService; //自定义用户详情实现spring security UserDetailService接口

@Bean

  public PasswordEncoder passwordEncoder() { //Spring security 密码加密器 使用不同得密钥加密

return new BCryptPasswordEncoder();

}

@Override

  protected void configure(HttpSecurity http)throws Exception {

//禁用csrf

    http.csrf().disable().headers().frameOptions().disable().and();

//配置无需验证Url

    http.authorizeRequests().antMatchers("/login","/login.html").permitAll();

    //配置除无需验证得URL外所有得URL必须要经过验证,并且当前用户拥有相应得权限点匹配上才可访问  
  http.authorizeRequests().anyRequest().access("@permissionService.hasPermission(request,authentication)").and();

//配置登录登陆请求,更改默认得参数,配置登录成功处理得Handler,和登录失败得Handler。

    http.formLogin().loginPage("/login").loginProcessingUrl("/login").usernameParameter("userName").passwordParameter("password").successHandler(new AuthenticationSuccessHandler() {

@Override

      public void onAuthenticationSuccess(HttpServletRequest request,

HttpServletResponse response,Authentication authentication)

throws IOException {

HttpSession session =request.getSession();

session.setAttribute("userInfo","测试用户信息");

response.setContentType("application/json;charset-utf-8");

PrintWriter printWriter =response.getWriter();

printWriter.write("{\"code\":00000,\"message\":\"登录成功\"}");

printWriter.close();

}

}).failureHandler(new AuthenticationFailureHandler() {

@Override

      public void onAuthenticationFailure(HttpServletRequest request,

HttpServletResponse response,AuthenticationException e)

throws IOException {

response.setContentType("application/json;charset-utf-8");

PrintWriter printWriter =response.getWriter();

printWriter.write("{\"code\":40000,\"message\":\"用户名密码错误\"}");

printWriter.close();

}
//配置异常处理Handler 

}).permitAll().and().exceptionHandling().accessDeniedHandler(//没有权限处理异常,登录成功之后,无权限才会触发该Handler

        new AccessDeniedHandler() {

@Override

          public void handle(HttpServletRequest request,

HttpServletResponse response,AccessDeniedException e)

throws IOException,ServletException {

response.setContentType("application/json;charset=utf-8");

PrintWriter printWriter =response.getWriter();

printWriter.write("{\"code\":40001,\"message\":\"无权限\"}");

printWriter.close();

}

//未登录处理异常Handler
}).authenticationEntryPoint(new AuthenticationEntryPoint() {//未登录处理异常

      @Override

      public void commence(HttpServletRequest httpServletRequest,

HttpServletResponse response,AuthenticationException e)

throws IOException,ServletException {

response.setContentType("application/json;charset=utf-8");

PrintWriter printWriter =response.getWriter();

printWriter.write("{\"code\":40002,\"message\":\"未登录\"}");

printWriter.close();

}

});

}

//配置登录认证

@Override

  protected void configure(AuthenticationManagerBuilder auth)throws Exception {

auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());

}

实现Spring Security UserDetailService接口,可实现数据库版本 //可自定义实现权限点鉴权
上一篇下一篇

猜你喜欢

热点阅读