Spring Security初学

Springsecurity基本原理

本文仅作为个人笔记,若有错误之处,敬请谅解

1:Springsecurity 过滤器链:UsernamePasswordAuthenticationFilter,BasicAuthenticationFilter.....

ExceptionTranslationFilter:异常过滤器

FilterSecurityInterceptor:该过滤器是过滤器链的最后的一个过滤器 (最终是否可访问)

过滤器大部分可配置是否生效,过滤器的顺序也不可改变

(1)获取用户信息:UserdetailsService

自定义类继承UserDetailsService实现loadUserByUsername方法返回一个user(SpringSecurity框架的user类,已经继承UserDetails)对象

return user(username,password,authentication);

user有很多个构造方法,根据自己的需求选择

(2)处理用户校验逻辑

先看UserDetails源码

package org.springframework.security.core.userdetails;

import java.io.Serializable;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;

public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();

    String getPassword();

    String getUsername();

    /**
    用户是否过期
    */
    boolean isAccountNonExpired();

    /**
    用户是否锁定
    */
    boolean isAccountNonLocked();

    /**
    密码是否过期
    */
    boolean isCredentialsNonExpired();

    /**
    用户是否可用
    */
    boolean isEnabled();
}

(3)Springsecurity的加密解密:PasswordEncoder

源码

package org.springframework.security.crypto.password;

public interface PasswordEncoder {

    /**
    用来加密的方法
    */
    String encode(CharSequence var1);

    /**
    比较用户上传的密码和加密后的密码是否匹配
    */
    boolean matches(CharSequence var1, String var2);
}

encode加密方法在注册的时候加密存入数据库,使用BCryptPasswordEncoder进行加密,同一窜字母加密后的都是不一样的

 

个性化认证流程

   自定义登录页面

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;
    @Autowired
    private UserDetailsServiceImpl userDetailsService;
    @Autowired
    private AuthenticationEntryPointImpl authenticationEntryPoint;
    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;
    @Autowired
    private com.yb.springsecurity.jwt.auth.impl.AccessDeniedHandlerImpl AccessDeniedHandlerImpl;
    @Autowired
    private RedisTemplate<String, Serializable> redisTemplate;

    @Value("${allow.common.url}")
    private String[] commonUrl;
    @Value("${allow.server.url}")
    private String[] serverUrl;

    /**
     * 设置 HTTP 验证规则,用户模板最好在controller类上添加一层访问的路径,例如/auth/**
     * 这样在放开登录注册等接口的时候,就不容易造成放开一些不必要的接口服务
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //解决SpringBoot不允许加载iframe问题
        http.headers().frameOptions().disable();
        //关闭默认的登录认证
        http.httpBasic().disable()
                //添加处理ajxa的类实例
                .exceptionHandling().accessDeniedHandler(AccessDeniedHandlerImpl)
                //添加拦截未登录用户访问的提示类实例
                .authenticationEntryPoint(authenticationEntryPoint).and()
                //添加改session为redis存储实例
                .securityContext().securityContextRepository(new RedisSecurityContextRepository(redisTemplate)).and()
                //把session的代理创建关闭
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);

        // 关闭csrf验证,我们用jwt的token就不需要了
        http.csrf().disable()
                //对请求进行认证
                .authorizeRequests()
                //所有带/的请求都放行-->可以统一放到配置文件,然后读取过来,那样更方便修改特别是使用云配置的那种更方便
                //放开登录和验证码相关的接口(建议不要加层路径例如/auth,
                //会导致/security下的其他的不想放开的接口被放开等问题,直接放确定的最好,方正也没有几个接口)
                .antMatchers(serverUrl).permitAll()
                .antMatchers(HttpMethod.GET, commonUrl).permitAll()
                //访问指定路径的ip地址校验,访问指定路径的权限校验--这些接口需要的权限可以通过注解@PreAuthorize等来设置
                //.antMatchers("/auth/yes").hasIpAddress("192.168.11.130")//这个注解目前还没发现,可以在这里设置
                //所有请求需要身份认证
                .anyRequest().authenticated().and()
                //添加一个过滤器,对其他请求的token进行合法性认证
                .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
                .formLogin().loginPage("/login")
                .and().logout()
                .logoutUrl("/logout");

        // 自定义注销
        http.logout().logoutUrl("/logout").logoutSuccessUrl("/login")
                .invalidateHttpSession(true);

        //记住我功能配置
        http.authorizeRequests()
                .and()
                .rememberMe()
                //TokenRepository,登录成功后往数据库存token的
                .tokenRepository(persistentTokenRepository())
                //记住我秒数(一周)
                .tokenValiditySeconds(CommonDic.REMEMBER_ME_TIME)
                //记住我成功后,调用userDetailsService查询用户信息
                .userDetailsService(userDetailsService);
    }
}

认证流程:

 自定义登录成功处理:实现AuthenticationSuccessHandler接口

源码

package org.springframework.security.web.authentication;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
    /**
    Authentication :封装认证信息:发起的认证请求(认证的IP,session,返回的用户信息)
    */
public interface AuthenticationSuccessHandler {
    void onAuthenticationSuccess(HttpServletRequest var1, 
    HttpServletResponse var2, 
    Authentication var3) throws IOException, ServletException;
}

自定义登录失败处理:实现AuthenticationFailureHandler

源码

package org.springframework.security.web.authentication;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;

public interface AuthenticationFailureHandler {
    void onAuthenticationFailure(HttpServletRequest var1, HttpServletResponse var2, AuthenticationException var3) throws IOException, ServletException;
}

只有AuthenticationException 此参数不一样,以上操作都需要进行配置进行生效

认证流程源码详解

认证流程说明

认证结果在多个请求之间共享

UsernamePasswordAuthenticationFilter:获取用户上传的用户名和密码进行校验

AuthenticationManger:本身不包含验证逻辑,其作用是用来管理AuthenticationProvider

AuthenticationProvider:不同的登录方式有不同的AuthenticationProvider

SecurityContextPersistenceFilter:用于存放Session消息(在同一个线程做的操作)

获取认证用户信息

 SecurityContextHolder.getContext().getAuthentication();

图片验证码

(1):根据随机数生成图片

(2):将随机数存放在session中 :SessionStrategy工具类

(3):将生成的图片写到接口的响应中

将图片验证码加入到过滤器链中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值