@Override
  protected AuthenticationInfo queryForAuthenticationInfo(
      AuthenticationToken token, LdapContextFactory contextFactory) throws NamingException {

    logger.debug(
        "queryForAuthenticationInfo, principal: {}, credentials: *****", token.getPrincipal());
    logger.debug("contextFactory : {}", contextFactory);

    try {
      if (token == null || token.getPrincipal() == null) {
        logger.info("No authentication token provided, will not try to authenticate..");
        return null;
      }

      LdapContext sysCtx = contextFactory.getSystemLdapContext();

      String objClsFilter = createObjectClassFilter(objectClasses);
      String userIdFilter = createAttributeFilter(userIdAttribute, token.getPrincipal().toString());

      String filter = mergeFiltersAND(objClsFilter, userIdFilter);

      NamingEnumeration<?> namingEnumeration =
          sysCtx.search(config.getUserLdapBaseDn(), filter, getSimpleSearchControls());

      while (namingEnumeration.hasMore()) {

        SearchResult result = (SearchResult) namingEnumeration.next();

        String dn = result.getNameInNamespace();

        try {
          contextFactory.getLdapContext(dn, token.getCredentials());

          return new SimpleAuthenticationInfo(dn, token.getCredentials(), "StaticRealm");

        } catch (Exception e) {
          logger.error(e.getMessage(), e);
        }
      }
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
    }

    return null;
  }
Exemple #2
0
 /**
  * Returns the {@link AuthenticationInfo} resulting from a Subject's successful LDAP
  * authentication attempt.
  *
  * <p>This implementation ignores the {@code ldapPrincipal}, {@code ldapCredentials}, and the
  * opened {@code ldapContext} arguments and merely returns an {@code AuthenticationInfo} instance
  * mirroring the submitted token's principal and credentials. This is acceptable because this
  * method is only ever invoked after a successful authentication attempt, which means the provided
  * principal and credentials were correct, and can be used directly to populate the (now verified)
  * {@code AuthenticationInfo}.
  *
  * <p>Subclasses however are free to override this method for more advanced construction logic.
  *
  * @param token the submitted {@code AuthenticationToken} that resulted in a successful
  *     authentication
  * @param ldapPrincipal the LDAP principal used when creating the LDAP connection. Unlike the
  *     token's {@link AuthenticationToken#getPrincipal() principal}, this value is usually a
  *     constructed User DN and not a simple username or uid. The exact value is depending on the
  *     configured <a
  *     href="http://download-llnw.oracle.com/javase/tutorial/jndi/ldap/auth_mechs.html">LDAP
  *     authentication mechanism</a> in use.
  * @param ldapCredentials the LDAP credentials used when creating the LDAP connection.
  * @param ldapContext the LdapContext created that resulted in a successful authentication. It can
  *     be used further by subclasses for more complex operations. It does not need to be closed -
  *     it will be closed automatically after this method returns.
  * @return the {@link AuthenticationInfo} resulting from a Subject's successful LDAP
  *     authentication attempt.
  * @throws NamingException if there was any problem using the {@code LdapContext}
  */
 @SuppressWarnings({"UnusedDeclaration"})
 protected AuthenticationInfo createAuthenticationInfo(
     AuthenticationToken token,
     Object ldapPrincipal,
     Object ldapCredentials,
     LdapContext ldapContext)
     throws NamingException {
   return new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), getName());
 }
Exemple #3
0
 // 登录信息和用户验证信息验证
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
     throws AuthenticationException {
   String username = (String) token.getPrincipal(); // 得到用户名
   String password = new String((char[]) token.getCredentials()); // 得到密码
   if (null != username && null != password) {
     return new SimpleAuthenticationInfo(username, password, getName());
   } else {
     return null;
   }
 }
Exemple #4
0
 @Override
 public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)
     throws AuthenticationException {
   String username = (String) token.getPrincipal(); // 得到用户名
   String password = new String((char[]) token.getCredentials()); // 得到用户密码
   if (!"zhang".equals(username)) {
     throw new UnknownAccountException(); // 如果用户名不对
   }
   if (!"123456".equals(password)) {
     throw new IncorrectCredentialsException();
   }
   // 如果身份认证成功,返回AuthenticationInfo实现
   return new SimpleAuthenticationInfo(username, password, getName());
 }
Exemple #5
0
 @Override
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
     throws AuthenticationException {
   String username = (String) token.getPrincipal(); // 得到用户名
   String password = new String((char[]) token.getCredentials()); // 得到密码
   if (!"zhang".equals(username)) {
     throw new UnknownAccountException(); // 如果用户名错误
   }
   if (!"123".equals(password)) {
     throw new IncorrectCredentialsException(); // 如果密码错误
   }
   // 如果身份认证验证成功,返回一个AuthenticationInfo实现;
   return new SimpleAuthenticationInfo(username, password, getName());
 }
  // 验证用户
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
      throws AuthenticationException {
    String loginName = (String) token.getPrincipal(); // 得到用户名
    String password = new String((char[]) token.getCredentials()); // 得到密码

    User user = new User();
    user.setLoginName(loginName);
    user.setPassword(password);
    User loginUser = adminUserDao.login(user.getLoginName(), user.getPassword());
    if (loginUser == null || loginUser.getId() <= 0) {
      throw new IncorrectCredentialsException("用户名或密码不正确!");
    }

    // 如果身份认证验证成功,返回一个 AuthenticationInfo 实现;
    return new SimpleAuthenticationInfo(loginName, password, getName());
  }
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
      throws AuthenticationException {
    User user = (User) token.getPrincipal();

    if (user == null) {
      throw new UnknownAccountException(
          ConstantsUtility.ERROR_MESSAGES.getString("userDoesNotExist"));
    } else if (!user.isActive()) {
      throw new LockedAccountException(ConstantsUtility.ERROR_MESSAGES.getString("userInactive"));
    } else if (user.isLocked()) {
      throw new LockedAccountException(ConstantsUtility.ERROR_MESSAGES.getString("userLocked"));
    }

    SimplePrincipalCollection principles = new SimplePrincipalCollection();
    principles.add(user, ConstantsUtility.OAUTH_REALM_NAME);
    return new SimpleAuthenticationInfo(principles, token.getCredentials());
  }
Exemple #8
0
  /**
   * This implementation opens an LDAP connection using the token's {@link
   * #getLdapPrincipal(org.apache.shiro.authc.AuthenticationToken) discovered principal} and
   * provided {@link AuthenticationToken#getCredentials() credentials}. If the connection opens
   * successfully, the authentication attempt is immediately considered successful and a new {@link
   * AuthenticationInfo} instance is {@link
   * #createAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken, Object, Object,
   * javax.naming.ldap.LdapContext) created} and returned. If the connection cannot be opened,
   * either because LDAP authentication failed or some other JNDI problem, an {@link
   * NamingException} will be thrown.
   *
   * @param token the submitted authentication token that triggered the authentication attempt.
   * @param ldapContextFactory factory used to retrieve LDAP connections.
   * @return an {@link AuthenticationInfo} instance representing the authenticated user's
   *     information.
   * @throws NamingException if any LDAP errors occur.
   */
  protected AuthenticationInfo queryForAuthenticationInfo(
      AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException {

    Object principal = token.getPrincipal();
    Object credentials = token.getCredentials();

    log.debug("Authenticating user '{}' through LDAP", principal);

    principal = getLdapPrincipal(token);

    LdapContext ctx = null;
    try {
      ctx = ldapContextFactory.getLdapContext(principal, credentials);
      // context was opened successfully, which means their credentials were valid.  Return the
      // AuthenticationInfo:
      return createAuthenticationInfo(token, principal, credentials, ctx);
    } finally {
      LdapUtils.closeContext(ctx);
    }
  }
  @Override
  protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
    String authorizationHeader = getAuthzHeader(request);
    if (authorizationHeader == null || authorizationHeader.length() == 0) {
      // Create an empty authentication token since there is no
      // Authorization header.
      return createToken("", "", request, response);
    }

    if (log.isDebugEnabled()) {
      log.debug("Attempting to execute login with headers [" + authorizationHeader + "]");
    }

    String[] prinCred = getPrincipalsAndCredentials(authorizationHeader, request);
    if (prinCred == null || prinCred.length < 2) {
      // Create an authentication token with an empty password,
      // since one hasn't been provided in the request.
      String username = prinCred == null || prinCred.length == 0 ? "" : prinCred[0];
      return createToken(username, "", request, response);
    }

    String username = prinCred[0];
    String password = prinCred[1];
    String sf = SF.replace("{0}", username);
    try {
      AuthenticationToken at =
          new UsernamePasswordToken(MessagingServletConfig.ldapUser, MessagingServletConfig.ldapPw);
      InitialLdapContext ctx =
          (InitialLdapContext) jlc.getLdapContext(at.getPrincipal(), at.getCredentials());
      SearchResult result = searchUnique(sf, ctx);
      Attributes attrs = result.getAttributes();
      username =
          "******" + attrs.get("cn").get(0) + ",ou=gateways," + MessagingServletConfig.ldapBaseDn;
      ctx.close();
    } catch (IllegalStateException | NamingException e) {
      e.printStackTrace();
      log.warn(username + "not found in directory");
    }
    return createToken(username, password, request, response);
  }
  /* (non-Javadoc)
   * @see org.apache.shiro.authc.credential.CredentialsMatcher#doCredentialsMatch(org.apache.shiro.authc.AuthenticationToken, org.apache.shiro.authc.AuthenticationInfo)
   */
  @Override
  public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
    if (token instanceof AutologinToken) {
      log.debug("Auto-logging in {}", token.getPrincipal());
      return true;
    }
    if (token.getCredentials() == null) {
      log.warn("Rejecting null token credentials for {}", token.getPrincipal());
      return false;
    }
    if (info.getCredentials() == null) {
      log.warn("Rejecting null stored credentials for {}", info.getPrincipals());
      return false;
    }
    final String host =
        token instanceof HostAuthenticationToken
            ? ((HostAuthenticationToken) token).getHost()
            : null;

    final String passwordToken = String.valueOf((char[]) token.getCredentials());
    final String userPassword = info.getCredentials().toString();
    final Matcher matcher = passwordPattern.matcher(userPassword);
    if (matcher.matches()) {
      final String algorithm = matcher.group(1);
      final String encodedBase64 = matcher.group(2);
      switch (algorithm) {
        case "SSHA":
          final byte[] encoded = Base64.decodeBase64(encodedBase64);
          log.trace("Decoded {} into {} bytes", encodedBase64, encoded.length);
          if (encoded.length < 21) {
            log.error(
                "Encoded length must be at least 21 bytes, 20-byte password and at least 1-byte salt, for {}",
                info.getPrincipals());
            return false;
          }
          final byte[] digest = Arrays.copyOf(encoded, 20);
          final byte[] salt = Arrays.copyOfRange(encoded, 20, encoded.length);
          byte[] digestToken = HashedPasswordUtils.calculateSsha(passwordToken, salt);
          boolean sshaMatches = Arrays.equals(digestToken, digest);
          log.debug(
              "Matching credentials for {} host {} using SSHA: {}",
              token.getPrincipal(),
              host,
              sshaMatches);
          return sshaMatches;
        case "PLAIN":
          boolean plainMatches = encodedBase64.equals(passwordToken);
          log.debug(
              "Matching credentials for {} host {} using PLAIN: {}",
              token.getPrincipal(),
              host,
              plainMatches);
          return plainMatches;
        default:
          log.error("Unknown password algorithm {} for {}", algorithm, info.getPrincipals());
          return false;
      }
    } else if (userPassword.startsWith("$")) {
      final BCryptPasswordService bCryptPasswordService = new BCryptPasswordService();
      return bCryptPasswordService.passwordsMatch(passwordToken, userPassword);
    } else {
      log.error("Unknown password syntax for {}", info.getPrincipals());
      return false;
    }
  }