Java语法:重写第三方类的方法和第三方接口实现类的不同

一、前言

        这里以oauth2协议+springSecurity框架的账户密码和微信扫码登陆为例。一方面是密码登录改写UserDeatilService的实现方法loadUserByUsername();

另一方面是改写类DaoAuthenticationProvider的方法additionalAuthenticationChecks()。

二、区别

2.1

        UserDeatilService的实现方法loadUserByUsername()改写 由于UserDeatilService在第三方包中是已经注入了 改写了方法也会自动生效【当调用这个方法的时候】

2.2 

        改写类DaoAuthenticationProvider的方法additionalAuthenticationChecks(),由于类的改写是继承的方式,自己改写的类,第三方包是没有办法获取的,只在本地生效,因此:1、需要自己注入到bean中,这样第三方包才能在ico中获取重写的类 2、需要在调用这个类的地方换成自己写的类 不然还是默认使用第三方的类

代码示例:

改写UserDeatilService的实现方法loadUserByUsername()

package com.xuecheng.ucenter.service.impl;

import com.alibaba.fastjson.JSON;
import com.xuecheng.ucenter.mapper.XcUserMapper;
import com.xuecheng.ucenter.model.dto.AuthParamsDto;
import com.xuecheng.ucenter.model.dto.XcUserExt;
import com.xuecheng.ucenter.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author Mr.Lan
 * @version 1.0
 * @ClassName UserServiceImpl$
 * @description TODO
 * @date 2024/4/13 21:00
 **/
@Slf4j
@Service
public class UserServiceImpl implements UserDetailsService {
    @Autowired
    XcUserMapper xcUserMapper;

    @Autowired
    ApplicationContext applicationContext;



    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {  //username和password的校验目前不清楚逻辑

//        这里是生成令牌 用authParamsDto接口请求参数
        AuthParamsDto authParamsDto = null;
        try {
            //将认证参数转为AuthParamsDto类型
            authParamsDto = JSON.parseObject(s, AuthParamsDto.class);
        } catch (Exception e) {
            log.info("认证请求不符合项目要求:{}",s);
            throw new RuntimeException("认证请求数据格式不对");
        }

        /**
         *  原来/auth/oauth/token?client_id=XcWebApp&client_secret=XcWebApp&grant_type=password&username=t1&password=111111
         *  其中String s 获取的变量是username
         * 现在解析json传那么传的username也是json串 后面服务解析的也是变量userName(只是一个名字具体定义看自己)
         *userName=   json串
         *
        **
        * @author Mr.Lan
        * @Description TODO
        * @Date   17:20
        * @Param [s]
        * @return org.springframework.security.core.userdetails.UserDetails
        **/

        //获取认证类型
        String authType = authParamsDto.getAuthType();
        //根据认证类型从容器中取出指定的bean
        String beanName = authType + "_authservice";
        AuthService authService = applicationContext.getBean(beanName, AuthService.class);
        //调用统一的excute方法完成认证
        XcUserExt user = authService.execute(authParamsDto);
        //封装用户信息XcUserExt成userDetails


//        XcUser user = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, authParamsDto.getUsername()));
//        if (user == null) {
//            //返回空表示用户不存在
//            return null;
//        }
//        //取出数据库存储的正确密码
//        String password = user.getPassword();
        //用户权限,如果不加报Cannot pass a null GrantedAuthority collection
        return getUserDetails(user);
    }

    private UserDetails getUserDetails(XcUserExt user) {
        //获取用户权限
        List<String> menuList = xcUserMapper.getMenuList(user.getId());
        //List转数组
        String[] Premissions = menuList.toArray(new String[0]);
//        String[] authorities = {"test"};
        String[] authorities = Premissions;
        //创建UserDetails对象,权限信息待实现授权功能时再向UserDetail中加入
        //withUsername()是存储一个变量可以是用户名也可以是json串
//        user.setPermissions(Arrays.stream(authorities).collect(Collectors.toList()));
        //已将校验密码了 密码不必存 安全性考虑
        user.setPassword(null);
        String userJson = JSON.toJSONString(user);
        //这里username、password是token中的内容password默认在additionalAuthenticationChecks中校验 但是additionalAuthenticationChecks已将被覆盖了
        //所以password已经失去校验功能 随便填
        UserDetails userDetails = User.withUsername(userJson).password("1").authorities(authorities).build();
        return userDetails;
    }




}

改写类DaoAuthenticationProvider的方法additionalAuthenticationChecks()并注入、调用的地方更新

注入:

@Component
public class DaoAuthenticationProviderCustom extends DaoAuthenticationProvider {

    @Autowired
    public void setUserDetailsService(UserDetailsService userDetailsService) {
        super.setUserDetailsService(userDetailsService);
    }

    //取消校验
    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {

    }
}

    更新:

package com.xuecheng.auth.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author Mr.M
 * @version 1.0
 * @description 安全管理配置
 * @date 2022/9/26 20:53
 */
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DaoAuthenticationProviderCustom daoAuthenticationProviderCustom;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(daoAuthenticationProviderCustom);
    }

//        配置用户信息服务
//    @Bean
//    public UserDetailsService userDetailsService() {
//        //这里配置用户信息,这里暂时使用这种方式将用户存储在内存中
//        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
//        manager.createUser(User.withUsername("zhangsan").password("123").authorities("p1").build());
//        manager.createUser(User.withUsername("lisi").password("456").authorities("p2").build());
//        return manager;
//    }

    @Bean
    public PasswordEncoder passwordEncoder() {
//        //密码为明文方式
//        return NoOpPasswordEncoder.getInstance();
        //密码为
        return new BCryptPasswordEncoder();
    }

    //配置安全拦截机制
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/r/**").authenticated()//访问/r开始的请求需要认证通过
                .anyRequest().permitAll()//其它请求全部放行
                .and()
                .formLogin().successForwardUrl("/login-success");//登录成功跳转到/login-success
    }

    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }




}

三、总结

        很多技术栈没必要将代码完完整整的敲出来,搞清楚原理,然后会CV使用以及派排查出现的问题就够了。面试和工作都是如此,没人问你怎么做出来的细节 ,只关心你懂不懂,能不能再现有的资源整合下作出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟蹦迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值