• 如何在spring security手动自定义用户认证SecurityContextHolder设置Authentication?


    正常情况下,我们登录都是用账号密码登录,spring security的登录逻辑是在UsernamePasswordAuthenticationFilter里,这个类继承了AbstractAuthenticationProcessingFilter,我们如果想实现自己的登陆判断业务逻辑,可以继承AbstractAuthenticationProcessingFilter来实现,然后 http.addFilterAt(new MyUsernamePasswordFilter(), UsernamePasswordAuthenticationFilter.class) 这样就替换成自己的filter了。

    UsernamePasswordAuthenticationFilter里的这段源码会把登录成功后的用户token信息放入上下文。

     1 public Authentication attemptAuthentication(HttpServletRequest request,
     2             HttpServletResponse response) throws AuthenticationException {
     3     if (postOnly && !request.getMethod().equals("POST")) {
     4         throw new AuthenticationServiceException(
     5             "Authentication method not supported: " + request.getMethod());
     6     }
     7 
     8     String username = obtainUsername(request);
     9     String password = obtainPassword(request);
    10 
    11     if (username == null) {
    12         username = "";
    13     }
    14 
    15     if (password == null) {
    16         password = "";
    17     }
    18 
    19     username = username.trim();
    20 
    21     UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
    22         username, password);
    23 
    24     // Allow subclasses to set the "details" property
    25     setDetails(request, authRequest);
    26 
    27     return this.getAuthenticationManager().authenticate(authRequest);
    28 }

    如果我不用上面的方法,自己在某个方法里需要实现登录并且session共享的功能,可以这样写。

     1 UserInfo userInfo = (UserInfo) userDetailsService.loadUserByUsername(username);
     2 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userInfo, password, userInfo.getAuthorities());
     3 
     4 // 设置authentication中details
     5 authentication.setDetails(new WebAuthenticationDetails(request));
     6 
     7 SecurityContextHolder.getContext().setAuthentication(authentication);
     8 
     9 // 在session中存放security context,方便同一个session中控制用户的其他操作
    10 HttpSession session = request.getSession(true);
    11 // 这一步很关键,不能省略掉
    12 session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());

    SecurityContextHolder是SpringSecurity最基本的组件了,是用来存放SecurityContext的对象,默认是使用ThreadLocal实现的,这样就保证了本线程内所有的方法都可以获得SecurityContext对象。

    SecurityContextHolder可以工作在以下三种模式之一:
    1)MODE_THREADLOCAL (缺省工作模式)
    2)MODE_GLOBAL
    3) MODE_INHERITABLETHREADLOCAL
    4) 修改SecurityContextHolder的工作模式有两种方法 :
    a: 设置一个系统属性(system.properties) : spring.security.strategy;
    SecurityContextHolder会自动从该系统属性中尝试获取被设定的工作模式
    b: 调用SecurityContextHolder静态方法setStrategyName()

    SecurityContextHolder存储SecurityContext的方式(默认就是mode_threadlocal)

    使用SecurityContextHolder获取当前登录的用户信息
    在SecurityContextHolder中保存的是当前访问者的信息。Spring Security使用一个Authentication对象来表示这个信息。一般情况下,我们都不需要创建这个对象,在登录过程中,Spring Security已经创建了该对象并帮我们放到了SecurityContextHolder中。从SecurityContextHolder中获取这个对象也是很简单的。

     1 SecurityContextHolder.getContext().getAuthentication(); 

    这样在其它接口里就可以拿到上面设置的用户信息了。

  • 相关阅读:
    关于表单的练习和基本登录界面的制作
    css3 闪光hover
    步步为营:Asp.Net序列化与反序列化
    步步为营:Asp.Net客户端存Cookie服务端取
    步步为营:Asp.Net使用HttpWebRequest通知,抓取,采集
    PHP学习(二):PHP的魔术方法
    步步为营:SQL通用存储过程分页
    PHP学习(三):PHP面向对象概念
    PHP学习(四):PHP5.3版本的新特性
    步步为营:Asp.Net转换Unix时间戳
  • 原文地址:https://www.cnblogs.com/shamo89/p/16803349.html
Copyright © 2020-2023  润新知