Spring Security - 认证流程与搭建过程问题记录

用户认证的流程:

Spring Security支持多种用户认证的方式,最常用的是基于用户名和密码的用户认证方式,其认证流程如下图所示:

1. 为什么定义的成功处理地址defaultSuccessUrl没生效:

如果自定义了用户认证成功处理器,则在Spring Security配置类中通过http.formlogin().defaultSuccessUrl(" URL")来指定的默认认证成功后请求的URL配置并不会对自定义的用户认证成功处理器有效,因为该配置只对Spring Security默认的用户认证成功处理器有效。要想使得自定义的用户认证成功之后自动请求指定的URL,则需要在自定义的用户认证成功处理器中通过设置defaultTargetUrl参数的值的方式来实现。

2. 假如用户登录后,在一定时间如果有操作,怎样设计一个延长登录有效时间。没有一定时间没有操作,不延长登录时间。(jwt前后端分离如何设计永久登录)

使用refresh_token机制:如设置refresh_token有效时间为3天,access_token时间为1天,如果一天过后用户有操作,将使用refresh_token刷新access_token并生成新的refresh_token,此时refresh_token重新计算三天有效期,也就延长了登录时间。永久登录同理,将refresh_token设置永不过期即可。

3. addFilterBefore使用介绍:

在UsernamePasswordAuthenticationFilter之前执行jwtAuthorizationFilter;

        // 用户权限的验证 在 beforeFilter 之前添加 filter
        http.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class); // JWT Filter

4. 除了使用@PreAuthorize控制方法权限,还可以添加全局拦截动态认证:

                // 认证的逻辑
HttpSecurity http
                .access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
扫描二维码关注公众号,回复: 13118075 查看本文章

5. JwtToken认证方式,在无状态,怎么实现注销操作?

每次登陆,生成 JwtToken放到 Redis 数据库里边,调用接口的时候,先查有没有这个 token,注销时把 token 删除。利用Redis判定用户token是否存在,验证用户是否已注销。

6.  AuthenticationManage、AuthenticationProvider之间的关系:

1、在UsernamePasswordAuthenticationFilter的attemptAuthentication()方法中,调用AuthenticationManager进行认证

2、AuthenticationManager接收Authentication对象作为参数,并通过authenticate方法对其进行验证(实际由其实现类ProviderManager完成)

3、在ProviderManager的authenticate方法中,轮训成员变量List<AuthenticationProvider> providers。该providers中如果有一个AuthenticationProvider的supports函数返回true,那么就会调用该AuthenticationProvider的authenticate函数认证,如果认证成功则整个认证过程结束。如果不成功,则继续使用下一个合适的AuthenticationProvider进行认证,只要有一个认证成功则为认证成功。

4、UsernamePasswordAuthenticationToken实现了Authentication,主要是将用户输入的用户名密码进行封装,并提供给AuthenticationManager进行验证,验证成功后,返回一个认证成功的UsernamePasswordAuthenticationToken对象。

AuthenticationProvider也是一个接口,包含两个函数authenticate和supports。当Spring Security默认提供的Provider不能满足需求的时候,可以通过实现AuthenticationProvider接口来扩展出不同的认证提供者。

AuthenticationManagerBuilder用于创建AuthenticationManager。 允许轻松构建内存身份验证,LDAP身份验证,基于JDBC的身份验证,添加UserDetailsService以及添加AuthenticationProvider。

参考:https://blog.csdn.net/shenchaohao12321/article/details/87721655

7. base64encode 一直出现特殊字符怎么办?(URL参数有时候因为安全问题,不用出现某些字符)

将其 hex 状态十六进制。

8. @PreAuthorize安全表达式hasRole、hasAuthority区别:

见我的博客:https://blog.csdn.net/qq_26878363/article/details/103632459

9. Spring当中很好用参考例子:supports方法来表示本provider提供的认证范围(学到新姿势了)

AuthenticationProvider->

boolean supports(Class<?> authentication);

10. 跨域预请求取消拦截(我记得OPTIONS不添加好像也是不会拦截的,在这里备份一下)

 .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() //跨域预请求添加;

11. 获取用户真实IP的方法(识破反向代理,暂未验证哟,等有时间了验证。看起来应该可以)

   /**
     * 获取用户真实IP地址,不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");

        if ((ip == null) || (ip.length() == 0) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if ((ip == null) || (ip.length() == 0) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if ((ip == null) || (ip.length() == 0) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }

        if ((ip == null) || (ip.length() == 0) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }

        if ((ip == null) || (ip.length() == 0) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        return ip;
    }

12. 链式编程:

	public StudentBean setName(String name) {
		this.name = name;
		return this;
	}
 

这段代码和传统的Bean区别就是我在set属性时候会返回一个this这样就达到了链式编程的效果

lombok其实已经提供该style,我们把这个bean改成lombok实现只需要加上一个@Accessors(chain = true)即可。

@Accessors(chain = true)
@Getter
@Setter
public class StudentBean {
	private String name;
	
	private int age;
}

参考文章:

https://blog.csdn.net/weixin_44516305/article/details/87860966(个人感觉这篇文章理解更清晰,里边还有自定义实现)

猜你喜欢

转载自blog.csdn.net/qq_26878363/article/details/103733932