Shiro (笔记) InI 配置

https://www.w3cschool.cn/shiro/h5it1if8.html

即使没接触过 IoC 容器的知识,如上配置也是很容易理解的:

  1. 对象名 = 全限定类名 相对于调用 public 无参构造器创建对象
  2. 对象名. 属性名 = 值 相当于调用 setter 方法设置常量值
  3. 对象名. 属性名 =$ 对象引用 相当于调用 setter 方法设置对象引用
package com.dudu.course2;

import java.nio.file.attribute.UserPrincipalLookupService;
import java.util.Arrays;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authz.ModularRealmAuthorizer;
import org.apache.shiro.authz.permission.WildcardPermissionResolver;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Assert;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * AtLeastOneSuccessfulStrategy 只要有一个Realm验证成功即可,和FirstSuccessfulStrategy不同,返回所有Realm身份验证成功的认证信息;
 * AllSuccessfulStrategy 所有Realm验证成功才算成功,且返回所有Realm身份验证成功的认证信息,如果有一个失败就失败了。
 * ModularRealmAuthenticator默认使用AtLeastOneSuccessfulStrategy策略。
 * FirstSuccessfulStrategy 只要有一个Realm验证成功即可,只返回第一个Realm身份验证成功的认证信息,其他的忽略;
 * @author xl
 *
 */
public class ShiroTest2INI {

	public void test(){
		DefaultSecurityManager securityManager = new DefaultSecurityManager();
		//设置authenticator 验证账户账号
		ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
		authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
		securityManager.setAuthenticator(authenticator);
		
		//设置authorizer 授权
		ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
		authorizer.setPermissionResolver(new WildcardPermissionResolver());
		securityManager.setAuthorizer(authorizer);
		
		//设置realm
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/shiro");
		dataSource.setUsername("root");
		dataSource.setPassword("123456");
		
		JdbcRealm jdbcRealm = new JdbcRealm(); 
		jdbcRealm.setDataSource(dataSource);
		jdbcRealm.setPermissionsLookupEnabled(true);
		securityManager.setRealms(Arrays.asList((Realm) jdbcRealm));
		
		SecurityUtils.setSecurityManager(securityManager);
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken();
		subject.login(token);
		Assert.assertTrue(subject.isAuthenticated());
		
	}
}

2、等价的 INI 配置(shiro-config.ini)

[main]
\#authenticator
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
authenticator.authenticationStrategy=$authenticationStrategy
securityManager.authenticator=$authenticator
\#authorizer
authorizer=org.apache.shiro.authz.ModularRealmAuthorizer
permissionResolver=org.apache.shiro.authz.permission.WildcardPermissionResolver
authorizer.permissionResolver=$permissionResolver
securityManager.authorizer=$authorizer
\#realm
dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/shiro
dataSource.username=root
\#dataSource.password=
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource=$dataSource
jdbcRealm.permissionsLookupEnabled=true
securityManager.realms=$jdbcRealm
[main]
\#提供了对根对象securityManager及其依赖的配置
securityManager=org.apache.shiro.mgt.DefaultSecurityManager
…………
securityManager.realms=$jdbcRealm
[users]
\#提供了对用户/密码及其角色的配置,用户名=密码,角色1,角色2
username=password,role1,role2
[roles]
\#提供了角色及权限之间关系的配置,角色=权限1,权限2
role1=permission1,permission2
[urls]
\#用于web,提供了对web url拦截相关的配置,url=拦截器[参数],拦截器
/index.html = anon
/admin/** = authc, roles[admin], perms["permission1"]
String str = "hello";
String salt = "123";
String md5 = new Md5Hash(str, salt).toString();//还可以转换为 toBase64()/toHex() 

如上代码通过盐 “123”MD5 散列 “hello”。另外散列时还可以指定散列次数,如 2 次表示:md5(md5(str)):“new Md5Hash(str, salt, 2).toString()”。

String str = "hello";
String salt = "123";
String sha1 = new Sha256Hash(str, salt).toString(); 

使用 SHA256 算法生成相应的散列数据,另外还有如 SHA1、SHA512 算法。

Shiro 还提供了通用的散列支持:

String str = "hello";
String salt = "123";
//内部使用MessageDigest
String simpleHash = new SimpleHash("SHA-1", str, salt).toString();   

通过调用 SimpleHash 时指定散列算法,其内部使用了 Java 的 MessageDigest 实现。

为了方便使用,Shiro 提供了 HashService,默认提供了 DefaultHashService 实现。

DefaultHashService hashService = new DefaultHashService(); //默认算法SHA-512
hashService.setHashAlgorithmName("SHA-512");
hashService.setPrivateSalt(new SimpleByteSource("123")); //私盐,默认无
hashService.setGeneratePublicSalt(true);//是否生成公盐,默认false
hashService.setRandomNumberGenerator(new SecureRandomNumberGenerator());//用于生成公盐。默认就这个
hashService.setHashIterations(1); //生成Hash值的迭代次数
HashRequest request = new HashRequest.Builder()
            .setAlgorithmName("MD5").setSource(ByteSource.Util.bytes("hello"))
            .setSalt(ByteSource.Util.bytes("123")).setIterations(2).build();
String hex = hashService.computeHash(request).toHex(); 
  1. 首先创建一个 DefaultHashService,默认使用 SHA-512 算法;
  2. 以通过 hashAlgorithmName 属性修改算法;
  3. 可以通过 privateSalt 设置一个私盐,其在散列时自动与用户传入的公盐混合产生一个新盐;
  4. 可以通过 generatePublicSalt 属性在用户没有传入公盐的情况下是否生成公盐;
  5. 可以设置 randomNumberGenerator 用于生成公盐;
  6. 可以设置 hashIterations 属性来修改默认加密迭代次数;
  7. 需要构建一个 HashRequest,传入算法、数据、公盐、迭代次数。

SecureRandomNumberGenerator 用于生成一个随机数:

SecureRandomNumberGenerator randomNumberGenerator =
     new SecureRandomNumberGenerator();
randomNumberGenerator.setSeed("123".getBytes());
String hex = randomNumberGenerator.nextBytes().toHex(); 

猜你喜欢

转载自blog.csdn.net/qq_37538698/article/details/84062712