1.shiro整體架構(gòu)
1.Authenticator=>認(rèn)證器:負(fù)責(zé)用戶登錄登出
2.Authoorizer=>授權(quán)器:shiro給用戶授權(quán)
3.Session Manager=>Session管理機(jī)制
4.SessionDao=>負(fù)責(zé)增刪改查
5.Pluggable Realms=>與數(shù)據(jù)庫交互,獲取權(quán)限信息
6.Cryptography=>加密
2.Shiro認(rèn)證
1.創(chuàng)建模版:
1.pom.xml添加依賴
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
2.創(chuàng)建測(cè)試類
package com.imooc.test;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;
/**
* Created by fly on 2018/4/18.
*/
public class AuthenticationTest {
//暫時(shí)使用SimpleAccountRealm
SimpleAccountRealm simpleAccountRealm=new SimpleAccountRealm();
//創(chuàng)建一個(gè)用戶
@Before
public void addUser(){
simpleAccountRealm.addAccount("Mark","123456");
}
@Test
public void testAuthentication(){
//1.構(gòu)建SecurityManager環(huán)境
DefaultSecurityManager defaultSecurityManager=new DefaultSecurityManager();
defaultSecurityManager.setRealm(simpleAccountRealm);
//2.主體提交認(rèn)證請(qǐng)求
SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject=SecurityUtils.getSubject();//注意使用shiro下的Subject
UsernamePasswordToken token=new UsernamePasswordToken("Mark","123456");
subject.login(token);
System.out.println("isAuthenticated:"+subject.isAuthenticated());
subject.logout();
System.out.println("isAuthenticated:"+subject.isAuthenticated());
}
}
認(rèn)證結(jié)果:
2.Shiro授權(quán)
1.給用戶賦予一個(gè)角色
2.驗(yàn)證是否擁有該角色
結(jié)果:
若主體角色錯(cuò)誤(異常)
擴(kuò)展
可同時(shí)添加多個(gè)角色,check多個(gè)角色
Shiro自定義Realm
內(nèi)置Realm:
1.IniRealm
2.JdbcRealm
1.IniRealm測(cè)試類
目錄結(jié)構(gòu)
創(chuàng)建IniRealmTest
package com.imooc.test;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
/**
* Created by fly on 2018/4/18.
*/
public class IniRealTest {
//創(chuàng)建IniRealm
IniRealm iniRealm=new IniRealm("classpath:user.ini");
@Test
public void testAuthentication(){
//1.構(gòu)建SecurityManager環(huán)境
DefaultSecurityManager defaultSecurityManager=new DefaultSecurityManager();
defaultSecurityManager.setRealm(iniRealm);
//2.主體提交認(rèn)證請(qǐng)求
SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject=SecurityUtils.getSubject();//注意使用shiro下的Subject
UsernamePasswordToken token=new UsernamePasswordToken("Mark","123456");
subject.login(token);
System.out.println("isAuthenticated:"+subject.isAuthenticated());
//權(quán)限驗(yàn)證
subject.checkRole("admin");
//是否具備某權(quán)限
subject.checkPermission("user:delete");
}
}
創(chuàng)建user.ini
[users]
Mark=123456,admin
[roles]
admin=user:delete
運(yùn)行結(jié)果
2.JdbcRealm
在pom.xml中導(dǎo)入mysql支持和datasource數(shù)據(jù)源
<!--mysql驅(qū)動(dòng)包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<!--數(shù)據(jù)源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
</dependencies>
JdbcRealmTest類
package com.imooc.test;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
/**
* Created by fly on 2018/4/19.
*/
public class JdbcRealmTest {
//創(chuàng)建jdbc數(shù)據(jù)源
DruidDataSource dataSource=new DruidDataSource();
//設(shè)置jdbc入口
{
dataSource.setUrl("jdbc:mysql://localhost:3306/shiro_test");
dataSource.setUsername("root");
dataSource.setPassword("123456");
}
@Test
public void testAuthentication(){
//創(chuàng)建JdbcRealm
JdbcRealm jdbcRealm=new JdbcRealm();
//設(shè)置JdbcRealm數(shù)據(jù)源
jdbcRealm.setDataSource(dataSource);
//設(shè)置權(quán)限開關(guān)(默認(rèn)為false)
jdbcRealm.setPermissionsLookupEnabled(true);
//1.構(gòu)建SecurityManager環(huán)境
DefaultSecurityManager defaultSecurityManager=new DefaultSecurityManager();
defaultSecurityManager.setRealm(jdbcRealm);
//2.主體提交認(rèn)證請(qǐng)求
SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject=SecurityUtils.getSubject();//注意使用shiro下的Subject
UsernamePasswordToken token=new UsernamePasswordToken("zhangsan","123456");
subject.login(token);
System.out.println("isAuthenticated:"+subject.isAuthenticated());
//驗(yàn)證角色
subject.checkRole("admin");
//驗(yàn)證權(quán)限
subject.checkPermission("user:delete");
}
}
如果使用shiro默認(rèn)的查詢語句,就根據(jù)shiro查詢語句創(chuàng)建表
注意:如果不設(shè)置開關(guān) subject.checkPermission("user:delete");將報(bào)錯(cuò)
自定義sql語句查詢
3.自定義Realm
創(chuàng)建自定義CustomRealm和測(cè)試類CustomRealmTest
沒有從數(shù)據(jù)庫查詢,使用Map和Set進(jìn)行模擬查詢
CustomRealm
package com.imooc.realm;
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;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Created by fly on 2018/4/19.
*/
public class CustomRealm extends AuthorizingRealm {
Map<String,String> userMap=new HashMap<String, String>(16);
{
userMap.put("Mark","123456");
super.setName("customRealm");
}
//授權(quán)方法
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String userName=(String) principalCollection.getPrimaryPrincipal();
//從數(shù)據(jù)庫或者緩存中獲取角色數(shù)據(jù)
Set<String> roles=getRolesByUserName(userName);
//從數(shù)據(jù)庫或者緩存中獲取權(quán)限數(shù)據(jù)
Set<String> permissions=getPermissionsByUserName(userName);
SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
simpleAuthorizationInfo.setStringPermissions(permissions);
simpleAuthorizationInfo.setRoles(roles);
return simpleAuthorizationInfo;
}
//模擬數(shù)據(jù)庫獲取角色數(shù)據(jù)
private Set<String> getPermissionsByUserName(String userName) {
Set<String> sets=new HashSet<String>();
sets.add("user:delete");
sets.add("user:select");
return sets;
}
//模擬數(shù)據(jù)庫獲取角色數(shù)據(jù)
private Set<String> getRolesByUserName(String userName) {
Set<String> sets=new HashSet<String>();
sets.add("admin");
sets.add("user");
return sets;
}
//認(rèn)證方法
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//1.從主體穿過來的認(rèn)證信息中,獲得用戶名
String userName=(String) authenticationToken.getPrincipal();
//2.通過用戶名到數(shù)據(jù)庫中獲取憑證
String password=getPasswordByUserName(userName);
if(password==null){
return null;
}
SimpleAuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo("Mark",password,"customRealm");
return authenticationInfo;
}
//模擬數(shù)據(jù)庫查詢
private String getPasswordByUserName(String userName) {
return userMap.get(userName);
}
}
CustomRealmTest
package com.imooc.test;
import com.imooc.realm.CustomRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
/**
* Created by fly on 2018/4/19.
*/
public class CustomReamlTest {
@Test
public void testAuthentication(){
//創(chuàng)建CustomRealm
CustomRealm customRealm=new CustomRealm();
//1.構(gòu)建SecurityManager環(huán)境
DefaultSecurityManager defaultSecurityManager=new DefaultSecurityManager();
defaultSecurityManager.setRealm(customRealm);
//2.主體提交認(rèn)證請(qǐng)求
SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject=SecurityUtils.getSubject();//注意使用shiro下的Subject
UsernamePasswordToken token=new UsernamePasswordToken("Mark","123456");
subject.login(token);
System.out.println("isAuthenticated:"+subject.isAuthenticated());
subject.checkRole("admin");
subject.checkPermissions("user:delete","user:select");
}
}
Shiro加密
1.Shiro散列配置
HashedCredentialsMatcher
自定義Realm中使用散列
鹽的使用
在驗(yàn)證方法中設(shè)置加密類型,加密次數(shù)
HashedCredentialsMatcher matcher=new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");//設(shè)置加密方法
matcher.setHashIterations(1);//設(shè)置加密次數(shù)
customRealm.setCredentialsMatcher(matcher);
在Realm中設(shè)置鹽等參數(shù)
//設(shè)置鹽
authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("Mark"));
============未完待續(xù)=================