Shiro應用(一)--- 單獨使用
阿新 • • 發佈:2018-12-11
shiro單獨使用demo:
需要的依賴:
<!-- 日誌 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <!-- shiro的核心包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency>
shiro-permissions.ini檔案(ini相對於properties檔案的區別在於ini檔案可以分組):
# ----------------------------------------------------------------------------- # 指定使用者名稱以及角色(可選) # username = password, role1, role2, ..., roleN # ----------------------------------------------------------------------------- [users] hurricane = 123, admin,handsome # ----------------------------------------------------------------------------- # 指定角色與許可權的對應關係 # roleName = perm1, perm2, ..., permN # ----------------------------------------------------------------------------- [roles] admin = user:add,user:delete handsome = user:update
簡單的日誌輸出配置log4j.properties:
log4j.rootLogger=info, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n
log4j.logger.com.hurricane = info
主要測試程式碼:
package com.hurricane.learn.shiro;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
public class App {
public static void main(String[] args) {
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permissions.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("hurricane", "123");
try {
subject.login(token);
} catch (UnknownAccountException e) {
System.out.println("使用者名稱不存在");
} catch (IncorrectCredentialsException e) {
System.out.println("密碼錯誤");
} catch (Exception e) {
System.out.println("未知錯誤");
}
System.out.println("使用者登入成功:" + subject.isAuthenticated());
System.out.println("使用者擁有admin角色:" + subject.hasRole("admin"));
System.out.println("使用者擁有user:delete許可權:" + subject.isPermitted("user:delete"));
System.out.println("使用者擁有user:query許可權:" + subject.isPermitted("user:query"));
}
}
以上即可實現shiro最基本的使用。
除此之外,shiro單獨使用通常需要使用自定義的realm進行校驗授權,以及對使用者密碼進行雜湊編碼。
自定義realm:
shiro-permissions.ini中加入:
[main]
customRealm = com.hurricane.learn.shiro.util.CustomRealm
securityManager.realms = $customRealm
CustomRealm的程式碼為:
package com.hurricane.learn.shiro.util;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class CustomRealm extends AuthorizingRealm{
/**
* 授權
*/
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//primaryPrincipal是認證階段傳入的principal
Object primaryPrincipal = principals.getPrimaryPrincipal();
//根據primaryPrincipal從資料庫中查詢對應的角色與許可權,並封裝進要返回的AuthorizationInfo
info.addRole("role1");
info.addStringPermission("user:create");
return info;
}
/**
* 認證
* 返回null代表使用者名稱不存在
*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
if (token.getPrincipal()==null || token.getPrincipal().toString().equals("")) {
return null;
}
//判斷使用者名稱是否存在,若不存在,返回null
// ...
String dbPassword = "123";
//將從資料庫中獲取的密碼傳入,shiro會進行校驗,此處傳入的principal應為工程中對使用者資訊進行封裝的類的例項,此處簡寫為一個使用者名稱的字串
AuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal(),dbPassword,"realm1");
return info;
}
}
以上就可以使shiro的校驗走自定義的realm。
對密碼進行加鹽與雜湊:
shiro-permissions.ini中關於自定義域的宣告中指定雜湊的演算法與雜湊的次數:
[main]
credentialsMatcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
credentialsMatcher.hashAlgorithmName = md5
credentialsMatcher.hashIterations = 2
customRealm = com.hurricane.learn.shiro.util.CustomRealm
customRealm.credentialsMatcher = $credentialsMatcher
securityManager.realms = $customRealm
在進行認證的方法中傳入鹽與加密後的密碼(一般為從資料庫中讀取的結果),如下:
/**
* 認證
* 返回null代表使用者名稱不存在
*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
if (token.getPrincipal()==null || token.getPrincipal().toString().equals("")) {
return null;
}
//判斷使用者名稱是否存在,若不存在,返回null
// ...
//755ac1a684638060155ccc37625b954b是123加鹽sss並進行2次md5雜湊後的結果
String dbPassword = "755ac1a684638060155ccc37625b954b";
//將從資料庫中獲取的密碼傳入,shiro會進行校驗,此處傳入的principal應為工程中對使用者資訊進行封裝的類的例項,此處簡寫為一個使用者名稱的字串
AuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal(),dbPassword,ByteSource.Util.bytes("sss"),"realm1");
return info;
}
參考:
燕青的視訊教程