魯春利的工作筆記,好記性不如爛筆頭
SecurityManager
Shiro是從根對象SecurityManager進行身份驗證和授權的;這個對象是線程安全且真個應用隻需要一個即可,是以Shiro 提供了SecurityUtils 讓我們綁定它為全局的,友善後續操作。
1、純Java 代碼寫法
@Test
public void testProgramSecurityManager () {
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/spring_test");
dataSource.setUsername("root");
dataSource.setPassword("Mvtech123!@");
JdbcRealm jdbcRealm = new JdbcRealm();
jdbcRealm.setDataSource(dataSource);
// Enables lookup of permissions during authorization.
jdbcRealm.setPermissionsLookupEnabled(true);
securityManager.setRealm(jdbcRealm);
// 将SecurityManager設定到SecurityUtils 友善全局使用
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("lucl", "123");
subject.login(token);
// 測試通過
Assert.assertTrue(subject.isAuthenticated());
}
2、等價的INI配置
- shiro-ini-equals-program.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
#dataSource
dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/spring_test
dataSource.username=root
dataSource.password=Mvtech123!@
#realm
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource=$dataSource
jdbcRealm.permissionsLookupEnabled=true
securityManager.realms=$jdbcRealm
- 單元測試
@Test
public void testConfigSecurityManager () {
// 1、擷取SecurityManager工廠,此處使用Ini配置檔案初始化SecurityManager
Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro/ini/shiro-ini-equals-program.ini");
// 2、得到SecurityManager執行個體并綁定給SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
// 3、得到Subject及建立使用者名/密碼身份驗證Token(即使用者身份/憑證)
Subject subject = SecurityUtils.getSubject();
/*
* 使用者身份Token 可能不僅僅是使用者名/密碼,也可能還有其他的,如登入時允許使用者名/郵箱/手機号同時登入。
*/
UsernamePasswordToken token = new UsernamePasswordToken("lucl", "123");
try{
// 4、登入,即身份驗證
subject.login(token);
} catch (AuthenticationException e) {
// 5、身份驗證失敗
e.printStackTrace();
}
// 測試通過
Assert.assertTrue(subject.isAuthenticated());
// 6、退出
subject.logout();
}
說明:
即使沒接觸過IoC 容器的知識,如上配置也是很容易了解的:
1、對象名=全限定類名相對于調用public 無參構造器建立對象
2、對象名.屬性名=值相當于調用setter方法設定常量值
3、對象名.屬性名=$對象引用相當于調用setter方法設定對象引用
Ini配置檔案示例
[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"]
測試INI配置的身份認證與授權
- shiro-ini-config.ini
[users]
lucl=123,role1
[roles]
role1=system:view:1,system:edit:1,user:update:2
測試代碼
/**
* 基于資源的通路控制(ini配置)
*/
@Test
public void testWhetherHasPermissionInIni () {
// 1、擷取SecurityManager工廠,此處使用Ini配置檔案初始化SecurityManager
Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro/ini/shiro-ini-config.ini");
// 2、得到SecurityManager執行個體并綁定給SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
// 3、得到Subject及建立使用者名/密碼身份驗證Token(即使用者身份/憑證)
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("lucl", "123");
try{
// 4、登入,即身份驗證
subject.login(token);
} catch (AuthenticationException e) {
// 5、身份驗證失敗
logger.info("使用者身份驗證失敗");
e.printStackTrace();
}
// 使用者身份得到确認
if (subject.isAuthenticated()) {
logger.info("使用者登入成功。");
/**
* 進行權限判斷
*/
// 判斷是否擁有權限
Assert.assertTrue(subject.isPermitted("system:edit:1"));
} else {
logger.info("使用者登入失敗。");
}
// 6、退出
subject.logout();
}
轉載于:https://blog.51cto.com/luchunli/1831154