Springsecuity的基本理解和使用

100 阅读3分钟

springsecuity的基本理解和使用

1.配置类中一些基本参数

@Bean
SecurityFilterChain filterChain(HttpSecurity http) 

这个bean中进行配置,让整个springsecurity生效,在测试的时候,可以直接对bean注释掉,让整个security失效

1.1定义授权规则

http.authorizeRequests

可以使用lambda表达式进行设置,主要参数为路径+规则的设置

1.2重写处理器

未获得权限认证

implements AccessDeniedHandler

重定向

implements AuthenticationEntryPoint

登录失败

implements AuthenticationFailureHandler

登录成功

 implements AuthenticationSuccessHandler

登出

implements LogoutSuccessHandler

session设置

 implements SessionInformationExpiredStrategy

1.3动态rbac

对这个接口实现,返回 new AuthorizationDecision(bool)对象,通过5张表的查询,判断返回类型

可以限制url,权限

/**
 * @param au,可以获得username
 * @param obj 可以获得方法
 * @retrun
 */
@Override
public AuthorizationDecision check(Supplier<Authentication> au, RequestAuthorizationContext obj)

在配置类中注册



http.authorizeHttpRequests(
                authorize -> authorize
                        .anyRequest()
                        .access(rbacAccess)

);

1.4 使用jwt策略

类似过滤器链接口, 继承这个父类OncePerRequestFilter,重写方法,使用上下文进行校验

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
    LoginUser loginUser = tokenManager.getLoginUser(request);
    if (ObjectUtil.isNotNull(loginUser) && ObjectUtil.isNull(SecurityUtils.getAuthentication()))
    {
        tokenManager.verifyToken(loginUser);
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
    }
    chain.doFilter(request,response);
}

在配置类中选择添加链的添加位置

http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

2.常见上下文对象

2.1 SecurityContextHolder

储存Authentication对象

Authentication 对象包含以下属性:

-   `Principal`:代表当前认证的用户,通常是一个 `UserDetails` 实例。implements UserDetails
-   `Credentials`:认证时使用的凭证,如密码(通常只在认证过程中使用,之后会被清除)。
-   `Authorities`:当前用户拥有的权限集合,通常是一个 `GrantedAuthority` 对象的集合。

2.2 userDetails

验证成功后,储存在Authentication的Principal中

这个对象可以继承重写接口,写可以之间使用security6提供的一个User实现类(建造者模式),这个对象在授权规则那一部分被调用,

                        .requestMatchers("/user/list").hasAuthority("USER_LIST")
                      .requestMatchers("/user/add").hasAuthority("USER_ADD")

或者1.3中的方法重写

2.3登录接口UserDetailsService接口中loadUserByUsername,创建userdetails

返回userDetails的实例,自动加入过滤链 .将数据库的password和输入创建的token进行对比,security中的失败用异常来捕捉

authentication = authenticationManager
        .authenticate(new UsernamePasswordAuthenticationToken(username, password));

try
{
    // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
    //对数据库查
    authentication = authenticationManager
            .authenticate(new UsernamePasswordAuthenticationToken(username, password));
}
catch (Exception e)
{
    if (e instanceof BadCredentialsException)
    {
        throw new ServiceException("用户名密码错误");
    }
    else
    {
        throw new ServiceException(e.getMessage());
    }
}

2.4* security的默认过滤链UsernamePasswordAuthenticationFilter

当前端传指定username和password字段时,会使用这个过滤链自动创建token UsernamePasswordAuthenticationFilter会使用这些信息创建一个UsernamePasswordAuthenticationToken,并将其传递给认证管理器(AuthenticationManager)进行验证。token校验失败

2.5 UsernamePasswordAuthenticationToken

继承了 Authentication

AuthenticationManager进行验证(委派)成功后,返回一个Authentication的实例对象(UsernamePasswordAuthenticationToke),authentication的接口也发生变化

  • 认证前创建的的token:

public UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
  super((Collection)null);
  this.principal = principal;
  this.credentials = credentials;
  this.setAuthenticated(false);
}
  • 认证成功后的token:

    • principal:此时通常是UserDetails实例,包含了用户的详细信息,如用户名、密码、权限等。
    • credentials:通常设置为null,因为在认证成功后,出于安全考虑,不应该在Authentication对象中保留密码。
    • authorities:包含了用户的权限集合,通常是GrantedAuthority对象的列表,定义了用户可以执行的操作或访问的资源。
public abstract class AbstractAuthenticationToken implements Authentication, CredentialsContainer {