Icce___ 2020-04-20 16:31 采纳率: 66.7%
浏览 1655
已结题

springsecurity + aop 如何在切点中获取当前用户信息

security实现用户认证,做了一个切面通过注释来给方法加日志打印,现在想要在日志打印出每次调用方法的当前用户,在切面中直接使用

SecurityContextHolder.getContext().getAuthentication()

获取不到对象

在security认证成功的回调方法里我是能正常获得信息的,下面是代码:

AjaxAuthenticationSuccessHandler.java

@Component
public class AjaxAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    ....//省略其他代码
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=utf-8");
        SysUser userDetails = (SysUser)authentication.getPrincipal();
                //这个userDetails是有想要的内容的
       ....//省略其他代码
    }
    }

WebSecurityConfig.java

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    SecurityService securityService;
    @Autowired
    UrlFilterInvocationSecurityMetadataSource urlFilterInvocationSecurityMetadataSource;
    @Autowired
    UrlAccessDecisionManager urlAccessDecisionManager;
    @Autowired
    AuthenticationAccessDeniedHandler authenticationAccessDeniedHandler;
    @Autowired
    AjaxAuthenticationSuccessHandler authenticationSuccessHandler;  // 登录成功返回的 JSON 格式数据给前端(否则为 html)
    @Autowired
    AjaxAuthenticationFailureHandler authenticationFailureHandler;  //  登录失败返回的 JSON 格式数据给前端(否则为 html)
    @Autowired
    AjaxAuthenticationEntryPoint authenticationEntryPoint;
    @Autowired
    ValidateCodeFilter validateCodeFilter;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(securityService).passwordEncoder(new MyPasswordEncoder());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        //设置哪些路径不进行权限控制,添加**允许所有地址可访问
        web.ignoring().antMatchers("/console","/index**","/resources/**","/druid/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(validateCodeFilter,UsernamePasswordAuthenticationFilter.class).
        csrf().disable()
        .httpBasic().authenticationEntryPoint(authenticationEntryPoint)
        .and()
        .formLogin()
        .usernameParameter("username")
        .passwordParameter("password")
        .failureHandler(authenticationFailureHandler)
        .successHandler(authenticationSuccessHandler)
        .permitAll()

        .and()
        .logout()
        .permitAll()

        .and()
        .exceptionHandling()
        .accessDeniedHandler(authenticationAccessDeniedHandler)

        .and()
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
            @Override
            public <O extends FilterSecurityInterceptor> O postProcess(O o) {
                o.setSecurityMetadataSource(urlFilterInvocationSecurityMetadataSource);
                o.setAccessDecisionManager(urlAccessDecisionManager);
                return o;
            }
        });
    }
}

MyLogAspect.java

@Aspect
@Component
public class MyLogAspect {
    private final Logger logger = LoggerFactory.getLogger(MyLogAspect.class);

    //定义切点
    @Pointcut("@annotation(xxx)")
    public void logPointCut() {
    }

    /**
     * 在方法调用之前调用通知
     *
     * @param joinPoint 切点
     */
    @Before("logPointCut()")
    public void doBefore(JoinPoint joinPoint) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        System.out.println(SecurityContextHolder.getContext().getAuthentication());
       //输出为null
    }
}

网上查资料好像是说在认证完之后会清空SecurityContextHolder?那我在其他的类里面要获取当前用户该怎么办呢?得自己写session存吗?感觉应该是哪里没搞对,有大佬指教一下吗?

找到问题了,是在security的过滤器中选择不进行权限控制的路径里把我测试用的访问路径也加进去了,所以导致拿不到用户。参考帖子:https://blog.csdn.net/u012702547/article/details/105237938

WebSecurityConfig文件中的

@Override
    public void configure(WebSecurity web) throws Exception {
        //设置哪些路径不进行权限控制,添加**允许所有地址可访问
        web.ignoring().antMatchers("/console","/index**","/resources/**","/druid/**");
    }

如果要拿到当前用户,接口地址就不能在这里面,可找死我了~

  • 写回答

2条回答 默认 最新

  • 关注
    评论

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘