spring cloud oauth2 替换用户信息

spring cloud oauth2 替换用户信息

在spring cloud 的oauth2认证中,有一个用户认证服务auth,提供客户端的认证,由于oauth2有多种授权方式,不同的授权采用的方式就不一样了。

在实际业务中,比如有个应用A,有自己的数据库A,需要auth授权后才能登陆,PC端登录的时候采用的是授权码模式,使用 @EnableOAuth2Sso 注解标记一个 WebSecurityConfigurerAdapter 类。当登录认证成功后会广播一个event事件,这个事件可以监听到,所以我们采用的是监听InteractiveAuthenticationSuccessEvent事件,这个是通过自动交互的手段来登录成功,比如cookie自动登录。具体实现细节如下,实际应用采用的是注释掉的代码,两种都可以参考:

   @EventListener
    public void authSuccessListener(InteractiveAuthenticationSuccessEvent event){
        System.out.println("哎呦喂,登录成功了");
        Authentication authentication=SecurityContextHolder.getContext().getAuthentication();
        //通用替换,针对用户名密码登录的
        if(authentication instanceof UsernamePasswordAuthenticationToken){
            UsernamePasswordAuthenticationToken originToken= (UsernamePasswordAuthenticationToken) authentication;
            String username= originToken.getName();
            System.out.println(username);
            //查找用户,这里直接模拟查到了用户,根据需求进行替换
            Person person=new Person(username,20);
            UsernamePasswordAuthenticationToken token=new UsernamePasswordAuthenticationToken(originToken.getPrincipal(),"N/A",originToken.getAuthorities());
            token.setDetails(person);
            SecurityContextHolder.getContext().setAuthentication(token);
        }
        //auth2替换
        //替换oauth认证的信息里的details,这里就不展示了
       /* if (authentication instanceof OAuth2Authentication) {
            OAuth2Authentication originalOAuth2Authentication = (OAuth2Authentication) authentication;
            if (!originalOAuth2Authentication.isClientOnly()) {
                Authentication userAuthentication = originalOAuth2Authentication.getUserAuthentication();
                if (userAuthentication instanceof UsernamePasswordAuthenticationToken) {
                    UsernamePasswordAuthenticationToken originalUsernamePasswordAuthentication = (UsernamePasswordAuthenticationToken) userAuthentication;

                    String username = (String) originalUsernamePasswordAuthentication.getPrincipal();
                    //可以根据username查找用户,这里模拟获取用户
                    Person person=new Person("二狗子",18);
                    if (person != null) {
                        //替换用户信息,权限信息根据自己的需求替换,这里直接取原来的
                        UsernamePasswordAuthenticationToken usernamePasswordAuthentication = new UsernamePasswordAuthenticationToken(originalUsernamePasswordAuthentication.getPrincipal(), "N/A", originalUsernamePasswordAuthentication.getAuthorities());
                        usernamePasswordAuthentication.setDetails(person);

                        OAuth2Authentication oauth2Authentication = new OAuth2Authentication(originalOAuth2Authentication.getOAuth2Request(), usernamePasswordAuthentication);
                        oauth2Authentication.setDetails(originalOAuth2Authentication.getDetails());

                        SecurityContextHolder.getContext().setAuthentication(oauth2Authentication);
                    }
                }
            }
        }*/
    }

 

但是在APP登录的时候采用的授权方式是密码,这样认证的时候是根据认证token,只是一个token没有像pc端那样有cookie去自动验证,服务器是通过资源服务器认证的,只要token通过就可以访问被资源服务器保护的资源,这里都是/api/的接口。这种情况下就不能监听登录事件了,要在每次验证通过后去替换oauthAuthentication里面的details了,这样接口获取本应用当前登录用户的时候就可以直接获取了。那么如何实现认证成功后替换呢,根据spring security的尿性,增加一个filter,在最后一个filter之前替换。(注意:自定义过滤器交给spring托管可能出现doFilter被执行两次的问题,可以加个标记解决)

 

@Component
public class CustomerSecurityFilter extends GenericFilterBean {
    //加个标记,防止被执行两次
    //在spring容器托管的GenericFilterBean的bean,都会自动加入到servlet的filter chain,而我们还额外把filter加入到了spring security的
    //最后一个Filter之前。而spring security也是一系列的filter,在mvc的filter之前执行。因此在鉴权通过的情况下,就会先后各执行一次。
    private static final String FILTER_APPLIED = "__spring_security_customerFilter_filterApplied";
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        if(servletRequest.getAttribute(FILTER_APPLIED)!=null){
           filterChain.doFilter(servletRequest,servletResponse);
           return;
        }
     
        System.out.println("哎呦呵,来啦");
        //替换用户信息,具体替换步骤参考上一个替换,这个用户最好存入缓存,毕竟过滤器过滤的请求挺多,每次都要查询很坑的
        servletRequest.setAttribute(FILTER_APPLIED,true);
        filterChain.doFilter(servletRequest,servletResponse);
    }
}
 @Autowired
    private CustomerSecurityFilter customerSecurityFilter;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/","/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/chat")
                .permitAll()
                .and()
                .logout()
                .permitAll()
                .and()
                .addFilterBefore(customerSecurityFilter,SwitchUserFilter.class);
    }

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/100307.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java编译环境配置

    java编译环境配置1.设置PATH环境变量右击桌面上的计算机图标,单击属性菜单项,系统显示控制面板主页,单击高级系统设置,出现系统属性对话框,再单击高级,出现如下图所示的对话框。单击环境变量按钮,将看到如下图所示的环境变量对话框,通过该对话框可以修改或添加环境变量。上图所示的对话框上面的用户变量用于设置当前用户的环境变量,系统变量用于设置整个系统的环境变量。对于windows系统而言,名为pat…

    2022年6月2日
    41
  • 服务器做矿机使用_文件服务器搭建

    服务器做矿机使用_文件服务器搭建云服务器搭建矿机内容精选换一换在专属主机资源上创建云服务器失败,可能由以下原因造成:您所选择的云服务器规格不在您已有的专属主机支持范围内。各类型专属主机支持的云服务器规格请参见概述。各类型专属主机支持的云服务器规格请参见概述。您的专属主机资源不足,无法创建您所选择的云服务器规格。您可以查看专属主机的剩余vCPU和内存数量是否满足您所选择的云服务器规格。如果资源不足,您弹性云服务器(Elastic…

    2022年9月30日
    3
  • linux清除隐藏的挖矿程序

    linux清除隐藏的挖矿程序1.找出cpu高的程序,top找不到的话,用下面命令ps-aux–sort=-pcpu|head-102.杀掉相关进程kill-9pid3.查看crontab是否有定时任务4.删除相关命令[root@dbserverlib]#lsattrlibiacpkmn.so.3—-i——–e–libiacpkmn.so.3[root@dbserverlib]#chattr-ilibiacpkmn.so.3[root@dbserver

    2022年6月16日
    28
  • Git 常用命令总结

    Git 常用命令总结

    2021年10月18日
    41
  • Java基础

    Java基础

    2021年7月5日
    70
  • k8s安装、访问kubernetes-dashboard监控

    k8s安装、访问kubernetes-dashboard监控

    2021年5月13日
    153

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号