跟我學Shiro——realm之密碼加密登陸退出(3)

Realm

realm:域shiro是從realm獲取安全數據(eg: 用戶、角色、權限),就是說SecurityManger要驗證用戶身份,那麼須要從Realm獲取相應的用戶進行比較肯定用戶身份是否合法;也須要從Realm獲得相應用戶的角色/權限進行驗證用戶是否能進行操做;能夠把Realm當作DataSource,即數據源。以前用的是ini的配置方式將使用org.apache.shiro.realm.text.IniRealm。
org.apache.shiro.realm.Realm 接口以下:算法

String getName(); //返回一個惟一的Realm名字
boolean supports(AuthenticationToken token); //判斷此Realm是否支持此Token
AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)
 throws AuthenticationException;  //根據Token獲取認證信息

單 Realm 登陸 配置

  1. 先編寫realm文件
public class MyRealm extends AuthorizingRealm {
    @Override
    public String getName() {
        return "MyRealm";
    }
     // 受權
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    // 身份認證
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //用戶名
        String userName = (String) authenticationToken.getPrincipal();
        if(!"zhangsan".equals(userName)){
            return null;
        }
        //假設從數據庫讀出來的密碼是222
        String password="222";
        AuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(userName,password,getName());
        return authenticationInfo;
    }
    
};
  1. 編寫realm.ini 文件
#聲明一個realm
MyRealm=com.tuyue.shiro.MyRealm
#指定securityManager的realms實現
securityManager.realms=$MyRealm

測試結果spring

@Test
    public void realm1() {
        //獲取SecurityManager的實例
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:realm.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "222");
        subject.login(token);
        //驗證登陸是否成功
        log.info("登陸是否成功!"+subject.isAuthenticated());
        subject.logout();
        log.info("登陸是否成功!"+subject.isAuthenticated());
    }

2018-09-30 11:45:11.616  INFO 8056 --- [           main] a.s.s.m.AbstractValidatingSessionManager : Enabling session validation scheduler...
2018-09-30 11:45:11.746  INFO 8056 --- [           main] c.tuyue.SpringbootshiroApplicationTests  : 登陸是否成功!true
2018-09-30 11:45:11.747  INFO 8056 --- [           main] c.tuyue.SpringbootshiroApplicationTests  : 登陸是否成功!false
2018-09-30 11:45:11.750  INFO 8056 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@16610890: startup date [Sun Sep 30 11:45:11 CST 2018]; root of context hierarchy

登陸加密操做

通常狀況下在數據庫存的用戶密碼是加密後的,那麼這種狀況shiro是怎麼驗證的呢?
咱們先了解一個概念:散列算法
散列算法 通常用於生成數據的摘要信息,是一種不可逆的算法,通常適合存儲密碼之類的數據,常見的散列算法如MD五、SHA等。通常進行散列時最好提供一個salt(鹽),好比加密密碼「admin」,產生的散列值是「21232f297a57a5a743894a0e4a801fc3」,能夠到一些md5解密網站很容易的經過散列值獲得密碼「admin」,即若是直接對密碼進行散列相對來講破解更容易,此時咱們能夠加一些只有系統知道的干擾數據,如用戶名和ID(即鹽);這樣散列的對象是「密碼+用戶名+ID」,這樣生成的散列值相對來講更難破解。
閒話很少說直接上手
1: 先模擬數據的加密操做數據庫

public class PasswordMd5  {
     public static void main(String[] args) {
          String password ="222";
          //加密以後
          Md5Hash md5Hash=new Md5Hash(password);
          System.out.println("md5加密:"+md5Hash);
          //md5+加鹽
          Md5Hash md5Hash1=new Md5Hash(password,"123");
          System.out.println("md5加密加鹽:"+md5Hash1);
          //md5+鹽+散列次數
          Md5Hash md5Hash2=new Md5Hash(password,"1234",3);
          System.out.println("md5+鹽+散列次數:"+md5Hash2);
      }
}
md5加密:       bcbe3365e6ac95ea2c0343a2395834dd
md5加密加鹽:   ea281b47cb711da418c35b07b9f06cd5
md5+鹽+散列次數:148dc8607c574b5ddfb8845f55536cca

2:編寫加密的ini文件apache

[main]
#定義憑證匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher

#指定散列算法
credentialsMatcher.hashAlgorithmName=md5
#指定散列次數
credentialsMatcher.hashIterations=3

myRealm=com.tuyue.shiro.MyRealm
myRealm.credentialsMatcher=$credentialsMatcher
#指定securityManager的realms實現
securityManager.realms=$myRealm

3.測試結果安全

@Test
    public void realm1() {
        //獲取SecurityManager的實例
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:Passwordrealm.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "222");
        subject.login(token);
        //驗證登陸是否成功
        log.info("登陸是否成功!"+subject.isAuthenticated());
        subject.logout();
        log.info("登陸是否成功!"+subject.isAuthenticated());

    }
2018-09-30 17:20:30.006  INFO 10120 --- [           main] c.tuyue.SpringbootshiroApplicationTests  : 登陸是否成功!true
2018-09-30 17:20:30.006  INFO 10120 --- [           main] c.tuyue.SpringbootshiroApplicationTests  : 登陸是否成功!false
相關文章
相關標籤/搜索