<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      若依--自定義loadUserByUsername參數入參

      若依--自定義loadUserByUsername參數入參

      前言

      在使用若依的Security的登錄認證時,默認只能使用用戶名去查詢sysUser,當我需要額外的參數去查詢用戶數據時,只能將用戶名和額外參數組成json或者特定字符拼接,然后在UserDetailsServiceImplloadUserByUsername方法自定義查詢數據。但是似乎不太優雅。

      代碼如下

      SysLoginService

      登錄service層的代碼,使用自定義的CustomUsernamePasswordAuthenticationToken,調用clientLoginAuthProvider自定義實現類的認證;

      ......
          @Resource
          private ClientLoginAuthProvider clientLoginAuthProvider;
      public String appLogin(String username, String password, Long schoolId) {
              // 登錄前置校驗
              loginPreCheck(username, password);
              // 用戶驗證
              Authentication authentication = null;
              //userService.checkStudent(username);
              try
              {
                  CustomUsernamePasswordAuthenticationToken authenticationToken = new CustomUsernamePasswordAuthenticationToken(username, password,schoolId);
                  //UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
                  AuthenticationContextHolder.setContext(authenticationToken);
                  // 該方法會去調用ClientUserDetailsService.loadUserByUsername
                  authentication = clientLoginAuthProvider.authenticate(authenticationToken);
              }
              catch (Exception e)
              {
                  if (e instanceof BadCredentialsException)
                  {
                      AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                      throw new UserPasswordNotMatchException();
                  }
                  else
                  {
                      AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                      throw new ServiceException(e.getMessage());
                  }
              }
              finally
              {
                  AuthenticationContextHolder.clearContext();
              }
              AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
              LoginUser loginUser = (LoginUser) authentication.getPrincipal();
              recordLoginInfo(loginUser.getUserId());
              // 生成token
              return tokenService.createToken(loginUser);
          }
      ......
      

      一、CustomUsernamePasswordAuthenticationToken

      public class CustomUsernamePasswordAuthenticationToken extends UsernamePasswordAuthenticationToken {
          private final Long schoolId;
      
          public CustomUsernamePasswordAuthenticationToken(Object principal, Object credentials, Long schoolId) {
              super(principal, credentials);
              this.schoolId = schoolId;
          }
      
          public Long getSchoolId() {
              return schoolId;
          }
      }
      

      二、自定義ClientUserDetailsService 以及實現類ClientUserDetailsServiceImpl

      接口:

      public interface ClientUserDetailsService{
          UserDetails loadUserByUsername(String username,Long SchoolId) throws UsernameNotFoundException;
      }
      

      實現類:

      @Service("clientUserDetailsService")
      public class ClientUserDetailsServiceImpl implements ClientUserDetailsService{
          private static final Logger log = LoggerFactory.getLogger(ClientUserDetailsServiceImpl.class);
          @Resource
          private SysUserMapper sysUserMapper;
          @Autowired
          private SysPasswordService passwordService;
          @Autowired
          private SysPermissionService permissionService;
          @Override
          public UserDetails loadUserByUsername(String username, Long schoolId) throws UsernameNotFoundException {
              // 此處即可自定義查詢用戶
              SysUser user = sysUserMapper.getStudentByUserName(username,schoolId);
              if (StringUtils.isNull(user))
              {
                  log.info("登錄用戶:{} 不存在.", username);
                  throw new ServiceException("登錄用戶:" + username + " 不存在");
              }
              else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
              {
                  log.info("登錄用戶:{} 已被刪除.", username);
                  throw new ServiceException("對不起,您的賬號:" + username + " 已被刪除");
              }
              else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
              {
                  log.info("登錄用戶:{} 已被停用.", username);
                  throw new ServiceException("對不起,您的賬號:" + username + " 已停用");
              }
      
              passwordService.validate(user);
      
              return createLoginUser(user);
          }
      
          public UserDetails createLoginUser(SysUser user)
          {
              return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
          }
      }
      

      三、ClientLoginAuthProvider

      內容和DaoAuthenticationProvider中的一樣 只是添加了ClientUserDetailsService,在retrieveUser方法中調用我們自己的實現方法

      public class ClientLoginAuthProvider extends AbstractUserDetailsAuthenticationProvider {
      
      
          private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";
      
          private PasswordEncoder passwordEncoder;
      
          /**
           * The password used to perform {@link PasswordEncoder#matches(CharSequence, String)}
           * on when the user is not found to avoid SEC-2056. This is necessary, because some
           * {@link PasswordEncoder} implementations will short circuit if the password is not
           * in a valid format.
           */
          private volatile String userNotFoundEncodedPassword;
      
          private ClientUserDetailsService userDetailsService;
      
          private UserDetailsPasswordService userDetailsPasswordService;
      
          public ClientLoginAuthProvider(ClientUserDetailsService clientUserDetailsService) {
              this.userDetailsService = clientUserDetailsService;
              setPasswordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder());
          }
      
          @Override
          @SuppressWarnings("deprecation")
          protected void additionalAuthenticationChecks(UserDetails userDetails,
                                                        UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
              if (authentication.getCredentials() == null) {
                  this.logger.debug("Failed to authenticate since no credentials provided");
                  throw new BadCredentialsException(this.messages
                          .getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
              }
              String presentedPassword = authentication.getCredentials().toString();
              if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
                  this.logger.debug("Failed to authenticate since password does not match stored value");
                  throw new BadCredentialsException(this.messages
                          .getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
              }
          }
      
          @Override
          protected void doAfterPropertiesSet() {
              Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
          }
      
          @Override
          protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
              CustomUsernamePasswordAuthenticationToken auth = (CustomUsernamePasswordAuthenticationToken) authentication;
      
              //多個參數
              UserDetails loadedUser = userDetailsService.loadUserByUsername(username,auth.getSchoolId());
      
              if (loadedUser == null) {
                  throw new InternalAuthenticationServiceException(
                          "UserDetailsService returned null, which is an interface contract violation");
              }
              return loadedUser;
          }
      
          @Override
          protected Authentication createSuccessAuthentication(Object principal, Authentication authentication,
                                                               UserDetails user) {
              boolean upgradeEncoding = this.userDetailsPasswordService != null
                      && this.passwordEncoder.upgradeEncoding(user.getPassword());
              if (upgradeEncoding) {
                  String presentedPassword = authentication.getCredentials().toString();
                  String newPassword = this.passwordEncoder.encode(presentedPassword);
                  user = this.userDetailsPasswordService.updatePassword(user, newPassword);
              }
              return super.createSuccessAuthentication(principal, authentication, user);
          }
      
          private void prepareTimingAttackProtection() {
              if (this.userNotFoundEncodedPassword == null) {
                  this.userNotFoundEncodedPassword = this.passwordEncoder.encode(USER_NOT_FOUND_PASSWORD);
              }
          }
      
          private void mitigateAgainstTimingAttack(UsernamePasswordAuthenticationToken authentication) {
              if (authentication.getCredentials() != null) {
                  String presentedPassword = authentication.getCredentials().toString();
                  this.passwordEncoder.matches(presentedPassword, this.userNotFoundEncodedPassword);
              }
          }
      
          /**
           * Sets the PasswordEncoder instance to be used to encode and validate passwords. If
           * not set, the password will be compared using
           * {@link PasswordEncoderFactories#createDelegatingPasswordEncoder()}
           * @param passwordEncoder must be an instance of one of the {@code PasswordEncoder}
           * types.
           */
          public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
              Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
              this.passwordEncoder = passwordEncoder;
              this.userNotFoundEncodedPassword = null;
          }
      
          protected PasswordEncoder getPasswordEncoder() {
              return this.passwordEncoder;
          }
      
          public void setUserDetailsService(ClientUserDetailsService userDetailsService) {
              this.userDetailsService = userDetailsService;
          }
      
          protected ClientUserDetailsService getUserDetailsService() {
              return this.userDetailsService;
          }
      
          public void setUserDetailsPasswordService(UserDetailsPasswordService userDetailsPasswordService) {
              this.userDetailsPasswordService = userDetailsPasswordService;
          }
      
      }
      

      四、SecurityConfig

      然后在SecurityConfig中添加ClientUserDetailsService注入,并且把ClientLoginAuthProvider注入到容器中

      @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
      public class SecurityConfig extends WebSecurityConfigurerAdapter
      {
          ......
          @Resource
          private ClientUserDetailsService clientUserDetailsService;
          
          ......
      
          @Bean
          public ClientLoginAuthProvider clientLoginAuthProvider(){
              ClientLoginAuthProvider provider = new ClientLoginAuthProvider(clientUserDetailsService);
              provider.setPasswordEncoder(bCryptPasswordEncoder());
              return provider;
          }
      
      }
      

      然后我們原來的接口能登錄,新添加的接口也能登錄了。

      posted @ 2023-08-01 22:56  嗶~嗶~嗶  閱讀(931)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 欧美日韩精品一区二区视频| 蜜臀一区二区三区精品免费| 天堂在线最新版av观看| 久久一日本综合色鬼综合色 | 日韩人妻少妇一区二区三区| 亚洲国模精品一区二区| 熟女少妇精品一区二区| 亚洲国产精品第一区二区| 亚洲一区二区三午夜福利| 2022最新国产在线不卡a| 成人亚洲精品一区二区三区 | 日本一区不卡高清更新二区| 一区二区三区四区国产综合| 无码人妻一区二区三区AV| 亚洲av日韩av中文高清性色| 精品国产乱码久久久久夜深人妻| 久久精品夜色国产亚洲av| 国产一区二区高清不卡| 国语自产精品视频在线看| 一区二区在线观看成人午夜| 国产亚洲精品第一综合| 国产精品一区在线蜜臀| 国产精品久久久久aaaa| 亚洲黄色第一页在线观看| 色欲av无码一区二区人妻| 亚洲国产日韩一区三区| 亚洲日韩性欧美中文字幕| 日韩V欧美V中文在线| 国产在线乱子伦一区二区| 高潮videossex潮喷| 婷婷丁香五月六月综合激情啪| 国产一区二区三区色成人| 国产精品原创不卡在线| 激情六月丁香婷婷四房播| 欧美人与禽2o2o性论交| 春色校园综合人妻av| 亚洲国产高清av网站| 无码国内精品久久人妻蜜桃| 亚洲蜜臀av乱码久久| 亚洲av伊人久久综合性色| 综合色天天久久|