org.apache.shiro.authc.credential.HashedCredentialsMatcher类的使用及代码示例

x33g5p2x  于2022-01-20 转载在 其他  
字(16.1k)|赞(0)|评价(0)|浏览(119)

本文整理了Java中org.apache.shiro.authc.credential.HashedCredentialsMatcher类的一些代码示例,展示了HashedCredentialsMatcher类的具体用法。这些代码示例主要来源于Github/Stackoverflow/Maven等平台,是从一些精选项目中提取出来的代码,具有较强的参考意义,能在一定程度帮忙到你。HashedCredentialsMatcher类的具体详情如下:
包路径:org.apache.shiro.authc.credential.HashedCredentialsMatcher
类名称:HashedCredentialsMatcher

HashedCredentialsMatcher介绍

[英]A HashedCredentialMatcher provides support for hashing of supplied AuthenticationToken credentials before being compared to those in the AuthenticationInfo from the data store.

Credential hashing is one of the most common security techniques when safeguarding a user's private credentials (passwords, keys, etc). Most developers never want to store their users' credentials in plain form, viewable by anyone, so they often hash the users' credentials before they are saved in the data store.

This class (and its subclasses) function as follows:

  1. Hash the AuthenticationToken credentials supplied by the user during their login.
  2. Compare this hashed value directly with the AuthenticationInfo credentials stored in the system (the stored account credentials are expected to already be in hashed form).
  3. If these two values are #equals(Object,Object), the submitted credentials match, otherwise they do not.

Salting and Multiple Hash Iterations Because simple hashing is usually not good enough for secure applications, this class also supports 'salting' and multiple hash iterations. Please read this excellent Hashing Java article to learn about salting and multiple iterations and why you might want to use them. (Note of sections 5 "Why add salt?" and 6 "Hardening against the attacker's attack"). We should also note here that all of Shiro's Hash implementations (for example, org.apache.shiro.crypto.hash.Md5Hash, org.apache.shiro.crypto.hash.Sha1Hash, etc) support salting and multiple hash iterations via overloaded constructors.

Real World Case Study

In April 2010, some public Atlassian Jira and Confluence installations (Apache Software Foundation, Codehaus, etc) were the target of account attacks and user accounts were compromised. The reason? Jira and Confluence at the time did not salt user passwords and attackers were able to use dictionary attacks to compromise user accounts (Atlassian has since fixed the problem of course).

The lesson?

ALWAYS, ALWAYS, ALWAYS SALT USER PASSWORDS!

Salting

Prior to Shiro 1.1, salts could be obtained based on the end-user submitted AuthenticationToken via the now-deprecated #getSalt(org.apache.shiro.authc.AuthenticationToken) method. This however could constitute a security hole since ideally salts should never be obtained based on what a user can submit. User-submitted salt mechanisms are much more susceptible to dictionary attacks and SHOULD NOT be used in secure systems. Instead salts should ideally be a secure randomly-generated number that is generated when the user account is created. The secure number should never be disseminated to the user and always kept private by the application.

Shiro 1.1

As of Shiro 1.1, it is expected that any salt used to hash the submitted credentials will be obtained from the stored account information (represented as an AuthenticationInfo instance). This is much more secure because the salt value remains private to the application (Shiro will never store this value).

To enable this, Realms should return SaltedAuthenticationInfo instances during authentication. HashedCredentialsMatcher implementations will then use the provided org.apache.shiro.authc.SaltedAuthenticationInfo#getCredentialsSalt for hashing. To avoid security risks, it is highly recommended that any existing Realm implementations that support hashed credentials are updated to return SaltedAuthenticationInfo instances as soon as possible.

Shiro 1.0 Backwards Compatibility

Because of the identified security risk, Realm implementations that support credentials hashing should be updated to return SaltedAuthenticationInfo instances as soon as possible.

If this is not possible for some reason, this class will retain 1.0 backwards-compatible behavior of obtaining the salt via the now-deprecated #getSalt(AuthenticationToken) method. This method will only be invoked if a Realm does not return SaltedAuthenticationInfo instances and #isHashSalted() is true. But please note that the #isHashSalted() property and the #getSalt(AuthenticationToken) methods will be removed before the Shiro 2.0 release.

Multiple Hash Iterations

If you hash your users' credentials multiple times before persisting to the data store, you will also need to set this class's #setHashIterations(int) property. See the Hashing Java article's "Hardening against the attacker's attack" section to learn more about why you might want to use multiple hash iterations. MD5 & SHA-1 Notice MD5 and SHA-1 algorithms are now known to be vulnerable to compromise and/or collisions (read the linked pages for more). While most applications are ok with either of these two, if your application mandates high security, use the SHA-256 (or higher) hashing algorithms and their supporting CredentialsMatcher implementations.
[中]HashedCredentialMatcher提供对提供的AuthenticationToken凭据进行哈希处理的支持,然后再与来自数据存储的AuthenticationInfo中的凭据进行比较。
凭证哈希是保护用户私人凭证(密码、密钥等)时最常用的安全技术之一。大多数开发人员从不希望以任何人都可以查看的简单形式存储用户凭据,因此他们通常在将用户凭据保存到数据存储中之前对其进行散列。
此类(及其子类)的功能如下:
1.散列用户在登录期间提供的AuthenticationToken凭据。
1.直接将此哈希值与存储在系统中的AuthenticationInfo凭据进行比较(存储的帐户凭据应已采用哈希形式)。
1.如果这两个值#等于(Object,Object),则提交的凭据匹配,否则不匹配。
satting和多个Hash迭代因为简单的Hash对于安全的应用程序来说通常不够好,所以这个类还支持“satting”和多个Hash迭代。请阅读这篇优秀的Hashing Java article,了解盐析和多次迭代,以及为什么您可能想要使用它们。(第5节“为什么要加盐?”和6“加强对攻击者的攻击”)。我们还应该注意,Shiro的所有哈希实现(例如,org.apache.Shiro.crypto.Hash.Md5Hash、org.apache.Shiro.crypto.Hash.Sha1Hash等)都支持通过重载构造函数进行salt和多次哈希迭代。
#####现实世界案例研究
在2010年4月,一些公共亚特兰西JIRA和汇合设施(Apache软件基金会,科德豪斯等)是账户攻击的目标,用户账户受到损害。原因是什么?Jira和Confluence当时没有攻击用户密码,攻击者能够使用字典攻击来破坏用户帐户(Atlassian从fixed the problem起就开始攻击)。
教训?
总是,总是,总是盐用户密码!
####腌制
在Shiro 1.1之前,可以基于最终用户提交的AuthenticationToken,通过现在已弃用的#getSalt(org.apache.Shiro.authc.AuthenticationToken)方法获得SALT。然而,这可能构成一个安全漏洞,因为在理想情况下,不应根据用户可以提交的内容获取盐。用户提交的salt机制更容易受到字典攻击,不应在安全系统中使用。理想情况下,salts应该是在创建用户帐户时生成的安全随机生成的数字。安全号码不应传播给用户,且应用程序应始终将其保密。
#####Shiro 1.1
从Shiro 1.1开始,用于散列提交的凭据的任何salt都将从存储的帐户信息(表示为AuthenticationInfo实例)中获得。这更加安全,因为salt值对于应用程序来说是私有的(Shiro永远不会存储这个值)。
要启用此功能,域应在身份验证期间返回SaltedAuthenticationInfo实例。HashedCredentialsMatcher实现将使用提供的组织。阿帕奇。西罗。authc。SaltedAuthenticationInfo#获取证书用于哈希的Salt。为了避免安全风险,强烈建议更新任何支持哈希凭据的现有领域实现,以尽快返回SaltedAuthenticationInfo实例。
#####Shiro 1.0向后兼容性
由于已识别的安全风险,应更新支持凭据哈希的领域实现,以尽快返回SaltedAuthenticationInfo实例。
如果由于某种原因这是不可能的,那么这个类将保留1.0向后兼容的行为,即通过现在不推荐的#getSalt(AuthenticationToken)方法获取salt。仅当域返回SaltedAuthenticationInfo实例且#isHashSalted()为true时,才会调用此方法。但请注意,#isHashSalted()属性和#getSalt(AuthenticationToken)方法将在Shiro 2.0发布之前删除。
####多重散列迭代
如果在持久化到数据存储之前多次散列用户凭据,则还需要设置此类的#setHashIterations(int)属性。请参阅Hashing Java article的{$3$}部分,以了解更多有关为什么要使用多个哈希迭代的信息。MD5&SHA-1通知MD5和{$5$}算法现在已知易受损害和/或冲突(请阅读链接页面了解更多信息)。虽然大多数应用程序都可以使用这两种方法中的任何一种,但如果您的应用程序要求高安全性,请使用SHA-256(或更高版本)哈希算法及其支持的CredentialsMatcher实现。

代码示例

代码示例来源:origin: ityouknow/spring-boot-examples

/**
 * 凭证匹配器
 * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
 * )
 * @return
 */
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
  HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
  hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
  hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
  return hashedCredentialsMatcher;
}

代码示例来源:origin: stylefeng/Guns

/**
 * api登录接口,通过账号密码获取token
 */
@RequestMapping("/auth")
public Object auth(@RequestParam("username") String username,
          @RequestParam("password") String password) {
  //封装请求账号密码为shiro可验证的token
  UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password.toCharArray());
  //获取数据库中的账号密码,准备比对
  User user = userMapper.getByAccount(username);
  String credentials = user.getPassword();
  String salt = user.getSalt();
  ByteSource credentialsSalt = new Md5Hash(salt);
  SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
      new ShiroUser(), credentials, credentialsSalt, "");
  //校验用户账号密码
  HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher();
  md5CredentialsMatcher.setHashAlgorithmName(ShiroKit.hashAlgorithmName);
  md5CredentialsMatcher.setHashIterations(ShiroKit.hashIterations);
  boolean passwordTrueFlag = md5CredentialsMatcher.doCredentialsMatch(
      usernamePasswordToken, simpleAuthenticationInfo);
  if (passwordTrueFlag) {
    HashMap<String, Object> result = new HashMap<>();
    result.put("token", JwtTokenUtil.generateToken(String.valueOf(user.getUserId())));
    return result;
  } else {
    return new ErrorResponseData(500, "账号密码错误!");
  }
}

代码示例来源:origin: 527515025/springBoot

/**
 * HashedCredentialsMatcher,这个类是为了对密码进行编码的,
 * 防止密码在数据库里明码保存,当然在登陆认证的时候,
 * 这个类也负责对form里输入的密码进行编码。
 */
@Bean(name = "hashedCredentialsMatcher")
public HashedCredentialsMatcher hashedCredentialsMatcher() {
  HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
  credentialsMatcher.setHashAlgorithmName("MD5");
  credentialsMatcher.setHashIterations(2);
  credentialsMatcher.setStoredCredentialsHexEncoded(true);
  return credentialsMatcher;
}

代码示例来源:origin: killbill/killbill

public static CredentialsMatcher getCredentialsMatcher(final SecurityConfig securityConfig) {
    // This needs to be in sync with DefaultTenantDao
    final HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(HASH_ALGORITHM_NAME);
    // base64 encoding, not hex
    credentialsMatcher.setStoredCredentialsHexEncoded(false);
    credentialsMatcher.setHashIterations(securityConfig.getShiroNbHashIterations());

    return credentialsMatcher;
  }
}

代码示例来源:origin: org.neo4j/neo4j-security-enterprise

public HashedCredentialsMatcher getHashedCredentialsMatcher()
{
  if ( hashedCredentialsMatcher == null )
  {
    hashedCredentialsMatcher = new HashedCredentialsMatcher( HASH_ALGORITHM );
    hashedCredentialsMatcher.setHashIterations( HASH_ITERATIONS );
  }
  return hashedCredentialsMatcher;
}

代码示例来源:origin: Graylog2/graylog2-server

@Inject
RootAccountRealm(@Named("root_username") String rootUsername,
         @Named("root_password_sha2") String rootPasswordSha2) {
  setCachingEnabled(false);
  setCredentialsMatcher(new HashedCredentialsMatcher("SHA-256"));
  setName("root-account-realm");
  addRootAccount(rootUsername, rootPasswordSha2);
}

代码示例来源:origin: magefree/mage

public boolean doCredentialsMatch(String name, String password) {
  HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(this.hashAlgorithm);
  matcher.setHashIterations(this.hashIterations);
  AuthenticationToken token = new UsernamePasswordToken(name, password);
  AuthenticationInfo info = new SimpleAuthenticationInfo(this.name,
      ByteSource.Util.bytes(Base64.decode(this.password)),
      ByteSource.Util.bytes(Base64.decode(this.salt)), "");
  return matcher.doCredentialsMatch(token, info);
}

代码示例来源:origin: ueboot/ueboot

/***
 * 密码凭证匹配器
 * @return
 */
@Bean
@ConditionalOnMissingBean
public CredentialsMatcher hashedCredentialsMatcher(RedisTemplate<Object,Object> redisTemplate) {
  HashedCredentialsMatcher  matcher=new RetryLimitHashedCredentialsMatcher(redisTemplate);
  matcher.setHashAlgorithmName ("SHA-512");
  //散列的次数,比如散列两次
  matcher.setHashIterations (2);
  matcher.setStoredCredentialsHexEncoded (Boolean.TRUE);
  return matcher;
}

代码示例来源:origin: stackoverflow.com

public class CdiEnvironmentLoaderListener extends EnvironmentLoaderListener {

  //this is your implementation that extends Authorizing Realm
  ShiroRealm shiroRealm = null; 

  @Override
  protected WebEnvironment createEnvironment(ServletContext sc) {
    WebEnvironment environment = super.createEnvironment(sc);
    shiroRealm = new ShiroRealm();

    RealmSecurityManager rsm = (RealmSecurityManager) environment
      .getSecurityManager();

    HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
    matcher.setHashAlgorithmName(Sha512Hash.ALGORITHM_NAME);

    shiroRealm.setCredentialsMatcher(matcher);

    rsm.setRealm(shiroRealm);

    ((DefaultWebEnvironment) environment).setSecurityManager(rsm);

    return environment;
  }
}

代码示例来源:origin: apache/shiro

/**
 * Test backwards compatibility of unsalted credentials before
 * <a href="https://issues.apache.org/jira/browse/SHIRO-186">SHIRO-186</a> edits.
 */
@Test
public void testBackwardsCompatibleUnsaltedAuthenticationInfo() {
  HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(Sha1Hash.ALGORITHM_NAME);
  //simulate an account with SHA-1 hashed password (no salt)
  final String username = "username";
  final String password = "password";
  final Object hashedPassword = new Sha1Hash(password).getBytes();
  AuthenticationInfo account = new AuthenticationInfo() {
    public PrincipalCollection getPrincipals() {
      return new SimplePrincipalCollection(username, "realmName");
    }
    public Object getCredentials() {
      return hashedPassword;
    }
  };
  //simulate a username/password (plaintext) token created in response to a login attempt:
  AuthenticationToken token = new UsernamePasswordToken("username", "password");
  //verify the hashed token matches what is in the account:
  assertTrue(matcher.doCredentialsMatch(token, account));
}

代码示例来源:origin: apache/shiro

HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(Sha1Hash.ALGORITHM_NAME);
matcher.setHashSalted(true);
assertTrue(matcher.doCredentialsMatch(token, account));

代码示例来源:origin: TomChen001/xmanager

@Override
  public void afterPropertiesSet() throws Exception {
    Assert.notNull(passwordHash, "you must set passwordHash!");
    super.setHashAlgorithmName(passwordHash.getAlgorithmName());
    super.setHashIterations(passwordHash.getHashIterations());
    this.passwordRetryCache = cacheManager.getCache(retryLimitCacheName);
  }
}

代码示例来源:origin: stackoverflow.com

final int iterations = 50000;

AuthenticationToken authToken = ...;
SaltedAuthenticationInfo saltedAuthInfo = ...;

HashedCredentialsMatcher authenticator = 
   new HashedCredentialsMatcher(Sha256Hash.ALGORITHM_NAME);
authenticator.setHashIterations(iterations);

final boolean successfulAuthentication = 
   authenticator.doCredentialsMatch(authToken, saltedAuthInfo);

代码示例来源:origin: peterl1084/cdiexample

@Override
  protected WebEnvironment createEnvironment(ServletContext sc) {
    WebEnvironment webEnvironment = super.createEnvironment(sc);

    RealmSecurityManager rsm = (RealmSecurityManager) webEnvironment
        .getSecurityManager();

    HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(
        HASHING_ALGORITHM);
    hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);

    jpaRealm.setCredentialsMatcher(hashedCredentialsMatcher);
    Collection<Realm> realms = rsm.getRealms();
    realms.add(jpaRealm);
    rsm.setRealms(realms);

    ((DefaultWebEnvironment) webEnvironment).setSecurityManager(rsm);
    return webEnvironment;
  }
}

代码示例来源:origin: be.c4j.ee.security.octopus/octopus-core

@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
  if (token instanceof UsernamePasswordToken) {
    return super.doCredentialsMatch(token, info);
  } else {
    return false;
  }
}

代码示例来源:origin: com.github.sogyf/goja-mvt

public AppDbRealm() {
  HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(EncodeKit.HASH_ALGORITHM);
  matcher.setHashIterations(EncodeKit.HASH_INTERATIONS);
  setCredentialsMatcher(matcher);
}

代码示例来源:origin: com.ning.billing/killbill-tenant

public static CredentialsMatcher getCredentialsMatcher() {
    // This needs to be in sync with DefaultTenantDao
    final HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(HASH_ALGORITHM_NAME);
    // base64 encoding, not hex
    credentialsMatcher.setStoredCredentialsHexEncoded(false);
    credentialsMatcher.setHashIterations(HASH_ITERATIONS);

    return credentialsMatcher;
  }
}

代码示例来源:origin: xautlx/s2jh4net

/**
   * 设定Password校验的Hash算法与迭代次数.
   */
  @PostConstruct
  public void initCredentialsMatcher() {
    HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(PasswordService.HASH_ALGORITHM);
    setCredentialsMatcher(matcher);
  }
}

代码示例来源:origin: tumao2/hdw-dubbo

/**
 * 凭证匹配器 (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
 * 所以我们需要修改下doGetAuthenticationInfo中的代码; @return
 */
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
  HashedCredentialsMatcher hashedCredentialsMatcher = new RetryLimitCredentialsMatcher(redisCacheManager());
  hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列算法:这里使用MD5算法;
  hashedCredentialsMatcher.setHashIterations(2);// 散列的次数,比如散列两次,相当于md5(md5(""));
  hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);// 表示是否存储散列后的密码为16进制,需要和生成密码时的一样,默认是base64;
  return hashedCredentialsMatcher;
}

代码示例来源:origin: org.sonatype.nexus/nexus-security

@Inject
public AuthorizingRealmImpl(final RealmSecurityManager realmSecurityManager,
              final UserManager userManager,
              final Map<String, UserManager> userManagerMap)
{
 this.realmSecurityManager = realmSecurityManager;
 this.userManager = userManager;
 this.userManagerMap = userManagerMap;
 HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
 credentialsMatcher.setHashAlgorithmName(Sha1Hash.ALGORITHM_NAME);
 setCredentialsMatcher(credentialsMatcher);
 setName(NAME);
 setAuthenticationCachingEnabled(false); // we authz only, no authc done by this realm
 setAuthorizationCachingEnabled(true);
}

相关文章