热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

springsecurity使用获得当前用户信息(四)

主要是通过Authentication封装publicinterfaceAuthenticationextendsPrincipal,Serializable{用来获取用户的权限。

主要是通过Authentication封装

public interface Authentication extends Principal, Serializable {
    //用来获取用户的权限。
    Collectionextends GrantedAuthority> getAuthorities();
    //方法用来获取用户凭证,一般来说就是密码。
    Object getCredentials();
    //方法用来获取用户携带的详细信息,可能是当前请求之类的东西。
    Object getDetails();
    //方法用来获取当前用户,可能是一个用户名,也可能是一个用户对象。
    Object getPrincipal();
    //当前用户是否认证成功。
    boolean isAuthenticated();

    void setAuthenticated(boolean var1) throws IllegalArgumentException;
}

如何获取

   @GetMapping("/hello")
    public String hello() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return "hello";
    }

getDetails方法

可以看到打印了用户id和sessionId信息

 @GetMapping("/hello")
    public String hello() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        WebAuthenticationDetails details = (WebAuthenticationDetails) authentication.getDetails();
        System.out.println(details);
        return "hello";
    }

打印

org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 127.0.0.1; SessionId: C1886FD11CACBAD7387B9273442BC212

源码

1.org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#attemptAuthentication

    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (this.postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        } else {
            String username = this.obtainUsername(request);
            String password = this.obtainPassword(request);
            if (username == null) {
                username = "";
            }

            if (password == null) {
                password = "";
            }

            username = username.trim();
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
            //为authRequest 的detail赋值 UsernamePasswordAuthenticationToken实现了Authentication
            this.setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
        }
    }

2.org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#setDetails

protected AuthenticationDetailsSource authenticatiOnDetailsSource= new WebAuthenticationDetailsSource();

 protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
            //UsernamePasswordAuthenticationToken是通过authenticationDetailsSource 构建的detail数据
            authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
        }

3.WebAuthenticationDetailsSource的定义

public class WebAuthenticationDetailsSource implements AuthenticationDetailsSource {
    public WebAuthenticationDetailsSource() {
    }

    public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
        //我们通过Authentication.getDetails()获取的就是WebAuthenticationDetails
        return new WebAuthenticationDetails(context);
    }
}

4.WebAuthenticationDetails定义

public class WebAuthenticationDetails implements Serializable {
    private static final long serialVersiOnUID= 520L;
    private final String remoteAddress;
    private final String sessionId;

    public WebAuthenticationDetails(HttpServletRequest request) {
        //从request获取ip
        this.remoteAddress = request.getRemoteAddr();
        //获取sessionId
        HttpSession session = request.getSession(false);
        this.sessiOnId= session != null ? session.getId() : null;
    }
}

自定义 

看上面源码我们知道入口是在UsernamePasswordAuthenticationFilter进行Authentication的detail设置的 如何构建detail对象 是委托给AuthenticationDetailsSource默认是WebAuthenticationDetailsSource

所以我们自定义就要自定义WebAuthenticationDetailsSource和封装数据的Dtail对象

通过自定优化《spring-security使用-更友好的方式扩展登录AuthenticationProvider(三)》 验证码校验逻辑

1.自定义的Detail对象

 */
public class MyWebAuthenticationDetails extends WebAuthenticationDetails {
    //封装提交的验证码信息
    private String code;
    private HttpServletRequest httpServletRequest;
    public MyWebAuthenticationDetails(HttpServletRequest request) {
        super(request);
        //获得验证码
        this.code=request.getParameter("code");
        this.httpServletRequest=request;
    }

    /**
     * 增加一个检查验证码的方法
     * @return
     */
    public boolean checkCode(){
        String verify_code = (String) httpServletRequest.getSession().getAttribute("verify_code");
        if (code == null || verify_code == null || !code.equals(verify_code)) {
            throw new AuthenticationServiceException("验证码错误");
        }
        return true;
    }

}

2.自定义构建对象

public class MyWebAuthenticationDetailsSource implements AuthenticationDetailsSource {
    @Override
    public MyWebAuthenticationDetails buildDetails(HttpServletRequest request) {
        return new MyWebAuthenticationDetails(request);
    }
}

3.使用自定义的构建对象替换默认的

    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .rememberMe()
                .key("system")
                .and()
                .formLogin()
                .authenticationDetailsSource(new MyWebAuthenticationDetailsSource())
                .usernameParameter("loginName")
                .passwordParameter("loginPassword")
                .defaultSuccessUrl("/hello")
                .failureForwardUrl("/loginFail")
                .failureUrl("/login.html")
                .permitAll()//不拦截
                .and()
                .csrf()//记得关闭
                .disable();
    }

 


推荐阅读
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Java实战之电影在线观看系统的实现
    本文介绍了Java实战之电影在线观看系统的实现过程。首先对项目进行了简述,然后展示了系统的效果图。接着介绍了系统的核心代码,包括后台用户管理控制器、电影管理控制器和前台电影控制器。最后对项目的环境配置和使用的技术进行了说明,包括JSP、Spring、SpringMVC、MyBatis、html、css、JavaScript、JQuery、Ajax、layui和maven等。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 开发笔记:Java是如何读取和写入浏览器Cookies的
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java是如何读取和写入浏览器Cookies的相关的知识,希望对你有一定的参考价值。首先我 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
author-avatar
cssic_630
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有